diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..b4978944 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,75 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Server Software (please complete the following information):** + - OS: [e.g. Ubuntu] + - Virtualization: [e.g. Docker] + - Network: [e.g. LAN/WAN, reverse proxy, cloudflare, ssl offload, etc...] + - Version: [e.g. 1.0.43] + - Node: [e.g. 18.4.0] + - Browser: [e.g. Google Chrome] + +**Remote Device (please complete the following information):** + - Device: [e.g. Laptop] + - OS: [e.g. Windows 10] + - Version: [e.g. 21H2] + - Current Core Version (if known): [**HINT**: Go to a device then `console` Tab then type `info`] + +**Additional context** +Add any other context about the problem here. + +**Your config.json file** +``` +{ + "$schema": "http://info.meshcentral.com/downloads/meshcentral-config-schema.json", + "__comment1__": "This is a simple configuration file, all values and sections that start with underscore (_) are ignored. Edit a section and remove the _ in front of the name. Refer to the user's guide for details.", + "__comment2__": "See node_modules/meshcentral/sample-config-advanced.json for a more advanced example.", + "settings": { + "_cert": "myserver.mydomain.com", + "_WANonly": true, + "_LANonly": true, + "_sessionKey": "MyReallySecretPassword1", + "_port": 443, + "_aliasPort": 443, + "_redirPort": 80, + "_redirAliasPort": 80 + }, + "domains": { + "": { + "_title": "MyServer", + "_title2": "Servername", + "_minify": true, + "_newAccounts": true, + "_userNameIsEmail": true + } + }, + "_letsencrypt": { + "__comment__": "Requires NodeJS 8.x or better, Go to https://letsdebug.net/ first before trying Let's Encrypt.", + "email": "myemail@mydomain.com", + "names": "myserver.mydomain.com", + "production": false + } +} +``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..11fc491e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..960df71d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,21 @@ +name: Release +on: + push: + branches: + - master + +jobs: + build: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Release + uses: justincy/github-action-npm-release@2.0.2 + id: release + - name: Print release output + if: ${{ steps.release.outputs.released == 'true' }} + run: echo Release ID ${{ steps.release.outputs.release_id }} diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj index 7cbdaf20..0403d4b8 100644 --- a/MeshCentralServer.njsproj +++ b/MeshCentralServer.njsproj @@ -239,6 +239,7 @@ + @@ -261,10 +262,8 @@ - - @@ -698,6 +697,7 @@ + @@ -738,6 +738,7 @@ + diff --git a/agents/MeshCentralRouter.exe b/agents/MeshCentralRouter.exe index ef3cda87..4c0b9830 100644 Binary files a/agents/MeshCentralRouter.exe and b/agents/MeshCentralRouter.exe differ diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index ad7eb6a2..ad23a7c2 100644 Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index 84211fdb..f1c1d3eb 100644 Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ diff --git a/agents/compressModules.bat b/agents/compressModules.bat index cc5af30b..dd9d8444 100644 --- a/agents/compressModules.bat +++ b/agents/compressModules.bat @@ -7,14 +7,14 @@ MD modules_meshcore_min "..\..\WebSiteCompiler\bin\Debug\WebSiteCompiler.exe" meshcmd.js REM del meshcore.min.js -REM %LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node ..\translate\translate.js minify meshcore.js +REM %LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node ..\translate\translate.js minify meshcore.js REM rename meshcore.js.min meshcore.min.js REM del meshcmd.min.js -REM %LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node ..\translate\translate.js minify meshcmd.js +REM %LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node ..\translate\translate.js minify meshcmd.js REM rename meshcmd.js.min meshcmd.min.js REM Minify the translations -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node ..\translate\translate.js minify modules_meshcore\coretranslations.json +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node ..\translate\translate.js minify modules_meshcore\coretranslations.json COPY modules_meshcore\coretranslations.json.min modules_meshcore_min\coretranslations.json DEL modules_meshcore\coretranslations.json.min \ No newline at end of file diff --git a/agents/hashagents.bat b/agents/hashagents.bat index fd893be0..f8ca9582 100644 --- a/agents/hashagents.bat +++ b/agents/hashagents.bat @@ -1 +1 @@ -MeshService-signed.exe hashagents.js > hashagents.json \ No newline at end of file +MeshService.exe hashagents.js > hashagents.json \ No newline at end of file diff --git a/agents/hashagents.js b/agents/hashagents.js index b5a5391b..52c0ee30 100644 --- a/agents/hashagents.js +++ b/agents/hashagents.js @@ -1,8 +1,8 @@ var fs = require('fs'); var agents = { - 'MeshService-signed.exe': 3, - 'MeshService64-signed.exe': 4, + 'MeshService.exe': 3, + 'MeshService64.exe': 4, 'meshagent_x86': 5, 'meshagent_x86-64': 6, 'meshagent_arm': 9, diff --git a/agents/hashagents.json b/agents/hashagents.json index 069fd7bc..14f83a82 100644 --- a/agents/hashagents.json +++ b/agents/hashagents.json @@ -1,15 +1,15 @@ { "3": { - "filename": "MeshService-signed.exe", + "filename": "MeshService.exe", "hash": "C0E5DB22DE5DED510C48141D7CFE4807F98B8205D680F5FC8A5D15950F17A1465E0953B7BFA7FAEED72019E765E1C8E1", - "size": 3686192, - "mtime": "2022-05-03T20:43:54Z" + "size": 3680256, + "mtime": "2022-04-04T17:13:59Z" }, "4": { - "filename": "MeshService64-signed.exe", + "filename": "MeshService64.exe", "hash": "47A927806EDB6DFAC2C79467719FADA0F3625010D551C6D0EA6EA7DB99F088C088E70F562416FC1809B014913CFEA7E0", - "size": 3299120, - "mtime": "2022-05-03T20:43:56Z" + "size": 3293184, + "mtime": "2022-03-25T19:04:18Z" }, "5": { "filename": "meshagent_x86", diff --git a/agents/meshcmd.js b/agents/meshcmd.js index e63d0c86..5628303b 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -157,6 +157,8 @@ function run(argv) { if ((typeof args.uuidoutput) == 'string' || args.uuidoutput) { settings.uuidoutput = args.uuidoutput; } if ((typeof args.desc) == 'string') { settings.desc = args.desc; } if ((typeof args.dnssuffix) == 'string') { settings.dnssuffix = args.dnssuffix; } + if ((typeof args.create) == 'string') { settings.create = args.create; } + if ((typeof args.delete) == 'string') { settings.delete = args.delete; } if (args.bindany) { settings.bindany = true; } if (args.emailtoken) { settings.emailtoken = true; } if (args.smstoken) { settings.smstoken = true; } @@ -238,8 +240,12 @@ function run(argv) { console.log('\r\nPossible arguments:\r\n'); console.log(' --json Display all Intel AMT state in JSON format.'); } else if (action == 'amthashes') { - console.log('Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes'); + console.log('Amthashes will display all trusted activations hashes for Intel AMT. If the host is not specified, the hashes are read using the local MEI driver is used. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes'); console.log('\r\nPossible arguments:\r\n'); + console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.'); + console.log(' --user [username] The Intel AMT login username, admin is default.'); + console.log(' --pass [password] The Intel AMT login password.'); + console.log(' --tls Specifies that TLS must be used.'); console.log(' --json Display all Intel AMT hashes in JSON format.'); } else if ((action == 'microlms') || (action == 'lms') || (action == 'amtlms')) { console.log('Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms'); @@ -528,23 +534,28 @@ function run(argv) { return; }); } else if (settings.action == 'amthashes') { - // Display Intel AMT list of trusted hashes - var amtMeiModule, amtMei, amtHashes = []; - try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } - amtMei.on('error', function (e) { console.log('amthashes error: ' + e); exit(1); return; }); - amtMei.getHashHandles(function (handles) { - exitOnCount = handles.length; - for (var i = 0; i < handles.length; ++i) { - this.getCertHashEntry(handles[i], function (result) { - var certState = []; - if (result.isDefault) { certState.push('Default'); } - if (result.isActive) { certState.push('Active'); } else { certState.push('Disabled'); } - amtHashes.push(result); - if (!args.json) { console.log(result.name + ', (' + certState.join(', ') + ')\r\n ' + result.hashAlgorithmStr + ': ' + result.certificateHash); } - if (--exitOnCount == 0) { if (args.json) { console.log(JSON.stringify(amtHashes, null, 2)); } exit(0); } - }); - } - }); + if (settings.hostname == null) { + // Display Intel AMT list of trusted hashes from the MEI driver + var amtMeiModule, amtMei, amtHashes = []; + try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } + amtMei.on('error', function (e) { console.log('amthashes error: ' + e); exit(1); return; }); + amtMei.getHashHandles(function (handles) { + exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + this.getCertHashEntry(handles[i], function (result) { + var certState = []; + if (result.isDefault) { certState.push('Default'); } + if (result.isActive) { certState.push('Active'); } else { certState.push('Disabled'); } + amtHashes.push(result); + if (!args.json) { console.log(result.name + ', (' + certState.join(', ') + ')\r\n ' + result.hashAlgorithmStr + ': ' + result.certificateHash); } + if (--exitOnCount == 0) { if (args.json) { console.log(JSON.stringify(amtHashes, null, 2)); } exit(0); } + }); + } + }); + } else { + // We are going to use WSMAN to perform hash operations + performAmtTrustedHashes(); + } } else if (settings.action == 'netinfo') { // Display network information var interfaces = require('os').networkInterfaces(); @@ -872,6 +883,104 @@ function run(argv) { } } + +// +// Intel AMT Trusted Hashes +// + +function performAmtTrustedHashes() { + // Check the settings + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; } + if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; } + if ((typeof settings.create == 'string')) { + if ((settings.name == null) || (typeof settings.name != 'string') || (settings.name == '')) { console.log('No or invalid \"name\" specified, use --name [name].'); exit(1); return; } + if ((settings.create.length != 32) && (settings.create.length != 40) && (settings.create.length != 64) && (settings.create.length != 96)) { console.log('No or invalid \"create\" hash, must be in HEX format of length 30, 40, 64, 96.'); exit(1); return; } + if (Buffer.from(settings.create, 'hex').toString('hex') != settings.create.toUpperCase()) { console.log('No or invalid \"create\" specified, must be in HEX format.'); exit(1); return; } + settings.create = Buffer.from(settings.create, 'hex').toString('hex'); + } + if ((typeof settings.delete == 'string')) { + if ((settings.delete.length != 32) && (settings.delete.length != 40) && (settings.delete.length != 64) && (settings.delete.length != 96)) { console.log('No or invalid \"delete\" hash, must be in HEX format of length 30, 40, 64, 96.'); exit(1); return; } + if (Buffer.from(settings.delete, 'hex').toString('hex') != settings.delete.toUpperCase()) { console.log('No or invalid \"delete\" specified, must be in HEX format.'); exit(1); return; } + settings.delete = Buffer.from(settings.delete, 'hex').toString('hex'); + } + + // See if MicroLMS needs to be started + if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { + settings.noconsole = true; startLms(performAmtTrustedHashesEx); + } else { + performAmtTrustedHashesEx(); + } +} + +function performAmtTrustedHashesEx(x) { + var transport = require('amt-wsman-duk'); + var wsman = require('amt-wsman'); + var amt = require('amt'); + wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls); + amtstack = new amt(wsstack); + amtstack.BatchEnum(null, ['AMT_ProvisioningCertificateHash'], performAmtTrustedHashesEx2); +} + +function performAmtTrustedHashesEx2(stack, name, responses, status) { + if (status != 200) { + console.log('Unable to get trusted hashes, status = ' + status + '.'); + } else { + var r = responses['AMT_ProvisioningCertificateHash'].responses; + if (settings.create) { + // Create a new hash entry + var instanceId = null; + for (var i in r) { if (Buffer.from(r[i]['HashData'], 'base64').toString('hex') == settings.create) { instanceId = r[i]['InstanceID']; } } + if (instanceId != null) { console.log('This trusted hash is already present.'); exit(1); return; } + + // Setup hash type + var hashtype = -1; + var hash = Buffer.from(settings.create, 'hex'); + if (hash.length == 16) { hashtype = 0; } // MD5 + if (hash.length == 20) { hashtype = 1; } // SHA1 + if (hash.length == 32) { hashtype = 2; } // SHA256 + if (hash.length == 48) { hashtype = 3; } // SHA384 + if (hashtype == -1) { console.log('Invalid hash type', hash.length); exit(1); return; } + + // Setup object instance + var instance = { "Description": settings.name, "Enabled": true, "HashData": hash.toString('base64'), "HashType": hashtype, "IsDefault": false, "InstanceID": '' }; + + // Perform WSMAN "CREATE" operation. + amtstack.Create('AMT_ProvisioningCertificateHash', instance, function (stack, name, response, status) { + if (status != 200) { console.log('ERROR: Failed to create trusted hash.', status, JSON.stringify(response, null, 2)); } else { console.log('Done.'); } + exit(0); + }); + return; + } else if (settings.delete) { + // Delete a hash entry + var instance = null; + for (var i in r) { if (Buffer.from(r[i]['HashData'], 'base64').toString('hex') == settings.delete) { instance = r[i]; } } + if (instance == null) { console.log('This trusted hash not present.'); exit(1); return; } + + // Perform WSMAN "DELETE" operation. + amtstack.Delete('AMT_ProvisioningCertificateHash', instance, function (stack, name, response, status) { + if (status != 200) { console.log('ERROR: Failed to delete trusted hash.', status, JSON.stringify(response, null, 2)); } else { console.log('Done.'); } + exit(0); + }); + return; + } else if (settings.json) { + // List the hashes in JSON format + console.log(JSON.stringify(r, null, 2)); + } else { + // List the hashes + for (var i in r) { + var certState = []; + var hashTypes = ['MD5', 'SHA1', 'SHA256', 'SHA384']; + if (r[i]['IsDefault']) { certState.push('Default'); } + if (r[i]['Enabled']) { certState.push('Active'); } else { certState.push('Disabled'); } + console.log(r[i]['Description'] + ', (' + certState.join(', ') + ')\r\n ' + hashTypes[r[i]['HashType']] + ': ' + Buffer.from(r[i]['HashData'], 'base64').toString('hex')); + } + } + exit(0); + } +} + + // // Intel AMT Agent Presence // diff --git a/agents/meshcore.js b/agents/meshcore.js index e8d3b723..54e12a23 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1365,13 +1365,18 @@ function handleServerCommand(data) { } case 'setclip': { // Set the load clipboard to a user value - if (typeof data.data == 'string') { + if (typeof data.data == 'string') + { MeshServerLogEx(22, [data.data.length], "Setting clipboard content, " + data.data.length + " byte(s)", data); - if (require('MeshAgent').isService) { - if (process.platform != 'win32') { + if (require('MeshAgent').isService) + { + if (process.platform != 'win32') + { require('clipboard').dispatchWrite(data.data); + mesh.SendCommand({ action: 'msg', type: 'setclip', sessionid: data.sessionid, success: true }); } - else { + else + { var clipargs = data.data; var uid = require('user-sessions').consoleUid(); var user = require('user-sessions').getUsername(uid); @@ -1381,20 +1386,24 @@ function handleServerCommand(data) { this._dispatcher = require('win-dispatcher').dispatch({ user: user, modules: [{ name: 'clip-dispatch', script: "module.exports = { dispatch: function dispatch(val) { require('clipboard')(val); process.exit(); } };" }], launch: { module: 'clip-dispatch', method: 'dispatch', args: [clipargs] } }); this._dispatcher.parent = this; //require('events').setFinalizerMetadata.call(this._dispatcher, 'clip-dispatch'); - this._dispatcher.on('connection', function (c) { + this._dispatcher.on('connection', function (c) + { this._c = c; this._c.root = this.parent; - this._c.on('end', function () { + this._c.on('end', function () + { this.root._dispatcher = null; this.root = null; + mesh.SendCommand({ action: 'msg', type: 'setclip', sessionid: data.sessionid, success: true }); }); }); } } - else { + else + { require("clipboard")(data.data); + mesh.SendCommand({ action: 'msg', type: 'setclip', sessionid: data.sessionid, success: true }); } // Set the clipboard - mesh.SendCommand({ action: 'msg', type: 'setclip', sessionid: data.sessionid, success: true }); } break; } diff --git a/agents/recoverycore.js b/agents/recoverycore.js index c0bbfc66..169b170c 100644 --- a/agents/recoverycore.js +++ b/agents/recoverycore.js @@ -7,7 +7,6 @@ var tunnels = {}; var fs = require('fs'); var needStreamFix = (new Date(process.versions.meshAgent) < new Date('2020-01-21 13:27:45.000-08:00')); - try { Object.defineProperty(Array.prototype, 'find', { @@ -553,15 +552,15 @@ function agentUpdate_Start(updateurl, updateoptions) { if (process.platform == 'win32') { // Special Processing for Temporary/Console Mode Agents on Windows - var parms = windows_getCommandLine(); - if (parms.findIndex(function (val) { return (val.toUpperCase() == 'RUN' || val.toUpperCase() == 'CONNECT');})>=0) + var parms = windows_getCommandLine(); // This uses FFI to fetch the command line parameters that the agent was started with + if (parms.findIndex(function (val) { return (val != null && (val.toUpperCase() == 'RUN' || val.toUpperCase() == 'CONNECT')); }) >= 0) { // This is a Temporary/Console Mode Agent sendConsoleText('This is a temporary/console agent, checking for conflicts with background services...'); // Check to see if our binary conflicts with an installed agent var agents = _getPotentialServiceNames(); - if(_getPotentialServiceNames().length>0) + if (_getPotentialServiceNames().length > 0) { sendConsoleText('Self update cannot continue because the installed agent (' + agents[0] + ') conflicts with the currently running Temp/Console agent...', sessionid); return; @@ -648,11 +647,25 @@ function agentUpdate_Start(updateurl, updateoptions) { sendAgentMessage('Self Update FAILED because the downloaded agent FAILED hash check (' + agentUpdate_Start._retryCount + '), URL: ' + updateurl, 3); agentUpdate_Start._selfupdate = null; + try + { + // We are clearing these two properties, becuase some older agents may not cleanup correctly causing problems with the retry + require('https').globalAgent.sockets = {}; + require('https').globalAgent.requests = {}; + } + catch(z) + {} + if (needStreamFix) + { + sendConsoleText('This is an older agent that may have an httpstream bug. On next retry will try to fetch the update differently...'); + needStreamFix = false; + } + if (agentUpdate_Start._retryCount < 4) { // Retry the download again - sendConsoleText('Self Update will try again in 60 seconds...', sessionid); - agentUpdate_Start._timeout = setTimeout(agentUpdate_Start, 60000, updateurl, updateoptions); + sendConsoleText('Self Update will try again in 20 seconds...', sessionid); + agentUpdate_Start._timeout = setTimeout(agentUpdate_Start, 20000, updateurl, updateoptions); } else { @@ -708,8 +721,11 @@ function agentUpdate_Start(updateurl, updateoptions) { } catch (zz) { - sendConsoleText('Self Update encountered an error trying to restart service', sessionid); - sendAgentMessage('Self Update encountered an error trying to restart service', 3); + if (zz.toString() != 'waitExit() aborted because thread is exiting') + { + sendConsoleText('Self Update encountered an error trying to restart service', sessionid); + sendAgentMessage('Self Update encountered an error trying to restart service', 3); + } } break; } @@ -900,7 +916,8 @@ function onTunnelControlData(data, ws) { } -require('MeshAgent').AddCommandHandler(function (data) { +require('MeshAgent').AddCommandHandler(function (data) +{ if (typeof data == 'object') { // If this is a console command, parse it and call the console handler switch (data.action) { diff --git a/amtmanager.js b/amtmanager.js index 34d95781..23004792 100644 --- a/amtmanager.js +++ b/amtmanager.js @@ -1525,55 +1525,55 @@ module.exports.CreateAmtManager = function (parent) { dev.amtstack.Delete('CIM_WiFiEndpointSettings', { InstanceID: 'Intel(r) AMT:WiFi Endpoint Settings ' + profilesToRemove[i].ElementName }, function (stack, name, responses, status) { }, 0, 1); } } + } - // Check the 802.1x client certificate expiration time - // TODO: We are only getting the client cert from the wired 802.1x profile, need to get it for wireless too. - var netAuthClientCert = null; - if (netAuthClientCertInstanceId != null) { - netAuthClientCert = getInstance(responses['AMT_PublicKeyCertificate'].responses, netAuthClientCertInstanceId); - if (netAuthClientCert) { - var cert = null; - try { cert = obj.parent.certificateOperations.forge.pki.certificateFromAsn1(obj.parent.certificateOperations.forge.asn1.fromDer(obj.parent.certificateOperations.forge.util.decode64(netAuthClientCert.X509Certificate))); } catch (ex) { } - if (cert != null) { - const certStart = new Date(cert.validity.notBefore).getTime(); - const certEnd = new Date(cert.validity.notAfter).getTime(); - const certMidPoint = certStart + ((certEnd - certStart) / 2); - if (Date.now() > certMidPoint) { newNetAuthProfileRequested = true; } // Past mid-point or expired, request a new 802.1x certificate & profile - } + // Check the 802.1x client certificate expiration time + // TODO: We are only getting the client cert from the wired 802.1x profile, need to get it for wireless too. + var netAuthClientCert = null; + if (netAuthClientCertInstanceId != null) { + netAuthClientCert = getInstance(responses['AMT_PublicKeyCertificate'].responses, netAuthClientCertInstanceId); + if (netAuthClientCert) { + var cert = null; + try { cert = obj.parent.certificateOperations.forge.pki.certificateFromAsn1(obj.parent.certificateOperations.forge.asn1.fromDer(obj.parent.certificateOperations.forge.util.decode64(netAuthClientCert.X509Certificate))); } catch (ex) { } + if (cert != null) { + const certStart = new Date(cert.validity.notBefore).getTime(); + const certEnd = new Date(cert.validity.notAfter).getTime(); + const certMidPoint = certStart + ((certEnd - certStart) / 2); + if (Date.now() > certMidPoint) { newNetAuthProfileRequested = true; } // Past mid-point or expired, request a new 802.1x certificate & profile } } + } - // Figure out is there are no changes to 802.1x wired configuration - if ((wiredMatch == 0) && (newNetAuthProfileRequested == false)) { wiredConfig = false; } + // Figure out if there are no changes to 802.1x wired configuration + if ((wiredMatch == 0) && (newNetAuthProfileRequested == false)) { wiredConfig = false; } - // See if we need to ask MeshCentral Satellite for a new 802.1x profile - if (newNetAuthProfileRequested && (typeof srvNetAuthProfile.satellitecredentials == 'string')) { - // Credentials for this 802.1x profile are provided using MeshCentral Satellite - // Send a message to Satellite requesting a 802.1x profile for this device - dev.consoleMsg("Requesting 802.1x credentials for " + netAuthStrings[srvNetAuthProfile.authenticationprotocol] + " from MeshCentral Satellite..."); - dev.netAuthSatReqId = Buffer.from(parent.crypto.randomBytes(16), 'binary').toString('base64'); // Generate a crypto-secure request id. - dev.netAuthSatReqData = { domain: domain, wiredConfig: wiredConfig, wirelessConfig: wirelessConfig, devNetAuthProfile: devNetAuthProfile, srvNetAuthProfile: srvNetAuthProfile, profilesToAdd: profilesToAdd, prioritiesInUse: prioritiesInUse, responses: responses, xxCertificates: xxCertificates, xxCertPrivateKeys: xxCertPrivateKeys } - const request = { action: 'satellite', subaction: '802.1x-ProFile-Request', satelliteFlags: 2, nodeid: dev.nodeid, icon: dev.icon, domain: dev.nodeid.split('/')[1], nolog: 1, reqid: dev.netAuthSatReqId, authProtocol: srvNetAuthProfile.authenticationprotocol, devname: dev.name, osname: dev.rname, ver: dev.intelamt.ver }; - if (netAuthClientCert != null) { request.cert = netAuthClientCert.X509Certificate; request.certid = netAuthClientCertInstanceId; } - parent.DispatchEvent([srvNetAuthProfile.satellitecredentials], obj, request); + // See if we need to ask MeshCentral Satellite for a new 802.1x profile + if (newNetAuthProfileRequested && (typeof srvNetAuthProfile.satellitecredentials == 'string')) { + // Credentials for this 802.1x profile are provided using MeshCentral Satellite + // Send a message to Satellite requesting a 802.1x profile for this device + dev.consoleMsg("Requesting 802.1x credentials for " + netAuthStrings[srvNetAuthProfile.authenticationprotocol] + " from MeshCentral Satellite..."); + dev.netAuthSatReqId = Buffer.from(parent.crypto.randomBytes(16), 'binary').toString('base64'); // Generate a crypto-secure request id. + dev.netAuthSatReqData = { domain: domain, wiredConfig: wiredConfig, wirelessConfig: wirelessConfig, devNetAuthProfile: devNetAuthProfile, srvNetAuthProfile: srvNetAuthProfile, profilesToAdd: profilesToAdd, prioritiesInUse: prioritiesInUse, responses: responses, xxCertificates: xxCertificates, xxCertPrivateKeys: xxCertPrivateKeys } + const request = { action: 'satellite', subaction: '802.1x-ProFile-Request', satelliteFlags: 2, nodeid: dev.nodeid, icon: dev.icon, domain: dev.nodeid.split('/')[1], nolog: 1, reqid: dev.netAuthSatReqId, authProtocol: srvNetAuthProfile.authenticationprotocol, devname: dev.name, osname: dev.rname, ver: dev.intelamt.ver }; + if (netAuthClientCert != null) { request.cert = netAuthClientCert.X509Certificate; request.certid = netAuthClientCertInstanceId; } + parent.DispatchEvent([srvNetAuthProfile.satellitecredentials], obj, request); - // Set a response timeout - const netAuthTimeoutFunc = function netAuthTimeout() { - if (isAmtDeviceValid(netAuthTimeout.dev) == false) return; // Device no longer exists, ignore this request. - if (dev.netAuthSatReqId != null) { - delete netAuthTimeout.dev.netAuthSatReqId; - delete netAuthTimeout.dev.netAuthSatReqData; - netAuthTimeout.dev.consoleMsg("MeshCentral Satellite did not respond in time, 802.1x profile will not be set."); - devTaskCompleted(netAuthTimeout.dev); - } + // Set a response timeout + const netAuthTimeoutFunc = function netAuthTimeout() { + if (isAmtDeviceValid(netAuthTimeout.dev) == false) return; // Device no longer exists, ignore this request. + if (dev.netAuthSatReqId != null) { + delete netAuthTimeout.dev.netAuthSatReqId; + delete netAuthTimeout.dev.netAuthSatReqData; + netAuthTimeout.dev.consoleMsg("MeshCentral Satellite did not respond in time, 802.1x profile will not be set."); + devTaskCompleted(netAuthTimeout.dev); } - netAuthTimeoutFunc.dev = dev; - dev.netAuthSatReqTimer = setTimeout(netAuthTimeoutFunc, 20000); - return; - } else { - // No need to call MeshCentral Satellite for a 802.1x profile, so configure everything now. - attempt8021xSyncEx(dev, { domain: domain, wiredConfig: wiredConfig, wirelessConfig: wirelessConfig, devNetAuthProfile: devNetAuthProfile, srvNetAuthProfile: srvNetAuthProfile, profilesToAdd: profilesToAdd, prioritiesInUse: prioritiesInUse, responses: responses, xxCertificates: xxCertificates, xxCertPrivateKeys: xxCertPrivateKeys }); } + netAuthTimeoutFunc.dev = dev; + dev.netAuthSatReqTimer = setTimeout(netAuthTimeoutFunc, 20000); + return; + } else { + // No need to call MeshCentral Satellite for a 802.1x profile, so configure everything now. + attempt8021xSyncEx(dev, { domain: domain, wiredConfig: wiredConfig, wirelessConfig: wirelessConfig, devNetAuthProfile: devNetAuthProfile, srvNetAuthProfile: srvNetAuthProfile, profilesToAdd: profilesToAdd, prioritiesInUse: prioritiesInUse, responses: responses, xxCertificates: xxCertificates, xxCertPrivateKeys: xxCertPrivateKeys }); } }); } @@ -1813,31 +1813,34 @@ module.exports.CreateAmtManager = function (parent) { function attemptWifiSyncEx2(dev, devNetAuthData) { if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. const responses = devNetAuthData.responses; + const wirelessConfig = devNetAuthData.wirelessConfig; - // Check if local WIFI profile sync is enabled, if not, enabled it. - if ((responses['AMT_WiFiPortConfigurationService'] != null) && (responses['AMT_WiFiPortConfigurationService'].response != null) && (responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] == 0)) { - responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] = 1; - dev.amtstack.Put('AMT_WiFiPortConfigurationService', responses['AMT_WiFiPortConfigurationService'].response, function (stack, name, response, status) { - if (status != 200) { dev.consoleMsg("Unable to enable local WIFI profile sync."); } else { dev.consoleMsg("Enabled local WIFI profile sync."); } - }); - } + if (wirelessConfig) { + // Check if local WIFI profile sync is enabled, if not, enabled it. + if ((responses['AMT_WiFiPortConfigurationService'] != null) && (responses['AMT_WiFiPortConfigurationService'].response != null) && (responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] == 0)) { + responses['AMT_WiFiPortConfigurationService'].response['localProfileSynchronizationEnabled'] = 1; + dev.amtstack.Put('AMT_WiFiPortConfigurationService', responses['AMT_WiFiPortConfigurationService'].response, function (stack, name, response, status) { + if (status != 200) { dev.consoleMsg("Unable to enable local WIFI profile sync."); } else { dev.consoleMsg("Enabled local WIFI profile sync."); } + }); + } - // Change the WIFI state if needed. Right now, we always enable it. - // WifiState = { 3: "Disabled", 32768: "Enabled in S0", 32769: "Enabled in S0, Sx/AC" }; - var wifiState = 32769; // For now, always enable WIFI - if (responses['CIM_WiFiPort'].responses.Body.EnabledState != 32769) { - if (wifiState == 3) { - dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) { - const dev = stack.dev; - if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. - if (status == 200) { dev.consoleMsg("Disabled WIFI."); } - }); - } else { - dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) { - const dev = stack.dev; - if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. - if (status == 200) { dev.consoleMsg("Enabled WIFI."); } - }); + // Change the WIFI state if needed. Right now, we always enable it. + // WifiState = { 3: "Disabled", 32768: "Enabled in S0", 32769: "Enabled in S0, Sx/AC" }; + var wifiState = 32769; // For now, always enable WIFI + if (responses['CIM_WiFiPort'].responses.Body.EnabledState != 32769) { + if (wifiState == 3) { + dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) { + const dev = stack.dev; + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. + if (status == 200) { dev.consoleMsg("Disabled WIFI."); } + }); + } else { + dev.amtstack.CIM_WiFiPort_RequestStateChange(wifiState, null, function (stack, name, responses, status) { + const dev = stack.dev; + if (isAmtDeviceValid(dev) == false) return; // Device no longer exists, ignore this request. + if (status == 200) { dev.consoleMsg("Enabled WIFI."); } + }); + } } } @@ -3010,17 +3013,20 @@ module.exports.CreateAmtManager = function (parent) { function guidToStr(g) { return g.substring(6, 8) + g.substring(4, 6) + g.substring(2, 4) + g.substring(0, 2) + '-' + g.substring(10, 12) + g.substring(8, 10) + '-' + g.substring(14, 16) + g.substring(12, 14) + '-' + g.substring(16, 20) + '-' + g.substring(20); } + // Base64 to string conversion utility functions + function atob(x) { return Buffer.from(x, 'base64').toString('binary'); } + function btoa(x) { return Buffer.from(x, 'binary').toString('base64'); } + // Check which key pair matches the public key in the certificate function amtcert_linkCertPrivateKey(certs, keys) { + if ((keys == null) || (keys.length == 0)) return; for (var i in certs) { var cert = certs[i]; try { - if (keys.length == 0) return; - var b = obj.parent.certificateOperations.forge.asn1.fromDer(cert.X509CertificateBin); - var a = obj.parent.certificateOperations.forge.pki.certificateFromAsn1(b).publicKey; - var publicKeyPEM = obj.parent.certificateOperations.forge.pki.publicKeyToPem(a).substring(28 + 32).replace(/(\r\n|\n|\r)/gm, ""); + var publicKeyPEM = obj.parent.certificateOperations.forge.pki.publicKeyToPem(obj.parent.certificateOperations.forge.pki.certificateFromAsn1(obj.parent.certificateOperations.forge.asn1.fromDer(cert.X509CertificateBin)).publicKey).substring(28 + 32).replace(/(\r\n|\n|\r)/gm, ""); + publicKeyPEM = publicKeyPEM.substring(0, publicKeyPEM.length - 24); // Remove the PEM footer for (var j = 0; j < keys.length; j++) { - if (publicKeyPEM === (keys[j]['DERKey'] + '-----END PUBLIC KEY-----')) { + if ((publicKeyPEM === (keys[j]['DERKey'])) || (publicKeyPEM == btoa(atob(keys[j]['DERKey']).substring(24)))) { // Match directly or, new version of Intel AMT put the key type OID in the private key, skip that and match. keys[j].XCert = cert; // Link the key pair to the certificate cert.XPrivateKey = keys[j]; // Link the certificate to the key pair } diff --git a/apprelays.js b/apprelays.js index ac742a2d..aa6e7bb2 100644 --- a/apprelays.js +++ b/apprelays.js @@ -13,13 +13,13 @@ /*jshint esversion: 6 */ "use strict"; - /* Protocol numbers 10 = RDP 11 = SSH-TERM 12 = VNC -13 - SSH-FILES +13 = SSH-FILES +14 = Web-TCP */ // Protocol Numbers @@ -58,6 +58,604 @@ const MESHRIGHT_GUESTSHARING = 0x00080000; // 524288 const MESHRIGHT_DEVICEDETAILS = 0x00100000; // 1048576 const MESHRIGHT_ADMIN = 0xFFFFFFFF; +// SerialTunnel object is used to embed TLS within another connection. +function SerialTunnel(options) { + var obj = new require('stream').Duplex(options); + obj.forwardwrite = null; + obj.updateBuffer = function (chunk) { this.push(chunk); }; + obj._write = function (chunk, encoding, callback) { if (obj.forwardwrite != null) { obj.forwardwrite(chunk); } else { console.err("Failed to fwd _write."); } if (callback) callback(); }; // Pass data written to forward + obj._read = function (size) { }; // Push nothing, anything to read should be pushed from updateBuffer() + return obj; +} + +// Construct a Web relay object +module.exports.CreateWebRelaySession = function (parent, db, req, args, domain, userid, nodeid, addr, port, appid) { + const obj = {}; + obj.parent = parent; + obj.lastOperation = Date.now(); + obj.domain = domain; + obj.userid = userid; + obj.nodeid = nodeid; + obj.addr = addr; + obj.port = port; + obj.appid = appid; + var pendingRequests = []; + var nextTunnelId = 1; + var tunnels = {}; + var errorCount = 0; // If we keep closing tunnels without processing requests, fail the requests + + // Any HTTP cookie set by the device is going to be shared between all tunnels to that device. + obj.webCookies = {}; + + // Events + obj.closed = false; + obj.onclose = null; + + // Check if any tunnels need to be cleaned up + obj.checkTimeout = function () { + const limit = Date.now() - (1 * 60 * 1000); // This is is 5 minutes before current time + + // Close any old non-websocket tunnels + const tunnelToRemove = []; + for (var i in tunnels) { if ((tunnels[i].lastOperation < limit) && (tunnels[i].isWebSocket !== true)) { tunnelToRemove.push(tunnels[i]); } } + for (var i in tunnelToRemove) { tunnelToRemove[i].close(); } + + // Close this session if no longer used + if (obj.lastOperation < limit) { + var count = 0; + for (var i in tunnels) { count++; } + if (count == 0) { close(); } // Time limit reached and no tunnels, clean up. + } + } + + // Handle new HTTP request + obj.handleRequest = function (req, res) { + pendingRequests.push([req, res, false]); + handleNextRequest(); + } + + // Handle new websocket request + obj.handleWebSocket = function (ws, req) { + pendingRequests.push([req, ws, true]); + handleNextRequest(); + } + + // Handle request + function handleNextRequest() { + // if there are not pending requests, do nothing + if (pendingRequests.length == 0) return; + + // If the errorCount is high, something is really wrong, we are opening lots of tunnels and not processing any requests. + if (errorCount > 5) { close(); return; } + + // Check to see if any of the tunnels are free + var count = 0; + for (var i in tunnels) { + count += (tunnels[i].isWebSocket ? 0 : 1); + if ((tunnels[i].relayActive == true) && (tunnels[i].res == null) && (tunnels[i].isWebSocket == false)) { + // Found a free tunnel, use it + const x = pendingRequests.shift(); + if (x[2] == true) { tunnels[i].processWebSocket(x[0], x[1]); } else { tunnels[i].processRequest(x[0], x[1]); } + return; + } + } + + if (count > 0) return; + launchNewTunnel(); + } + + function launchNewTunnel() { + // Launch a new tunnel + const tunnel = module.exports.CreateWebRelay(obj, db, args, domain); + tunnel.onclose = function (tunnelId, processedCount) { + if (processedCount == 0) { errorCount++; } // If this tunnel closed without processing any requests, mark this as an error + delete tunnels[tunnelId]; + handleNextRequest(); + } + tunnel.onconnect = function (tunnelId) { + if (pendingRequests.length > 0) { + const x = pendingRequests.shift(); + if (x[2] == true) { tunnels[tunnelId].processWebSocket(x[0], x[1]); } else { tunnels[tunnelId].processRequest(x[0], x[1]); } + } + } + tunnel.oncompleted = function (tunnelId) { + errorCount = 0; // Something got completed, clear any error count + if (pendingRequests.length > 0) { + const x = pendingRequests.shift(); + if (x[2] == true) { tunnels[tunnelId].processWebSocket(x[0], x[1]); } else { tunnels[tunnelId].processRequest(x[0], x[1]); } + } + } + tunnel.connect(userid, nodeid, addr, port, appid); + tunnel.tunnelId = nextTunnelId++; + tunnels[tunnel.tunnelId] = tunnel; + } + + // Close all tunnels + function close() { + // Set the session as closed + if (obj.closed == true) return; + obj.closed = true; + + // Close all tunnels + for (var i in tunnels) { tunnels[i].close(); } + tunnels = null; + + // Close any pending requests + for (var i in pendingRequests) { if (pendingRequests[i][2] == true) { pendingRequests[i][1].close(); } else { pendingRequests[i][1].end(); } } + + // Notify of session closure + if (obj.onclose) { obj.onclose(obj.userid + '/' + obj.sessionId); } + + // Cleanup + delete obj.userid; + delete obj.lastOperation; + } + + return obj; +} + + +// Construct a Web relay object +module.exports.CreateWebRelay = function (parent, db, args, domain) { + //const Net = require('net'); + const WebSocket = require('ws') + + const obj = {}; + obj.lastOperation = Date.now(); + obj.relayActive = false; + obj.closed = false; + obj.isWebSocket = false; + obj.processedRequestCount = 0; + const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. + + // Events + obj.onclose = null; + obj.oncompleted = null; + obj.onconnect = null; + + // Process a HTTP request + obj.processRequest = function (req, res) { + if (obj.relayActive == false) { console.log("ERROR: Attempt to use an unconnected tunnel"); return false; } + parent.lastOperation = obj.lastOperation = Date.now(); + + // Construct the HTTP request + var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n'; + const blockedHeaders = ['origin', 'cookie']; // These are headers we do not forward + for (var i in req.headers) { if (blockedHeaders.indexOf(i) == -1) { request += i + ': ' + req.headers[i] + '\r\n'; } } + var cookieStr = ''; + for (var i in parent.webCookies) { if (cookieStr != '') { cookieStr += '; ' } cookieStr += (i + '=' + parent.webCookies[i].value); } + if (cookieStr.length > 0) { request += 'cookie: ' + cookieStr + '\r\n' } // If we have session cookies, set them in the header here + request += '\r\n'; + + if (req.headers['content-length'] != null) { + // Stream the HTTP request and body, this is a content-length HTTP request, just forward the body data + send(Buffer.from(request)); + req.on('data', function (data) { send(data); }); // TODO: Flow control (Not sure how to do this in ExpressJS) + req.on('end', function () { }); + } else if (req.headers['transfer-encoding'] != null) { + // Stream the HTTP request and body, this is a chunked encoded HTTP request + // TODO: Flow control (Not sure how to do this in ExpressJS) + send(Buffer.from(request)); + req.on('data', function (data) { send(Buffer.concat([Buffer.from(data.length.toString(16) + '\r\n', 'binary'), data, send(Buffer.from('\r\n', 'binary'))])); }); + req.on('end', function () { send(Buffer.from('0\r\n\r\n', 'binary')); }); + } else { + // Request has no body, send it now + send(Buffer.from(request)); + } + obj.res = res; + } + + // Process a websocket request + obj.processWebSocket = function (req, ws) { + if (obj.relayActive == false) { console.log("ERROR: Attempt to use an unconnected tunnel"); return false; } + parent.lastOperation = obj.lastOperation = Date.now(); + + // Mark this tunnel as being a web socket tunnel + obj.isWebSocket = true; + obj.ws = ws; + + // Pause the websocket until we get a tunnel connected + obj.ws._socket.pause(); + + // Remove the trailing '/.websocket' if needed + var baseurl = req.url, i = req.url.indexOf('?'); + if (i > 0) { baseurl = req.url.substring(0, i); } + if (baseurl.endsWith('/.websocket')) { req.url = baseurl.substring(0, baseurl.length - 11) + ((i < 1) ? '' : req.url.substring(i)); } + + // Construct the HTTP request + var request = req.method + ' ' + req.url + ' HTTP/' + req.httpVersion + '\r\n'; + const blockedHeaders = ['origin', 'cookie', 'sec-websocket-extensions']; // These are headers we do not forward + for (var i in req.headers) { if (blockedHeaders.indexOf(i) == -1) { request += i + ': ' + req.headers[i] + '\r\n'; } } + var cookieStr = ''; + for (var i in parent.webCookies) { if (cookieStr != '') { cookieStr += '; ' } cookieStr += (i + '=' + parent.webCookies[i].value); } + if (cookieStr.length > 0) { request += 'cookie: ' + cookieStr + '\r\n' } // If we have session cookies, set them in the header here + request += '\r\n'; + send(Buffer.from(request)); + + // Hook up the websocket events + obj.ws.on('message', function (data) { + // Setup opcode and payload + var op = 2, payload = data; + if (typeof data == 'string') { op = 1; payload = Buffer.from(data, 'binary'); } // Text frame + sendWebSocketFrameToDevice(op, payload); + }); + + obj.ws.on('ping', function (data) { sendWebSocketFrameToDevice(9, data); }); // Forward ping frame + obj.ws.on('pong', function (data) { sendWebSocketFrameToDevice(10, data); }); // Forward pong frame + obj.ws.on('close', function () { obj.close(); }); + obj.ws.on('error', function (err) { obj.close(); }); + } + + function sendWebSocketFrameToDevice(op, payload) { + // Select a random mask + const mask = parent.parent.crypto.randomBytes(4) + + // Setup header and mask + var header = null; + if (payload.length < 126) { + header = Buffer.alloc(6); // Header (2) + Mask (4) + header[0] = 0x80 + op; // FIN + OP + header[1] = 0x80 + payload.length; // Mask + Length + mask.copy(header, 2, 0, 4); // Copy the mask + } else if (payload.length <= 0xFFFF) { + header = Buffer.alloc(8); // Header (2) + Length (2) + Mask (4) + header[0] = 0x80 + op; // FIN + OP + header[1] = 0x80 + 126; // Mask + 126 + header.writeInt16BE(payload.length, 2); // Payload size + mask.copy(header, 4, 0, 4); // Copy the mask + } else { + header = Buffer.alloc(14); // Header (2) + Length (8) + Mask (4) + header[0] = 0x80 + op; // FIN + OP + header[1] = 0x80 + 127; // Mask + 127 + header.writeInt32BE(payload.length, 6); // Payload size + mask.copy(header, 10, 0, 4); // Copy the mask + } + + // Mask the payload + for (var i = 0; i < payload.length; i++) { payload[i] = (payload[i] ^ mask[i % 4]); } + + // Send the frame + //console.log(obj.tunnelId, '-->', op, payload.length); + send(Buffer.concat([header, payload])); + } + + // Disconnect + obj.close = function (arg) { + if (obj.closed == true) return; + obj.closed = true; + + if (obj.tls) { + try { obj.tls.end(); } catch (ex) { console.log(ex); } + delete obj.tls; + } + + /* + // Event the session ending + if ((obj.startTime) && (obj.meshid != null)) { + // Collect how many raw bytes where received and sent. + // We sum both the websocket and TCP client in this case. + var inTraffc = obj.ws._socket.bytesRead, outTraffc = obj.ws._socket.bytesWritten; + if (obj.wsClient != null) { inTraffc += obj.wsClient._socket.bytesRead; outTraffc += obj.wsClient._socket.bytesWritten; } + const sessionSeconds = Math.round((Date.now() - obj.startTime) / 1000); + const user = parent.users[obj.cookie.userid]; + const username = (user != null) ? user.name : null; + const event = { etype: 'relay', action: 'relaylog', domain: domain.id, nodeid: obj.nodeid, userid: obj.cookie.userid, username: username, sessionid: obj.sessionid, msgid: 123, msgArgs: [sessionSeconds, obj.sessionid], msg: "Left Web-SSH session \"" + obj.sessionid + "\" after " + sessionSeconds + " second(s).", protocol: PROTOCOL_WEBSSH, bytesin: inTraffc, bytesout: outTraffc }; + parent.DispatchEvent(['*', obj.nodeid, obj.cookie.userid, obj.meshid], obj, event); + delete obj.startTime; + delete obj.sessionid; + } + */ + if (obj.wsClient) { + obj.wsClient.removeAllListeners('open'); + obj.wsClient.removeAllListeners('message'); + obj.wsClient.removeAllListeners('close'); + try { obj.wsClient.close(); } catch (ex) { console.log(ex); } + delete obj.wsClient; + } + + // Close any pending request + if (obj.res) { obj.res.end(); delete obj.res; } + if (obj.ws) { obj.ws.close(); delete obj.ws; } + + // Event disconnection + if (obj.onclose) { obj.onclose(obj.tunnelId, obj.processedRequestCount); } + + obj.relayActive = false; + }; + + // Start the looppback server + obj.connect = function (userid, nodeid, addr, port, appid) { + if (obj.relayActive || obj.closed) return; + obj.addr = addr; + obj.port = port; + obj.appid = appid; + + // Encode a cookie for the mesh relay + const cookieContent = { userid: userid, domainid: domain.id, nodeid: nodeid, tcpport: port }; + if (addr != null) { cookieContent.tcpaddr = addr; } + const cookie = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey); + + try { + // Setup the correct URL with domain and use TLS only if needed. + const options = { rejectUnauthorized: false }; + const protocol = (args.tlsoffload) ? 'ws' : 'wss'; + var domainadd = ''; + if ((domain.dns == null) && (domain.id != '')) { domainadd = domain.id + '/' } + const url = protocol + '://localhost:' + args.port + '/' + domainadd + (((obj.mtype == 3) && (obj.relaynodeid == null)) ? 'local' : 'mesh') + 'relay.ashx?p=14&auth=' + cookie; // Protocol 14 is Web-TCP + parent.parent.debug('relay', 'TCP: Connection websocket to ' + url); + obj.wsClient = new WebSocket(url, options); + obj.wsClient.on('open', function () { parent.parent.debug('relay', 'TCP: Relay websocket open'); }); + obj.wsClient.on('message', function (data) { // Make sure to handle flow control. + if (obj.tls) { + // WS --> TLS + processRawHttpData(data); + } else if (obj.relayActive == false) { + if ((data == 'c') || (data == 'cr')) { + if (appid == 2) { + // TLS needs to be setup + obj.ser = new SerialTunnel(); + obj.ser.forwardwrite = function (data) { if (data.length > 0) { try { obj.wsClient.send(data); } catch (ex) { } } }; // TLS ---> WS + + // TLSSocket to encapsulate TLS communication, which then tunneled via SerialTunnel + const tlsoptions = { socket: obj.ser, rejectUnauthorized: false }; + obj.tls = require('tls').connect(tlsoptions, function () { + parent.parent.debug('relay', "Web Relay Secure TLS Connection"); + obj.relayActive = true; + parent.lastOperation = obj.lastOperation = Date.now(); // Update time of last opertion performed + if (obj.onconnect) { obj.onconnect(obj.tunnelId); } // Event connection + }); + obj.tls.setEncoding('binary'); + obj.tls.on('error', function (err) { parent.parent.debug('relay', "Web Relay TLS Connection Error", err); obj.close(); }); + + // Decrypted tunnel from TLS communcation to be forwarded to the browser + obj.tls.on('data', function (data) { processHttpData(data); }); // TLS ---> Browser + } else { + // No TLS needed, tunnel is now active + obj.relayActive = true; + parent.lastOperation = obj.lastOperation = Date.now(); // Update time of last opertion performed + if (obj.onconnect) { obj.onconnect(obj.tunnelId); } // Event connection + } + } + } else { + processRawHttpData(data); + } + }); + obj.wsClient.on('close', function () { parent.parent.debug('relay', 'TCP: Relay websocket closed'); obj.close(); }); + obj.wsClient.on('error', function (err) { parent.parent.debug('relay', 'TCP: Relay websocket error: ' + err); obj.close(); }); + } catch (ex) { + console.log(ex); + } + } + + function processRawHttpData(data) { + if (typeof data == 'string') { + // Forward any ping/pong commands to the browser + var cmd = null; + try { cmd = JSON.parse(data); } catch (ex) { } + if ((cmd != null) && (cmd.ctrlChannel == '102938') && (cmd.type == 'ping')) { cmd.type = 'pong'; obj.wsClient.send(JSON.stringify(cmd)); } + return; + } + if (obj.tls) { + // If TLS is in use, WS --> TLS + if (data.length > 0) { try { obj.ser.updateBuffer(data); } catch (ex) { console.log(ex); } } + } else { + // Relay WS --> TCP, event data coming in + processHttpData(data.toString('binary')); + } + } + + // Process incoming HTTP data + obj.socketAccumulator = ''; + obj.socketParseState = 0; + obj.socketContentLengthRemaining = 0; + function processHttpData(data) { + obj.socketAccumulator += data; + while (true) { + //console.log('ACC(' + obj.socketAccumulator + '): ' + obj.socketAccumulator); + if (obj.socketParseState == 0) { + var headersize = obj.socketAccumulator.indexOf('\r\n\r\n'); + if (headersize < 0) return; + //obj.Debug("Header: "+obj.socketAccumulator.substring(0, headersize)); // Display received HTTP header + obj.socketHeader = obj.socketAccumulator.substring(0, headersize).split('\r\n'); + obj.socketAccumulator = obj.socketAccumulator.substring(headersize + 4); + obj.socketXHeader = { Directive: obj.socketHeader[0].split(' ') }; + for (var i in obj.socketHeader) { + if (i != 0) { + var x2 = obj.socketHeader[i].indexOf(':'); + const n = obj.socketHeader[i].substring(0, x2).toLowerCase(); + const v = obj.socketHeader[i].substring(x2 + 2); + if (n == 'set-cookie') { // Since "set-cookie" can be present many times in the header, handle it as an array of values + if (obj.socketXHeader[n] == null) { obj.socketXHeader[n] = [v]; } else { obj.socketXHeader[n].push(v); } + } else { + obj.socketXHeader[n] = v; + } + } + } + + // Check if this HTTP request has a body + if ((obj.socketXHeader['connection'] != null) && (obj.socketXHeader['connection'].toLowerCase() == 'close')) { obj.socketParseState = 1; } + if (obj.socketXHeader['content-length'] != null) { obj.socketParseState = 1; } + if ((obj.socketXHeader['transfer-encoding'] != null) && (obj.socketXHeader['transfer-encoding'].toLowerCase() == 'chunked')) { obj.socketParseState = 1; } + if (obj.isWebSocket) { + if ((obj.socketXHeader['connection'] != null) && (obj.socketXHeader['connection'].toLowerCase() == 'upgrade')) { + obj.processedRequestCount++; + obj.socketParseState = 2; // Switch to decoding websocket frames + obj.ws._socket.resume(); // Resume the browser's websocket + } else { + obj.close(); // Failed to upgrade to websocket + } + } + + // Forward the HTTP request into the tunnel, if no body is present, close the request. + processHttpResponse(obj.socketXHeader, null, (obj.socketParseState == 0)); + } + if (obj.socketParseState == 1) { + var csize = -1; + if ((obj.socketXHeader['connection'] != null) && (obj.socketXHeader['connection'].toLowerCase() == 'close')) { + // The body ends with a close, in this case, we will only process the header + processHttpResponse(null, null, true); + csize = 0; + } else if (obj.socketXHeader['content-length'] != null) { + // The body length is specified by the content-length + if (obj.socketContentLengthRemaining == 0) { obj.socketContentLengthRemaining = parseInt(obj.socketXHeader['content-length']); } // Set the remaining content-length if not set + var data = obj.socketAccumulator.substring(0, obj.socketContentLengthRemaining); // Grab the available data, not passed the expected content-length + obj.socketAccumulator = obj.socketAccumulator.substring(data.length); // Remove the data from the accumulator + obj.socketContentLengthRemaining -= data.length; // Substract the obtained data from the expected size + processHttpResponse(null, data, (obj.socketContentLengthRemaining == 0)); // Send any data we have, if we are done, signal the end of the response + if (obj.socketContentLengthRemaining > 0) return; // If more data is needed, return now so we exit the while() loop. + csize = 0; // We are done + } + else if ((obj.socketXHeader['transfer-encoding'] != null) && (obj.socketXHeader['transfer-encoding'].toLowerCase() == 'chunked')) { + // The body is chunked + var clen = obj.socketAccumulator.indexOf('\r\n'); + if (clen < 0) { return; } // Chunk length not found, exit now and get more data. + // Chunk length if found, lets see if we can get the data. + csize = parseInt(obj.socketAccumulator.substring(0, clen), 16); + if (obj.socketAccumulator.length < clen + 2 + csize + 2) return; + // We got a chunk with all of the data, handle the chunck now. + var data = obj.socketAccumulator.substring(clen + 2, clen + 2 + csize); + obj.socketAccumulator = obj.socketAccumulator.substring(clen + 2 + csize + 2); + processHttpResponse(null, data, (csize == 0)); + } + if (csize == 0) { + //obj.Debug("xxOnSocketData DONE: (" + obj.socketData.length + "): " + obj.socketData); + obj.socketParseState = 0; + obj.socketHeader = null; + } + } + if (obj.socketParseState == 2) { + // We are in websocket pass-thru mode, decode the websocket frame + if (obj.socketAccumulator.length < 2) return; // Need at least 2 bytes to decode a websocket header + //console.log('WebSocket frame', obj.socketAccumulator.length, Buffer.from(obj.socketAccumulator, 'binary')); + + // Decode the websocket frame + const buf = Buffer.from(obj.socketAccumulator, 'binary'); + const fin = ((buf[0] & 0x80) != 0); + const rsv = ((buf[0] & 0x70) != 0); + const op = buf[0] & 0x0F; + const mask = ((buf[1] & 0x80) != 0); + var len = buf[1] & 0x7F; + //console.log(obj.tunnelId, 'fin: ' + fin + ', rsv: ' + rsv + ', op: ' + op + ', len: ' + len); + + // Calculate the total length + var payload = null; + if (len < 126) { + // 1 byte length + if (buf.length < (2 + len)) return; // Insuffisent data + payload = buf.slice(2, 2 + len); + obj.socketAccumulator = obj.socketAccumulator.substring(2 + len); // Remove data from accumulator + } else if (len == 126) { + // 2 byte length + if (buf.length < 4) return; + len = buf.readUInt16BE(2); + if (buf.length < (4 + len)) return; // Insuffisent data + payload = buf.slice(4, 4 + len); + obj.socketAccumulator = obj.socketAccumulator.substring(4 + len); // Remove data from accumulator + } if (len == 127) { + // 8 byte length + if (buf.length < 10) return; + len = buf.readUInt32BE(2); + if (len > 0) { obj.close(); return; } // This frame is larger than 4 gigabyte, close the connection. + len = buf.readUInt32BE(6); + if (buf.length < (10 + len)) return; // Insuffisent data + payload = buf.slice(10, 10 + len); + obj.socketAccumulator = obj.socketAccumulator.substring(10 + len); // Remove data from accumulator + } + if (buf.length < len) return; + + // If the mask or reserved bit are true, we are not decoding this right, close the connection. + if ((mask == true) || (rsv == true)) { obj.close(); return; } + + // TODO: If FIN is not set, we need to add support for continue frames + //console.log(obj.tunnelId, '<--', op, payload ? payload.length : 0); + + // Perform operation + switch (op) { + case 0: { break; } // Continue frame (TODO) + case 1: { try { obj.ws.send(payload.toString('binary')); } catch (ex) { } break; } // Text frame + case 2: { try { obj.ws.send(payload); } catch (ex) { } break; } // Binary frame + case 8: { obj.close(); return; } // Connection close + case 9: { try { obj.ws.ping(payload); } catch (ex) { } break; } // Ping frame + case 10: { try { obj.ws.pong(payload); } catch (ex) { } break; } // Pong frame + } + } + } + } + + // This is a fully parsed HTTP response from the remote device + function processHttpResponse(header, data, done) { + //console.log('processHttpResponse'); + if (obj.isWebSocket == false) { + if (obj.res == null) return; + parent.lastOperation = obj.lastOperation = Date.now(); // Update time of last opertion performed + + // If there is a header, send it + if (header != null) { + obj.res.status(parseInt(header.Directive[1])); // Set the status + const blockHeaders = ['Directive', 'sec-websocket-extensions']; // We do not forward these headers + for (var i in header) { + if (i == 'set-cookie') { + for (var ii in header[i]) { + // Decode the new cookie + //console.log('set-cookie', header[i][ii]); + const cookieSplit = header[i][ii].split(';'); + var newCookieName = null, newCookie = {}; + for (var j in cookieSplit) { + var l = cookieSplit[j].indexOf('='), k = null, v = null; + if (l == -1) { k = cookieSplit[j].trim(); } else { k = cookieSplit[j].substring(0, l).trim(); v = cookieSplit[j].substring(l + 1).trim(); } + if (j == 0) { newCookieName = k; newCookie.value = v; } else { newCookie[k.toLowerCase()] = (v == null) ? true : v; } + } + if (newCookieName != null) { + if ((typeof newCookie['max-age'] == 'string') && (parseInt(newCookie['max-age']) <= 0)) { + delete parent.webCookies[newCookieName]; // Remove a expired cookie + //console.log('clear-cookie', newCookieName); + } else if (((newCookie.secure != true) || (obj.tls != null))) { + parent.webCookies[newCookieName] = newCookie; // Keep this cookie in the session + if (newCookie.httponly != true) { obj.res.set(i, header[i]); } // if the cookie is not HTTP-only, forward it to the browser. We need to do this to allow JavaScript to read it. + //console.log('new-cookie', newCookieName, newCookie); + } + } + } + } + else if (blockHeaders.indexOf(i) == -1) { obj.res.set(i, header[i]); } // Set the headers if not blocked + } + obj.res.set('Content-Security-Policy', "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:;"); // Set an "allow all" policy, see if the can restrict this in the future + obj.res.set('Cache-Control', 'no-cache'); // Tell the browser not to cache the responses since since the relay port can be used for many relays + } + + // If there is data, send it + if (data != null) { obj.res.write(data, 'binary'); } + + // If we are done, close the response + if (done == true) { + // Close the response + obj.res.end(); + delete obj.res; + + // Event completion + obj.processedRequestCount++; + if (obj.oncompleted) { obj.oncompleted(obj.tunnelId); } + } + } else { + // Tunnel is now in web socket pass-thru mode + if ((typeof header.connection == 'string') && (header.connection.toLowerCase() == 'upgrade')) { + // Websocket upgrade succesful + obj.socketParseState = 2; + } else { + // Unable to upgrade to web socket + obj.close(); + } + } + } + + // Send data thru the relay tunnel. Written to use TLS if needed. + function send(data) { try { if (obj.tls) { obj.tls.write(data); } else { obj.wsClient.send(data); } } catch (ex) { } } + + parent.parent.debug('relay', 'TCP: Request for web relay'); + return obj; +}; + + // Construct a MSTSC Relay object, called upon connection // This implementation does not have TLS support // This is a bit of a hack as we are going to run the RDP connection thru a loopback connection. @@ -202,10 +800,16 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) { delete bitmap.data; send(['rdp-bitmap', bitmap]); // Send the bitmap metadata seperately, without bitmap data. }).on('clipboard', function (content) { - // Clipboard data changed - send(['rdp-clipboard', content]); + send(['rdp-clipboard', content]); // The clipboard data has changed + }).on('pointer', function (cursorId, cursorStr) { + if (cursorStr == null) { cursorStr = 'default'; } + if (obj.lastCursorStrSent != cursorStr) { + obj.lastCursorStrSent = cursorStr; + //console.log('pointer', cursorStr); + send(['rdp-pointer', cursorStr]); // The mouse pointer has changed + } }).on('close', function () { - send(['rdp-close']); + send(['rdp-close']); // This RDP session has closed }).on('error', function (err) { if (typeof err == 'string') { send(['rdp-error', err]); } if ((typeof err == 'object') && (err.err) && (err.code)) { send(['rdp-error', err.err, err.code]); } @@ -1623,4 +2227,4 @@ function checkRelayRights(parent, domain, user, relayNodeId, func) { parent.GetNodeWithRights(domain, user, relayNodeId, function (node, rights, visible) { func((node != null) && (rights == 0xFFFFFFFF)); }); -} \ No newline at end of file +} diff --git a/authenticode.js b/authenticode.js index faa5a016..213d3d4d 100644 --- a/authenticode.js +++ b/authenticode.js @@ -69,6 +69,11 @@ function loadCertificates(pemFileNames) { var k = PemKeys[j].indexOf('-----END RSA PRIVATE KEY-----'); if (k >= 0) { keys.push(pki.privateKeyFromPem('-----BEGIN RSA PRIVATE KEY-----' + PemKeys[j].substring(0, k) + '-----END RSA PRIVATE KEY-----')); } } + PemKeys = pem.split('-----BEGIN PRIVATE KEY-----'); + for (var j in PemKeys) { + var k = PemKeys[j].indexOf('-----END PRIVATE KEY-----'); + if (k >= 0) { keys.push(pki.privateKeyFromPem('-----BEGIN PRIVATE KEY-----' + PemKeys[j].substring(0, k) + '-----END PRIVATE KEY-----')); } + } } catch (ex) { } } if ((certs.length == 0) || (keys.length != 1)) return; // No certificates or private keys @@ -288,80 +293,218 @@ function createAuthenticodeHandler(path) { var derlen = forge.asn1.getBerValueLength(forge.util.createBuffer(pkcs7raw.slice(1, 5))) + 4; if (derlen != pkcs7raw.length) { pkcs7raw = pkcs7raw.slice(0, derlen); } - //console.log('pkcs7raw', Buffer.from(pkcs7raw, 'binary').toString('base64')); + // Decode the signature block and check that it's valid + var pkcs7der = null, valid = false; + try { pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(pkcs7raw)); } catch (ex) { } + try { valid = ((pkcs7der != null) && (forge.asn1.derToOid(pkcs7der.value[1].value[0].value[2].value[0].value) == "1.3.6.1.4.1.311.2.1.4")); } catch (ex) { } + if (pkcs7der == null) { + // Can't decode the signature + obj.header.sigpos = 0; + obj.header.siglen = 0; + obj.header.signed = false; + } else { + // To work around ForgeJS PKCS#7 limitation, this may break PKCS7 verify if ForgeJS adds support for it in the future + // Switch content type from "1.3.6.1.4.1.311.2.1.4" to "1.2.840.113549.1.7.1" + pkcs7der.value[1].value[0].value[2].value[0].value = forge.asn1.oidToDer(forge.pki.oids.data).data; - // Decode the signature block - var pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(pkcs7raw)); + // Decode the PKCS7 message + var pkcs7 = null, pkcs7content = null; + try { + pkcs7 = p7.messageFromAsn1(pkcs7der); + pkcs7content = pkcs7.rawCapture.content.value[0]; + } catch (ex) { } - // To work around ForgeJS PKCS#7 limitation, this may break PKCS7 verify if ForjeJS adds support for it in the future - // Switch content type from "1.3.6.1.4.1.311.2.1.4" to "1.2.840.113549.1.7.1" - pkcs7der.value[1].value[0].value[2].value[0].value = forge.asn1.oidToDer(forge.pki.oids.data).data; + if ((pkcs7 == null) || (pkcs7content == null)) { + // Can't decode the signature + obj.header.sigpos = 0; + obj.header.siglen = 0; + obj.header.signed = false; + } else { + // Verify a PKCS#7 signature + // Verify is not currently supported in node-forge, but if implemented in the future, this code could work. + //var caStore = forge.pki.createCaStore(); + //for (var i in obj.certificates) { caStore.addCertificate(obj.certificates[i]); } + // Return is true if all signatures are valid and chain up to a provided CA + //if (!pkcs7.verify(caStore)) { throw ('Executable file has an invalid signature.'); } - // Decode the PKCS7 message - var pkcs7 = p7.messageFromAsn1(pkcs7der); - var pkcs7content = pkcs7.rawCapture.content.value[0]; - - // Verify a PKCS#7 signature - // Verify is not currently supported in node-forge, but if implemented in the future, this code could work. - //var caStore = forge.pki.createCaStore(); - //for (var i in obj.certificates) { caStore.addCertificate(obj.certificates[i]); } - // Return is true if all signatures are valid and chain up to a provided CA - //if (!pkcs7.verify(caStore)) { throw ('Executable file has an invalid signature.'); } - - // Get the signing attributes - obj.signingAttribs = []; - try { - for (var i in pkcs7.rawCapture.authenticatedAttributes) { - if ( - (pkcs7.rawCapture.authenticatedAttributes[i].value != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[0] != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[0].value != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1] != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0] != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value != null) && - (forge.asn1.derToOid(pkcs7.rawCapture.authenticatedAttributes[i].value[0].value) == obj.Oids.SPC_SP_OPUS_INFO_OBJID)) { - for (var j in pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value) { + // Get the signing attributes + obj.signingAttribs = []; + try { + for (var i in pkcs7.rawCapture.authenticatedAttributes) { if ( - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j] != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value[0] != null) && - (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value[0].value != null) - ) { - var v = pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value[0].value; - if (v.startsWith('http://') || v.startsWith('https://') || ((v.length % 2) == 1)) { obj.signingAttribs.push(v); } else { - var r = ""; // This string value is in UCS2 format, convert it to a normal string. - for (var k = 0; k < v.length; k += 2) { r += String.fromCharCode((v.charCodeAt(k + 8) << 8) + v.charCodeAt(k + 1)); } - obj.signingAttribs.push(r); + (pkcs7.rawCapture.authenticatedAttributes[i].value != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[0] != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[0].value != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1] != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0] != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value != null) && + (forge.asn1.derToOid(pkcs7.rawCapture.authenticatedAttributes[i].value[0].value) == obj.Oids.SPC_SP_OPUS_INFO_OBJID)) { + for (var j in pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value) { + if ( + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j] != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value[0] != null) && + (pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value[0].value != null) + ) { + var v = pkcs7.rawCapture.authenticatedAttributes[i].value[1].value[0].value[j].value[0].value; + if (v.startsWith('http://') || v.startsWith('https://') || ((v.length % 2) == 1)) { obj.signingAttribs.push(v); } else { + var r = ''; // This string value is in UCS2 format, convert it to a normal string. + for (var k = 0; k < v.length; k += 2) { r += String.fromCharCode((v.charCodeAt(k + 8) << 8) + v.charCodeAt(k + 1)); } + obj.signingAttribs.push(r); + } + } } } } + } catch (ex) { } + + // Set the certificate chain + obj.certificates = pkcs7.certificates; + + // Set the signature + obj.signature = Buffer.from(pkcs7.rawCapture.signature, 'binary'); + + // Get the file hashing algorithm + var hashAlgoOid = forge.asn1.derToOid(pkcs7content.value[1].value[0].value[0].value); + switch (hashAlgoOid) { + case forge.pki.oids.sha256: { obj.fileHashAlgo = 'sha256'; break; } + case forge.pki.oids.sha384: { obj.fileHashAlgo = 'sha384'; break; } + case forge.pki.oids.sha512: { obj.fileHashAlgo = 'sha512'; break; } + case forge.pki.oids.sha224: { obj.fileHashAlgo = 'sha224'; break; } + case forge.pki.oids.md5: { obj.fileHashAlgo = 'md5'; break; } } + + // Get the signed file hash + obj.fileHashSigned = Buffer.from(pkcs7content.value[1].value[1].value, 'binary') + + // Compute the actual file hash + if (obj.fileHashAlgo != null) { obj.fileHashActual = obj.getHash(obj.fileHashAlgo); } } - } catch (ex) { } - - // Set the certificate chain - obj.certificates = pkcs7.certificates; - - // Get the file hashing algorithm - var hashAlgoOid = forge.asn1.derToOid(pkcs7content.value[1].value[0].value[0].value); - switch (hashAlgoOid) { - case forge.pki.oids.sha256: { obj.fileHashAlgo = 'sha256'; break; } - case forge.pki.oids.sha384: { obj.fileHashAlgo = 'sha384'; break; } - case forge.pki.oids.sha512: { obj.fileHashAlgo = 'sha512'; break; } - case forge.pki.oids.sha224: { obj.fileHashAlgo = 'sha224'; break; } - case forge.pki.oids.md5: { obj.fileHashAlgo = 'md5'; break; } } - - // Get the signed file hash - obj.fileHashSigned = Buffer.from(pkcs7content.value[1].value[1].value, 'binary') - - // Compute the actual file hash - if (obj.fileHashAlgo != null) { obj.fileHashActual = obj.getHash(obj.fileHashAlgo); } } return true; } + // Make a timestamp signature request + obj.timeStampRequest = function (args, func) { + // Create the timestamp request in DER format + const asn1 = forge.asn1; + const pkcs7dataOid = asn1.oidToDer('1.2.840.113549.1.7.1').data; + const microsoftCodeSigningOid = asn1.oidToDer('1.3.6.1.4.1.311.3.2.1').data; + const asn1obj = + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, microsoftCodeSigningOid), + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, pkcs7dataOid), + asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.signature.toString('binary')) // Signature here + ]) + ]) + ]); + + // Serialize an ASN.1 object to DER format in Base64 + const requestBody = Buffer.from(asn1.toDer(asn1obj).data, 'binary').toString('base64'); + + // Make an HTTP request + const options = { url: args.time, proxy: args.proxy }; + + // Make a request to the time server + httpRequest(options, requestBody, function (err, data) { + if (err != null) { func(err); return; } + + // Decode the timestamp signature block + var timepkcs7der = null; + try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func("Unable to parse time-stamp response: " + ex); return; } + + // Decode the executable signature block + var pkcs7der = null; + try { + var pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(obj.getRawSignatureBlock(), 'base64').toString('binary'))); + + // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable + // TODO: We could look to see if the certificate is already present in the executable + const timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value; + for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); } + + // Remove any existing time stamp signatures + var newValues = []; + for (var i in pkcs7der.value[1].value[0].value[4].value[0].value) { + const j = pkcs7der.value[1].value[0].value[4].value[0].value[i]; + if ((j.tagClass != 128) || (j.type != 1)) { newValues.push(j); } // If this is not a time stamp, add it to out new list. + } + pkcs7der.value[1].value[0].value[4].value[0].value = newValues; // Set the new list + + // Get the time signature and add it to the executables PKCS7 + const timeasn1Signature = timepkcs7der.value[1].value[0].value[4]; + const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data; + const asn1obj2 = + asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid), + timeasn1Signature + ]) + ]); + pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2); + + // Re-encode the executable signature block + const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary'); + + // Open the output file + var output = null; + try { output = fs.openSync(args.out, 'w+'); } catch (ex) { } + if (output == null) return false; + var tmp, written = 0; + var executableSize = obj.header.sigpos ? obj.header.sigpos : this.filesize; + + // Compute pre-header length and copy that to the new file + var preHeaderLen = (obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); + var tmp = readFileSlice(written, preHeaderLen); + fs.writeSync(output, tmp); + written += tmp.length; + + // Quad Align the results, adding padding if necessary + var len = executableSize + p7signature.length; + var padding = (8 - ((len) % 8)) % 8; + + // Write the signature header + var addresstable = Buffer.alloc(8); + addresstable.writeUInt32LE(executableSize); + addresstable.writeUInt32LE(8 + p7signature.length + padding, 4); + fs.writeSync(output, addresstable); + written += addresstable.length; + + // Copy the rest of the file until the start of the signature block + while ((executableSize - written) > 0) { + tmp = readFileSlice(written, Math.min(executableSize - written, 65536)); + fs.writeSync(output, tmp); + written += tmp.length; + } + + // Write the signature block header and signature + var win = Buffer.alloc(8); // WIN CERTIFICATE Structure + win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length + win.writeUInt16LE(512, 4); // WORD revision + win.writeUInt16LE(2, 6); // WORD type + fs.writeSync(output, win); + fs.writeSync(output, p7signature); + if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); } + written += (p7signature.length + padding + 8); + + // Compute the checksum and write it in the PE header checksum location + var tmp = Buffer.alloc(4); + tmp.writeUInt32LE(runChecksumOnFile(output, written, ((obj.header.peOptionalHeaderLocation + 64) / 4))); + fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64); + + // Close the file + fs.closeSync(output); + + // Indicate we are done + func(null); + } catch (ex) { func('' + ex); return; } + }); + } + // Read a resource table. // ptr: The pointer to the start of the resource section // offset: The offset start of the resource table to read @@ -568,6 +711,15 @@ function createAuthenticodeHandler(path) { 'configurationFiles': 24 } + // Return the raw signature block buffer with padding removed + obj.getRawSignatureBlock = function () { + if ((obj.header.sigpos == 0) || (obj.header.siglen == 0)) return null; + var pkcs7raw = readFileSlice(obj.header.sigpos + 8, obj.header.siglen - 8); + var derlen = forge.asn1.getBerValueLength(forge.util.createBuffer(pkcs7raw.slice(1, 5))) + 4; + if (derlen != pkcs7raw.length) { pkcs7raw = pkcs7raw.slice(0, derlen); } + return pkcs7raw; + } + // Get icon information from resource obj.getIconInfo = function () { const r = {}, ptr = obj.header.sections['.rsrc'].rawAddr; @@ -945,8 +1097,9 @@ function createAuthenticodeHandler(path) { //function padPointer(ptr) { return ptr + (ptr % 4); } // Hash the file using the selected hashing system + // This hash skips the executables CRC and code signing data and signing block obj.getHash = function(algo) { - var hash = crypto.createHash(algo); + const hash = crypto.createHash(algo); runHash(hash, 0, obj.header.peHeaderLocation + 88); runHash(hash, obj.header.peHeaderLocation + 88 + 4, obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); runHash(hash, obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16) + 8, obj.header.sigpos > 0 ? obj.header.sigpos : obj.filesize); @@ -954,14 +1107,41 @@ function createAuthenticodeHandler(path) { } // Hash of an open file using the selected hashing system - obj.getHashOfFile = function (fd, algo, filesize) { - var hash = crypto.createHash(algo); + // This hash skips the executables CRC and code signing data and signing block + obj.getHashOfFile = function(fd, algo, filesize) { + const hash = crypto.createHash(algo); runHashOnFile(fd, hash, 0, obj.header.peHeaderLocation + 88); runHashOnFile(fd, hash, obj.header.peHeaderLocation + 88 + 4, obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); runHashOnFile(fd, hash, obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16) + 8, obj.header.sigpos > 0 ? obj.header.sigpos : filesize); return hash.digest(); } + // Hash the file using the selected hashing system skipping resource section + // This hash skips the executables CRC, sections table, resource section, code signing data and signing block + obj.getHashNoResources = function (algo) { + if (obj.header.sections['.rsrc'] == null) { return obj.getHash(algo); } // No resources in this executable, return a normal hash + + // Get the sections table start and size + const sectionHeaderPtr = obj.header.SectionHeadersPtr; + const sectionHeaderSize = obj.header.coff.numberOfSections * 40; + + // Get the resource section start and size + const resPtr = obj.header.sections['.rsrc'].rawAddr; + const resSize = obj.header.sections['.rsrc'].rawSize; + + // Get the end-of-file location + const eof = obj.header.sigpos > 0 ? obj.header.sigpos : obj.filesize; + + // Hash the remaining data + const hash = crypto.createHash(algo); + runHash(hash, 0, obj.header.peHeaderLocation + 88); + runHash(hash, obj.header.peHeaderLocation + 88 + 4, obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); + runHash(hash, obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16) + 8, sectionHeaderPtr); + runHash(hash, sectionHeaderPtr + sectionHeaderSize, resPtr); + runHash(hash, resPtr + resSize, eof); + return hash.digest(); + } + // Hash the file from start to end loading 64k chunks function runHash(hash, start, end) { var ptr = start; @@ -971,8 +1151,8 @@ function createAuthenticodeHandler(path) { // Hash the open file loading 64k chunks // TODO: Do chunks on this!!! function runHashOnFile(fd, hash, start, end) { - var buf = Buffer.alloc(end - start); - var len = fs.readSync(fd, buf, 0, buf.length, start); + const buf = Buffer.alloc(end - start); + const len = fs.readSync(fd, buf, 0, buf.length, start); if (len != buf.length) { console.log('BAD runHashOnFile'); } hash.update(buf); } @@ -1044,7 +1224,7 @@ function createAuthenticodeHandler(path) { } // Sign the file using the certificate and key. If none is specified, generate a dummy one - obj.sign = function (cert, args) { + obj.sign = function (cert, args, func) { if (cert == null) { cert = createSelfSignedCert({ cn: 'Test' }); } // Set the hash algorithm hash OID @@ -1055,16 +1235,16 @@ function createAuthenticodeHandler(path) { if (args.hash == 'sha512') { hashOid = forge.pki.oids.sha512; fileHash = obj.getHash('sha512'); } if (args.hash == 'sha224') { hashOid = forge.pki.oids.sha224; fileHash = obj.getHash('sha224'); } if (args.hash == 'md5') { hashOid = forge.pki.oids.md5; fileHash = obj.getHash('md5'); } - if (hashOid == null) return false; + if (hashOid == null) { func(false); return; }; // Create the signature block - var p7 = forge.pkcs7.createSignedData(); + var xp7 = forge.pkcs7.createSignedData(); var content = { 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 6, 'constructed': false, 'composed': false, 'value': forge.asn1.oidToDer('1.3.6.1.4.1.311.2.1.15').data }, { 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 3, 'constructed': false, 'composed': false, 'value': '\u0000', 'bitStringContents': '\u0000', 'original': { 'tagClass': 0, 'type': 3, 'constructed': false, 'composed': false, 'value': '\u0000' } }, { 'tagClass': 128, 'type': 0, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 128, 'type': 2, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 128, 'type': 0, 'constructed': false, 'composed': false, 'value': '' }] }] }] }] }, { 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 6, 'constructed': false, 'composed': false, 'value': forge.asn1.oidToDer(hashOid).data }, { 'tagClass': 0, 'type': 5, 'constructed': false, 'composed': false, 'value': '' }] }, { 'tagClass': 0, 'type': 4, 'constructed': false, 'composed': false, 'value': fileHash.toString('binary') }] }] }; - p7.contentInfo = forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.SEQUENCE, true, [forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.OID, false, forge.asn1.oidToDer('1.3.6.1.4.1.311.2.1.4').getBytes())]); - p7.contentInfo.value.push(forge.asn1.create(forge.asn1.Class.CONTEXT_SPECIFIC, 0, true, [content])); - p7.content = {}; // We set .contentInfo and have .content empty to bypass node-forge limitation on the type of content it can sign. - p7.addCertificate(cert.cert); - if (cert.extraCerts) { for (var i = 0; i < cert.extraCerts.length; i++) { p7.addCertificate(cert.extraCerts[0]); } } // Add any extra certificates that form the cert chain + xp7.contentInfo = forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.SEQUENCE, true, [forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.OID, false, forge.asn1.oidToDer('1.3.6.1.4.1.311.2.1.4').getBytes())]); + xp7.contentInfo.value.push(forge.asn1.create(forge.asn1.Class.CONTEXT_SPECIFIC, 0, true, [content])); + xp7.content = {}; // We set .contentInfo and have .content empty to bypass node-forge limitation on the type of content it can sign. + xp7.addCertificate(cert.cert); + if (cert.extraCerts) { for (var i = 0; i < cert.extraCerts.length; i++) { xp7.addCertificate(cert.extraCerts[0]); } } // Add any extra certificates that form the cert chain // Build authenticated attributes var authenticatedAttributes = [ @@ -1083,22 +1263,198 @@ function createAuthenticodeHandler(path) { } // Add the signer and sign - p7.addSigner({ + xp7.addSigner({ key: cert.key, certificate: cert.cert, digestAlgorithm: forge.pki.oids.sha384, authenticatedAttributes: authenticatedAttributes }); - p7.sign(); - var p7signature = Buffer.from(forge.pkcs7.messageToPem(p7).split('-----BEGIN PKCS7-----')[1].split('-----END PKCS7-----')[0], 'base64'); - //console.log('Signature', Buffer.from(p7signature, 'binary').toString('base64')); + xp7.sign(); + var p7signature = Buffer.from(forge.pkcs7.messageToPem(xp7).split('-----BEGIN PKCS7-----')[1].split('-----END PKCS7-----')[0], 'base64'); + if (args.time == null) { + // Sign the executable without timestamp + signEx(args, p7signature, obj.filesize, func); + } else { + // Decode the signature block + var pkcs7der = null; + try { pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(p7signature)); } catch (ex) { func('' + ex); return; } + + // To work around ForgeJS PKCS#7 limitation, this may break PKCS7 verify if ForgeJS adds support for it in the future + // Switch content type from "1.3.6.1.4.1.311.2.1.4" to "1.2.840.113549.1.7.1" + pkcs7der.value[1].value[0].value[2].value[0].value = forge.asn1.oidToDer(forge.pki.oids.data).data; + + // Decode the PKCS7 message + var pkcs7 = p7.messageFromAsn1(pkcs7der); + + // Create the timestamp request in DER format + const asn1 = forge.asn1; + const pkcs7dataOid = asn1.oidToDer('1.2.840.113549.1.7.1').data; + const microsoftCodeSigningOid = asn1.oidToDer('1.3.6.1.4.1.311.3.2.1').data; + const asn1obj = + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, microsoftCodeSigningOid), + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, pkcs7dataOid), + asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, pkcs7.rawCapture.signature.toString('binary')) // Signature here + ]) + ]) + ]); + + // Re-decode the PKCS7 from the executable, this time, no workaround needed + try { pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(p7signature)); } catch (ex) { func('' + ex); return; } + + // Serialize an ASN.1 object to DER format in Base64 + const requestBody = Buffer.from(asn1.toDer(asn1obj).data, 'binary').toString('base64'); + + // Make an HTTP request + const options = { url: args.time, proxy: args.proxy }; + + // Make a request to the time server + httpRequest(options, requestBody, function (err, data) { + if (err != null) { func(err); return; } + + // Decode the timestamp signature block + var timepkcs7der = null; + try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func("Unable to parse time-stamp response: " + ex); return; } + + try { + // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable + // TODO: We could look to see if the certificate is already present in the executable + const timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value; + for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); } + + // Get the time signature and add it to the executables PKCS7 + const timeasn1Signature = timepkcs7der.value[1].value[0].value[4]; + const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data; + const asn1obj2 = + asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid), + timeasn1Signature + ]) + ]); + pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2); + + // Re-encode the executable signature block + const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary'); + + // Write the file with the signature block + signEx(args, p7signature, obj.filesize, func); + } catch (ex) { func('' + ex); } + }); + } + } + + // Make a HTTP request, use a proxy if needed + function httpRequest(options, requestBody, func) { + // Decode the URL + const timeServerUrl = new URL(options.url); + options.protocol = timeServerUrl.protocol; + options.hostname = timeServerUrl.hostname; + options.path = timeServerUrl.pathname; + options.port = ((timeServerUrl.port == '') ? 80 : parseInt(timeServerUrl.port)); + + if (options.proxy == null) { + // No proxy needed + + // Setup the options + delete options.url; + options.method = 'POST'; + options.headers = { + 'accept': 'application/octet-stream', + 'cache-control': 'no-cache', + 'user-agent': 'Transport', + 'content-type': 'application/octet-stream', + 'content-length': Buffer.byteLength(requestBody) + }; + + // Set up the request + var responseAccumulator = ''; + var req = require('http').request(options, function (res) { + res.setEncoding('utf8'); + res.on('data', function (chunk) { responseAccumulator += chunk; }); + res.on('end', function () { func(null, responseAccumulator); }); + }); + + // Post the data + req.on('error', function (err) { func('' + err); }); + req.write(requestBody); + req.end(); + } else { + // We are using a proxy + // This is a fairly basic proxy implementation, should work most of the time. + + // Setup the options and decode the proxy URL + var proxyOptions = { method: 'CONNECT' }; + if (options.proxy) { + const proxyUrl = new URL(options.proxy); + proxyOptions.protocol = proxyUrl.protocol; + proxyOptions.hostname = proxyUrl.hostname; + proxyOptions.path = options.hostname + ':' + options.port; + proxyOptions.port = ((proxyUrl.port == '') ? 80 : parseInt(proxyUrl.port)); + } + + // Set up the proxy request + var responseAccumulator = ''; + var req = require('http').request(proxyOptions); + req.on('error', function (err) { func('' + err); }); + req.on('connect', function (res, socket, head) { + // Make a request over the HTTP tunnel + socket.write('POST ' + options.path + ' HTTP/1.1\r\n' + + 'host: ' + options.hostname + ':' + options.port + '\r\n' + + 'accept: application/octet-stream\r\n' + + 'cache-control: no-cache\r\n' + + 'user-agent: Transport\r\n' + + 'content-type: application/octet-stream\r\n' + + 'content-length: ' + Buffer.byteLength(requestBody) + '\r\n' + + '\r\n' + requestBody); + socket.on('data', function (chunk) { + responseAccumulator += chunk.toString(); + var responseData = parseHttpResponse(responseAccumulator); + if (responseData != null) { try { socket.end(); } catch (ex) { console.log('ex', ex); } socket.xdone = true; func(null, responseData); } + }); + socket.on('end', function () { + if (socket.xdone == true) return; + var responseData = parseHttpResponse(responseAccumulator); + if (responseData != null) { func(null, responseData); } else { func("Unable to parse response."); } + }); + }); + req.end(); + } + } + + // Parse the HTTP response and return data if available + function parseHttpResponse(data) { + var dataSplit = data.split('\r\n\r\n'); + if (dataSplit.length < 2) return null; + + // Parse the HTTP header + var headerSplit = dataSplit[0].split('\r\n'), headers = {}; + for (var i in headerSplit) { + if (i != 0) { + var x = headerSplit[i].indexOf(':'); + headers[headerSplit[i].substring(0, x).toLowerCase()] = headerSplit[i].substring(x + 2); + } + } + + // If there is a content-length in the header, keep accumulating data until we have the right length + if (headers['content-length'] != null) { + const contentLength = parseInt(headers['content-length']); + if (dataSplit[1].length < contentLength) return null; // Wait for more data + return dataSplit[1]; + } + return dataSplit[1]; + } + + // Complete the signature of an executable + function signEx(args, p7signature, filesize, func) { // Open the output file var output = null; try { output = fs.openSync(args.out, 'w+'); } catch (ex) { } - if (output == null) return false; - var tmp, written = 0; - var executableSize = obj.header.sigpos ? obj.header.sigpos : this.filesize; + if (output == null) { func(false); return; } + var tmp, written = 0, executableSize = obj.header.sigpos ? obj.header.sigpos : filesize; // Compute pre-header length and copy that to the new file var preHeaderLen = (obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); @@ -1141,7 +1497,7 @@ function createAuthenticodeHandler(path) { // Close the file fs.closeSync(output); - return true; + func(null); } // Save an executable without the signature @@ -1176,7 +1532,7 @@ function createAuthenticodeHandler(path) { } // Save the executable - obj.writeExecutable = function (args, cert) { + obj.writeExecutable = function (args, cert, func) { // Open the file var output = fs.openSync(args.out, 'w+'); var tmp, written = 0; @@ -1232,13 +1588,13 @@ function createAuthenticodeHandler(path) { } // Write the entire header to the destination file - //console.log('Write header', fullHeader.length); + //console.log('Write header', fullHeader.length, written); fs.writeSync(output, fullHeader); written += fullHeader.length; // Write the entire executable until the start to the resource segment var totalWrite = resPtr; - //console.log('Write until res', totalWrite); + //console.log('Write until res', totalWrite, written); while ((totalWrite - written) > 0) { tmp = readFileSlice(written, Math.min(totalWrite - written, 65536)); fs.writeSync(output, tmp); @@ -1249,15 +1605,24 @@ function createAuthenticodeHandler(path) { var rsrcSection = generateResourceSection(obj.resources); fs.writeSync(output, rsrcSection); written += rsrcSection.length; + //console.log('Write res', rsrcSection.length, written); // Write until the signature block - totalWrite = obj.header.sigpos + resDeltaSize; - //console.log('Write until signature', totalWrite); + if (obj.header.sigpos > 0) { + // Since the original file was signed, write from the end of the resources to the start of the signature block. + totalWrite = obj.header.sigpos + resDeltaSize; + } else { + // The original file was not signed, write from the end of the resources to the end of the file. + totalWrite = obj.filesize + resDeltaSize; + } + + //console.log('Write until signature', totalWrite, written); while ((totalWrite - written) > 0) { tmp = readFileSlice(written - resDeltaSize, Math.min(totalWrite - written, 65536)); fs.writeSync(output, tmp); written += tmp.length; } + //console.log('Write to signature', written); // Write the signature if needed if (cert != null) { @@ -1271,16 +1636,16 @@ function createAuthenticodeHandler(path) { if (args.hash == 'sha512') { hashOid = forge.pki.oids.sha512; fileHash = obj.getHashOfFile(output, 'sha512', written); } if (args.hash == 'sha224') { hashOid = forge.pki.oids.sha224; fileHash = obj.getHashOfFile(output, 'sha224', written); } if (args.hash == 'md5') { hashOid = forge.pki.oids.md5; fileHash = obj.getHashOfFile(output, 'md5', written); } - if (hashOid == null) return false; + if (hashOid == null) { func('Bad hash method OID'); return; } // Create the signature block - var p7 = forge.pkcs7.createSignedData(); + var xp7 = forge.pkcs7.createSignedData(); var content = { 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 6, 'constructed': false, 'composed': false, 'value': forge.asn1.oidToDer('1.3.6.1.4.1.311.2.1.15').data }, { 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 3, 'constructed': false, 'composed': false, 'value': '\u0000', 'bitStringContents': '\u0000', 'original': { 'tagClass': 0, 'type': 3, 'constructed': false, 'composed': false, 'value': '\u0000' } }, { 'tagClass': 128, 'type': 0, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 128, 'type': 2, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 128, 'type': 0, 'constructed': false, 'composed': false, 'value': '' }] }] }] }] }, { 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 16, 'constructed': true, 'composed': true, 'value': [{ 'tagClass': 0, 'type': 6, 'constructed': false, 'composed': false, 'value': forge.asn1.oidToDer(hashOid).data }, { 'tagClass': 0, 'type': 5, 'constructed': false, 'composed': false, 'value': '' }] }, { 'tagClass': 0, 'type': 4, 'constructed': false, 'composed': false, 'value': fileHash.toString('binary') }] }] }; - p7.contentInfo = forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.SEQUENCE, true, [forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.OID, false, forge.asn1.oidToDer('1.3.6.1.4.1.311.2.1.4').getBytes())]); - p7.contentInfo.value.push(forge.asn1.create(forge.asn1.Class.CONTEXT_SPECIFIC, 0, true, [content])); - p7.content = {}; // We set .contentInfo and have .content empty to bypass node-forge limitation on the type of content it can sign. - p7.addCertificate(cert.cert); - if (cert.extraCerts) { for (var i = 0; i < cert.extraCerts.length; i++) { p7.addCertificate(cert.extraCerts[0]); } } // Add any extra certificates that form the cert chain + xp7.contentInfo = forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.SEQUENCE, true, [forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.OID, false, forge.asn1.oidToDer('1.3.6.1.4.1.311.2.1.4').getBytes())]); + xp7.contentInfo.value.push(forge.asn1.create(forge.asn1.Class.CONTEXT_SPECIFIC, 0, true, [content])); + xp7.content = {}; // We set .contentInfo and have .content empty to bypass node-forge limitation on the type of content it can sign. + xp7.addCertificate(cert.cert); + if (cert.extraCerts) { for (var i = 0; i < cert.extraCerts.length; i++) { xp7.addCertificate(cert.extraCerts[0]); } } // Add any extra certificates that form the cert chain // Build authenticated attributes var authenticatedAttributes = [ @@ -1299,45 +1664,131 @@ function createAuthenticodeHandler(path) { } // Add the signer and sign - p7.addSigner({ + xp7.addSigner({ key: cert.key, certificate: cert.cert, digestAlgorithm: forge.pki.oids.sha384, authenticatedAttributes: authenticatedAttributes }); - p7.sign(); - var p7signature = Buffer.from(forge.pkcs7.messageToPem(p7).split('-----BEGIN PKCS7-----')[1].split('-----END PKCS7-----')[0], 'base64'); + xp7.sign(); + var p7signature = Buffer.from(forge.pkcs7.messageToPem(xp7).split('-----BEGIN PKCS7-----')[1].split('-----END PKCS7-----')[0], 'base64'); //console.log('Signature', Buffer.from(p7signature, 'binary').toString('base64')); - // Quad Align the results, adding padding if necessary - var len = written + p7signature.length; - var padding = (8 - ((len) % 8)) % 8; + if (args.time == null) { + // Write the signature block to the output executable without time stamp + writeExecutableEx(output, p7signature, written, func); + } else { + // Decode the signature block + var pkcs7der = null; + try { pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(p7signature)); } catch (ex) { func('' + ex); return; } - // Write the signature block header and signature - var win = Buffer.alloc(8); // WIN CERTIFICATE Structure - win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length - win.writeUInt16LE(512, 4); // WORD revision - win.writeUInt16LE(2, 6); // WORD type - fs.writeSync(output, win); - fs.writeSync(output, p7signature); - if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); } + // To work around ForgeJS PKCS#7 limitation, this may break PKCS7 verify if ForgeJS adds support for it in the future + // Switch content type from "1.3.6.1.4.1.311.2.1.4" to "1.2.840.113549.1.7.1" + pkcs7der.value[1].value[0].value[2].value[0].value = forge.asn1.oidToDer(forge.pki.oids.data).data; - // Write the signature header - var addresstable = Buffer.alloc(8); - addresstable.writeUInt32LE(written); - addresstable.writeUInt32LE(8 + p7signature.length + padding, 4); - var signatureHeaderLocation = (obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); - fs.writeSync(output, addresstable, 0, 8, signatureHeaderLocation); - written += (p7signature.length + padding + 8); // Add the signature block to written counter + // Decode the PKCS7 message + var pkcs7 = p7.messageFromAsn1(pkcs7der); - // Compute the checksum and write it in the PE header checksum location - var tmp = Buffer.alloc(4); - tmp.writeUInt32LE(runChecksumOnFile(output, written, ((obj.header.peOptionalHeaderLocation + 64) / 4))); - fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64); + // Create the timestamp request in DER format + const asn1 = forge.asn1; + const pkcs7dataOid = asn1.oidToDer('1.2.840.113549.1.7.1').data; + const microsoftCodeSigningOid = asn1.oidToDer('1.3.6.1.4.1.311.3.2.1').data; + const asn1obj = + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, microsoftCodeSigningOid), + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, pkcs7dataOid), + asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, pkcs7.rawCapture.signature.toString('binary')) // Signature here + ]) + ]) + ]); + + // Re-decode the PKCS7 from the executable, this time, no workaround needed + try { pkcs7der = forge.asn1.fromDer(forge.util.createBuffer(p7signature)); } catch (ex) { func('' + ex); return; } + + // Serialize an ASN.1 object to DER format in Base64 + const requestBody = Buffer.from(asn1.toDer(asn1obj).data, 'binary').toString('base64'); + + // Make an HTTP request + const options = { url: args.time, proxy: args.proxy }; + + // Make a request to the time server + httpRequest(options, requestBody, function (err, data) { + if (err != null) { func(err); return; } + + // Decode the timestamp signature block + var timepkcs7der = null; + try { timepkcs7der = forge.asn1.fromDer(forge.util.createBuffer(Buffer.from(data, 'base64').toString('binary'))); } catch (ex) { func("Unable to parse time-stamp response: " + ex); return; } + + // Get the ASN1 certificates used to sign the timestamp and add them to the certs in the PKCS7 of the executable + // TODO: We could look to see if the certificate is already present in the executable + try { + var timeasn1Certs = timepkcs7der.value[1].value[0].value[3].value; + for (var i in timeasn1Certs) { pkcs7der.value[1].value[0].value[3].value.push(timeasn1Certs[i]); } + + // Get the time signature and add it to the executables PKCS7 + const timeasn1Signature = timepkcs7der.value[1].value[0].value[4]; + const countersignatureOid = asn1.oidToDer('1.2.840.113549.1.9.6').data; + const asn1obj2 = + asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ + asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, countersignatureOid), + timeasn1Signature + ]) + ]); + pkcs7der.value[1].value[0].value[4].value[0].value.push(asn1obj2); + + // Re-encode the executable signature block + const p7signature = Buffer.from(forge.asn1.toDer(pkcs7der).data, 'binary'); + + // Write the file with the signature block + writeExecutableEx(output, p7signature, written, func); + } catch (ex) { func('' + ex); return; } // Something failed + }); + } + return; } // Close the file fs.closeSync(output); + + // Indicate success + func(null); + } + + function writeExecutableEx(output, p7signature, written, func) { + // Quad Align the results, adding padding if necessary + var len = written + p7signature.length; + var padding = (8 - ((len) % 8)) % 8; + + // Write the signature block header and signature + var win = Buffer.alloc(8); // WIN CERTIFICATE Structure + win.writeUInt32LE(p7signature.length + padding + 8); // DWORD length + win.writeUInt16LE(512, 4); // WORD revision + win.writeUInt16LE(2, 6); // WORD type + fs.writeSync(output, win); + fs.writeSync(output, p7signature); + if (padding > 0) { fs.writeSync(output, Buffer.alloc(padding, 0)); } + + // Write the signature header + var addresstable = Buffer.alloc(8); + addresstable.writeUInt32LE(written); + addresstable.writeUInt32LE(8 + p7signature.length + padding, 4); + var signatureHeaderLocation = (obj.header.peHeaderLocation + 152 + (obj.header.pe32plus * 16)); + fs.writeSync(output, addresstable, 0, 8, signatureHeaderLocation); + written += (p7signature.length + padding + 8); // Add the signature block to written counter + + // Compute the checksum and write it in the PE header checksum location + var tmp = Buffer.alloc(4); + tmp.writeUInt32LE(runChecksumOnFile(output, written, ((obj.header.peOptionalHeaderLocation + 64) / 4))); + fs.writeSync(output, tmp, 0, 4, obj.header.peOptionalHeaderLocation + 64); + + // Close the file + fs.closeSync(output); + + // Indicate success + func(null); } // Return null if we could not open the file @@ -1364,6 +1815,8 @@ function start() { console.log(" --desc [description] Description string to embbed into signature."); console.log(" --url [url] URL to embbed into signature."); console.log(" --hash [method] Default is SHA384, possible value: MD5, SHA224, SHA256, SHA384 or SHA512."); + console.log(" --time [url] The time signing server URL."); + console.log(" --proxy [url] The HTTP proxy to use to contact the time signing server, must start with http://"); console.log(" unsign: Remove the signature from the executable."); console.log(" --exe [file] Required executable to un-sign."); console.log(" --out [file] Resulting executable with signature removed."); @@ -1376,6 +1829,11 @@ function start() { console.log(" --org [value] Certificate organization name."); console.log(" --ou [value] Certificate organization unit name."); console.log(" --serial [value] Certificate serial number."); + console.log(" timestamp: Add a signed timestamp to an already signed executable."); + console.log(" --exe [file] Required executable to sign."); + console.log(" --out [file] Resulting signed executable."); + console.log(" --time [url] The time signing server URL."); + console.log(" --proxy [url] The HTTP proxy to use to contact the time signing server, must start with http://"); console.log(""); console.log("Note that certificate PEM files must first have the signing certificate,"); console.log("followed by all certificates that form the trust chain."); @@ -1393,9 +1851,9 @@ function start() { } // Check that a valid command is passed in - if (['info', 'sign', 'unsign', 'createcert', 'icons', 'saveicon', 'header', 'test'].indexOf(process.argv[2].toLowerCase()) == -1) { + if (['info', 'sign', 'unsign', 'createcert', 'icons', 'saveicon', 'header', 'timestamp', 'signblock'].indexOf(process.argv[2].toLowerCase()) == -1) { console.log("Invalid command: " + process.argv[2]); - console.log("Valid commands are: info, sign, unsign, createcert"); + console.log("Valid commands are: info, sign, unsign, createcert, timestamp"); return; } @@ -1410,13 +1868,16 @@ function start() { } // Parse the resources and make any required changes - var resChanges = false, versionStrings = exe.getVersionInfo(); - var versionProperties = ['FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright', 'OriginalFilename', 'ProductName', 'ProductVersion']; - for (var i in versionProperties) { - const prop = versionProperties[i], propl = prop.toLowerCase(); - if (args[propl] && (args[propl] != versionStrings[prop])) { versionStrings[prop] = args[propl]; resChanges = true; } + var resChanges = false, versionStrings = null; + if (exe != null) { + versionStrings = exe.getVersionInfo(); + var versionProperties = ['FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright', 'OriginalFilename', 'ProductName', 'ProductVersion']; + for (var i in versionProperties) { + const prop = versionProperties[i], propl = prop.toLowerCase(); + if (args[propl] && (args[propl] != versionStrings[prop])) { versionStrings[prop] = args[propl]; resChanges = true; } + } + if (resChanges == true) { exe.setVersionInfo(versionStrings); } } - if (resChanges == true) { exe.setVersionInfo(versionStrings); } // Execute the command var command = process.argv[2].toLowerCase(); @@ -1463,12 +1924,19 @@ function start() { if (cert == null) { console.log("Unable to load certificate and/or private key, generating test certificate."); cert = createSelfSignedCert({ cn: 'Test' }); } if (resChanges == false) { console.log("Signing to " + args.out); - exe.sign(cert, args); // Simple signing, copy most of the original file. + exe.sign(cert, args, function (err) { // Simple signing, copy most of the original file. + if (err == null) { console.log("Done."); } else { console.log(err); } + if (exe != null) { exe.close(); } + }); + return; } else { console.log("Changing resources and signing to " + args.out); - exe.writeExecutable(args, cert); // Signing with resources decoded and re-encoded. + exe.writeExecutable(args, cert, function (err) { // Signing with resources decoded and re-encoded. + if (err == null) { console.log("Done."); } else { console.log(err); } + if (exe != null) { exe.close(); } + }); + return; } - console.log("Done."); } if (command == 'unsign') { // Unsign an executable if (typeof args.exe != 'string') { console.log("Missing --exe [filename]"); return; } @@ -1483,7 +1951,10 @@ function start() { } } else { console.log("Changing resources and unsigning to " + args.out); - exe.writeExecutable(args, null); // Unsigning with resources decoded and re-encoded. + exe.writeExecutable(args, null, function (err) { // Unsigning with resources decoded and re-encoded. + if (err == null) { console.log("Done."); } else { console.log(err); } + if (exe != null) { exe.close(); } + }); } } if (command == 'createcert') { // Create a code signing certificate and private key @@ -1511,6 +1982,7 @@ function start() { } } if (command == 'saveicon') { // Save an icon to file + if (exe == null) { console.log("Missing --exe [filename]"); return; } if (typeof args.out != 'string') { console.log("Missing --out [filename]"); return; } if (typeof args.icon != 'number') { console.log("Missing or incorrect --icon [number]"); return; } const iconInfo = exe.getIconInfo(); @@ -1534,6 +2006,23 @@ function start() { fs.writeFileSync(args.out, Buffer.concat([buf, icon.icon])); console.log("Done."); } + if (command == 'signblock') { // Display the raw signature block of the executable in hex + if (exe == null) { console.log("Missing --exe [filename]"); return; } + var buf = exe.getRawSignatureBlock(); + if (buf == null) { console.log("Executable is not signed."); return } else { console.log(buf.toString('hex')); return } + } + if (command == 'timestamp') { + if (exe == null) { console.log("Missing --exe [filename]"); return; } + if (exe.signature == null) { console.log("Executable is not signed."); return; } + if (typeof args.time != 'string') { console.log("Missing --time [url]"); return; } + createOutFile(args, args.exe); + console.log("Requesting time signature..."); + exe.timeStampRequest(args, function (err) { + if (err == null) { console.log("Done."); } else { console.log(err); } + if (exe != null) { exe.close(); } + }) + return; + } // Close the file if (exe != null) { exe.close(); } @@ -1545,3 +2034,4 @@ if (require.main === module) { start(); } // Exports module.exports.createAuthenticodeHandler = createAuthenticodeHandler; module.exports.loadCertificates = loadCertificates; + diff --git a/db.js b/db.js index b4939f5d..899d1e38 100644 --- a/db.js +++ b/db.js @@ -109,7 +109,13 @@ module.exports.CreateDB = function (parent, func) { obj.eventsfile.remove({ time: { '$lt': new Date(Date.now() - (expireEventsSeconds * 1000)) } }, { multi: true }); // Force delete older events obj.powerfile.remove({ time: { '$lt': new Date(Date.now() - (expirePowerEventsSeconds * 1000)) } }, { multi: true }); // Force delete older events obj.serverstatsfile.remove({ time: { '$lt': new Date(Date.now() - (expireServerStatsSeconds * 1000)) } }, { multi: true }); // Force delete older events + } else if ((obj.databaseType == 4) || (obj.databaseType == 5)) { // MariaDB or MySQL + sqlDbQuery('DELETE FROM events WHERE time < ?', [new Date(Date.now() - (expireEventsSeconds * 1000))], function (doc, err) { }); // Delete events older than expireEventsSeconds + sqlDbQuery('DELETE FROM power WHERE time < ?', [new Date(Date.now() - (expirePowerEventsSeconds * 1000))], function (doc, err) { }); // Delete events older than expirePowerSeconds + sqlDbQuery('DELETE FROM serverstats WHERE expire < ?', [new Date()], function (doc, err) { }); // Delete events where expiration date is in the past + sqlDbQuery('DELETE FROM smbios WHERE expire < ?', [new Date()], function (doc, err) { }); // Delete events where expiration date is in the past } + obj.removeInactiveDevices(); } @@ -1198,23 +1204,20 @@ module.exports.CreateDB = function (parent, func) { obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM main WHERE type = $1 AND domain = $2', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); }; obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) { if (id && (id != '')) { - sqlDbQuery('SELECT doc FROM main WHERE id = $1 AND type = $2 AND domain = $3 AND (extra = ANY ($4))', [id, type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); + sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra = ANY ($4))', [id, type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } else { if (extrasids == null) { - sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra = ANY ($3))', [type, domain, meshes], function (err, docs) { - if (err == null) { for (var i in docs) { delete docs[i].type } } - func(err, performTypedRecordDecrypt(docs)); - }, true); + sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra = ANY ($3))', [type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }, true); } else { - sqlDbQuery('SELECT doc FROM main WHERE type = $1 AND domain = $2 AND ((extra = ANY ($3)) OR (id = ANY ($4)))', [type, domain, meshes, extrasids], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); + sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra = ANY ($3)) OR (id = ANY ($4)))', [type, domain, meshes, extrasids], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } } }; obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) { if (id && (id != '')) { - sqlDbQuery('SELECT doc FROM main WHERE id = $1 AND type = $2 AND domain = $3 AND (extra = ANY ($4))', [id, type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); + sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra = ANY ($4))', [id, type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } else { - sqlDbQuery('SELECT doc FROM main WHERE type = $1 AND domain = $2 AND (extra = ANY ($3))', [type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); + sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra = ANY ($3))', [type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } }; obj.GetAllType = function (type, func) { sqlDbQuery('SELECT doc FROM main WHERE type = $1', [type], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); } @@ -1367,17 +1370,16 @@ module.exports.CreateDB = function (parent, func) { obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM main WHERE id = ?', [id], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); } obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); }; obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) { + if ((meshes == null) || (meshes.length == 0)) { meshes = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. + if ((extrasids == null) || (extrasids.length == 0)) { extrasids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. if (id && (id != '')) { sqlDbQuery('SELECT doc FROM main WHERE id = ? AND type = ? AND domain = ? AND extra IN (?)', [id, type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } else { - if (extrasids == null) { - sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ? AND extra IN (?)', [type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); - } else { - sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ? AND (extra IN (?) OR id IN (?))', [type, domain, meshes, extrasids], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); - } + sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ? AND (extra IN (?) OR id IN (?))', [type, domain, meshes, extrasids], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } }; obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) { + if ((nodes == null) || (nodes.length == 0)) { nodes = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. if (id && (id != '')) { sqlDbQuery('SELECT doc FROM main WHERE id = ? AND type = ? AND domain = ? AND extra IN (?)', [id, type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); } else { @@ -1385,7 +1387,10 @@ module.exports.CreateDB = function (parent, func) { } }; obj.GetAllType = function (type, func) { sqlDbQuery('SELECT doc FROM main WHERE type = ?', [type], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); } - obj.GetAllIdsOfType = function (ids, domain, type, func) { sqlDbQuery('SELECT doc FROM main WHERE id IN (?) AND domain = ? AND type = ?', [ids, domain, type], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); } + obj.GetAllIdsOfType = function (ids, domain, type, func) { + if ((ids == null) || (ids.length == 0)) { ids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. + sqlDbQuery('SELECT doc FROM main WHERE id IN (?) AND domain = ? AND type = ?', [ids, domain, type], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); + } obj.GetUserWithEmail = function (domain, email, func) { sqlDbQuery('SELECT doc FROM main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); } obj.GetUserWithVerifiedEmail = function (domain, email, func) { sqlDbQuery('SELECT doc FROM main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); } obj.Remove = function (id, func) { sqlDbQuery('DELETE FROM main WHERE id = ?', [id], func); }; @@ -1413,6 +1418,7 @@ module.exports.CreateDB = function (parent, func) { if (ids.indexOf('*') >= 0) { sqlDbQuery('SELECT doc FROM events WHERE (domain = ?) ORDER BY time DESC', [domain], func); } else { + if (ids.length == 0) { ids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = ? AND target IN (?)) GROUP BY id ORDER BY time DESC', [domain, ids], func); } }; @@ -1420,6 +1426,7 @@ module.exports.CreateDB = function (parent, func) { if (ids.indexOf('*') >= 0) { sqlDbQuery('SELECT doc FROM events WHERE (domain = ?) ORDER BY time DESC LIMIT ?', [domain, limit], func); } else { + if (ids.length == 0) { ids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = ? AND target IN (?)) GROUP BY id ORDER BY time DESC LIMIT ?', [domain, ids, limit], func); } }; @@ -1427,6 +1434,7 @@ module.exports.CreateDB = function (parent, func) { if (ids.indexOf('*') >= 0) { sqlDbQuery('SELECT doc FROM events WHERE (domain = ? AND userid = ?) ORDER BY time DESC', [domain, userid], func); } else { + if (ids.length == 0) { ids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = ? AND userid = ? AND target IN (?)) GROUP BY id ORDER BY time DESC', [domain, userid, ids], func); } }; @@ -1434,6 +1442,7 @@ module.exports.CreateDB = function (parent, func) { if (ids.indexOf('*') >= 0) { sqlDbQuery('SELECT doc FROM events WHERE (domain = ? AND userid = ?) ORDER BY time DESC LIMIT ?', [domain, userid, limit], func); } else { + if (ids.length == 0) { ids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE (domain = ? AND userid = ? AND target IN (?)) GROUP BY id ORDER BY time DESC LIMIT ?', [domain, userid, ids, limit], func); } }; @@ -1441,6 +1450,7 @@ module.exports.CreateDB = function (parent, func) { if (ids.indexOf('*') >= 0) { sqlDbQuery('SELECT doc FROM events WHERE ((domain = ?) AND (time BETWEEN ? AND ?)) ORDER BY time', [domain, start, end], func); } else { + if (ids.length == 0) { ids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead. sqlDbQuery('SELECT doc FROM events JOIN eventids ON id = fkid WHERE ((domain = ?) AND (target IN (?)) AND (time BETWEEN ? AND ?)) GROUP BY id ORDER BY time', [domain, ids, start, end], func); } }; @@ -1467,7 +1477,7 @@ module.exports.CreateDB = function (parent, func) { // Database actions on the Server Stats collection obj.SetServerStats = function (data, func) { sqlDbQuery('REPLACE INTO serverstats VALUE (?, ?, ?)', [data.time, data.expire, JSON.stringify(data)], func); }; - obj.GetServerStats = function (hours, func) { var t = new Date(); t.setTime(t.getTime() - (60 * 60 * 1000 * hours)); sqlDbQuery('SELECT doc FROM serverstats WHERE time > ?', [t], func); }; // TODO: Expire old entries + obj.GetServerStats = function (hours, func) { var t = new Date(); t.setTime(t.getTime() - (60 * 60 * 1000 * hours)); sqlDbQuery('SELECT doc FROM serverstats WHERE time > ?', [t], func); }; // Read a configuration file from the database obj.getConfigFile = function (path, func) { obj.Get('cfile/' + path, func); } diff --git a/docs/docs/design/index.md b/docs/docs/design/index.md index 3eda1e7c..6c90729a 100644 --- a/docs/docs/design/index.md +++ b/docs/docs/design/index.md @@ -81,6 +81,12 @@ The main takeaway is that MeshCentral is mostly an ExpressJS application. This i MeshCentral will run `npm install` automatically when any of these optional modules are needed but not currently available. +## Understanding the different modes: LAN, WAN and Hybrid + +
+ +
+ ## Code files and folders Someone would think the server is rather simple when taking a look at the MeshCentral server code files. At a high level, the entire server has 3 folders, 3 text files and a manageable number of .js files that are fairly self-descriptive. Here is a list of the source files and folders. diff --git a/docs/docs/install/index.md b/docs/docs/install/index.md index 34a428bf..f278b4b9 100644 --- a/docs/docs/install/index.md +++ b/docs/docs/install/index.md @@ -24,3 +24,9 @@ You can run the MeshCentral Server with --help to get options for background ins Once you get MeshCentral installed, the first user account that is created will be the server administrator. So, don't delay and navigate to the login page and create a new account. You can then start using your server right away. A lot of the fun with MeshCentral is the 100's of configuration options that are available in the config.json file. You can put your own branding on the web pages, setup a SMTP email server, SMS services and much more. You can look [here for simple config.json](https://raw.githubusercontent.com/Ylianst/MeshCentral/master/sample-config.json), [here for a more advanced configuration](https://raw.githubusercontent.com/Ylianst/MeshCentral/master/sample-config-advanced.json) and [here for all possible configuration options](https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json). You can also take a look at the [MeshCentral User's Guide](https://meshcentral.com/info/docs/MeshCentral2InstallGuide.pdf) and [tutorial videos](https://meshcentral.com/info/tutorials.html) for additional help. + +## Video Walkthru + +
+ +
\ No newline at end of file diff --git a/docs/docs/intelamt/index.md b/docs/docs/intelamt/index.md index c7ba65ca..67b3f74d 100644 --- a/docs/docs/intelamt/index.md +++ b/docs/docs/intelamt/index.md @@ -13,6 +13,12 @@ Intel AMT Guide [as .odt](https://github.com/Ylianst/MeshCentral/blob/master/doc This user guide contains all essential information for activating and using Intel® Active Management Technology (Intel® AMT) with MeshCentral. We will review how to activate, connect to and use Intel AMT features and how this benefit administrators that want to manage computers remotely. This document expect the reader to already be familiar with how to install and operate MeshCentral and have a basic understanding of how Intel® AMT works. +## History of AMT + +
+ +
+ ## Introduction MeshCentral is a free open source web-based remote computer management software and it fully supports Intel® Active Management Technology (Intel® AMT). MeshCentral does not require that computers it manages support Intel AMT, but if a remote computer has this capability, MeshCentral will make use of it. @@ -173,3 +179,19 @@ Once Intel AMT is in a situation where ACM activation can occur, the activation ![](images/2022-05-16-23-16-05.png) The best way to test this feature is to create an “Intel AMT only” device group and run the MeshCMD command on the remote system to perform activation. If there is a problem, this process should clearly display why ACM activation fails. + +## Intel AMT MEI and LMS + +Intel Active Management Technology (Intel AMT) can communicate to the local platform using the Management Engine Interface (MEI). We show how your can use that to get Intel AMT information. For more advanced usages, you need to connect using TCP and TLS which requires Intel Local Manageability Service (LMS). We show how MeshCentral's Mesh Agent and MeshCMD have a small version of LMS built-in and how it works + +
+ +
+ +## Intel AMT System Defense + +As part of Intel AMT there are hardware filters in the network interface you can setup to match and perform actions on packets. This happens at Ethernet speeds with no slow down and independent of the OS. + +
+ +
diff --git a/docs/docs/meshcentral/codesigning.md b/docs/docs/meshcentral/codesigning.md index f1482bb4..5cd7404a 100644 --- a/docs/docs/meshcentral/codesigning.md +++ b/docs/docs/meshcentral/codesigning.md @@ -6,6 +6,63 @@ Nodejs Code Signing module +MeshCentral comes with authenticode.js, you can run it like this: + +```bash +node node_modules/meshcentral/authenticode-js +``` + +and you will get + +``` +MeshCentral Authenticode Tool. +Usage: + node authenticode.js [command] [options] +Commands: + info: Show information about an executable. + --exe [file] Required executable to view information. + --json Show information in JSON format. + sign: Sign an executable. + --exe [file] Required executable to sign. + --out [file] Resulting signed executable. + --pem [pemfile] Certificate & private key to sign the executable with. + --desc [description] Description string to embbed into signature. + --url [url] URL to embbed into signature. + --hash [method] Default is SHA384, possible value: MD5, SHA224, SHA256, SHA384 or SHA512. + --time [url] The time signing server URL. + --proxy [url] The HTTP proxy to use to contact the time signing server, must start with http:// + unsign: Remove the signature from the executable. + --exe [file] Required executable to un-sign. + --out [file] Resulting executable with signature removed. + createcert: Create a code signging self-signed certificate and key. + --out [pemfile] Required certificate file to create. + --cn [value] Required certificate common name. + --country [value] Certificate country name. + --state [value] Certificate state name. + --locality [value] Certificate locality name. + --org [value] Certificate organization name. + --ou [value] Certificate organization unit name. + --serial [value] Certificate serial number. + timestamp: Add a signed timestamp to an already signed executable. + --exe [file] Required executable to sign. + --out [file] Resulting signed executable. + --time [url] The time signing server URL. + --proxy [url] The HTTP proxy to use to contact the time signing server, must start with http:// + +Note that certificate PEM files must first have the signing certificate, +followed by all certificates that form the trust chain. + +When doing sign/unsign, you can also change resource properties of the generated file. + + --filedescription [value] + --fileversion [value] + --internalname [value] + --legalcopyright [value] + --originalfilename [value] + --productname [value] + --productversion [value] +``` + ## Automatic Agent Code Signing If you want to self-sign the mesh agent so you can whitelist the software in your AV, and lock it to your server and organization. @@ -13,3 +70,6 @@ If you want to self-sign the mesh agent so you can whitelist the software in you
+ +!!!note + If you generate your private key on windows with use `BEGIN PRIVATE KEY` and openssl needs `BEGIN RSA PRIVATE KEY` you can convert your private key to rsa private key using `openssl rsa -in server.key -out server_new.key` \ No newline at end of file diff --git a/docs/docs/meshcentral/debugging.md b/docs/docs/meshcentral/debugging.md index b34360d5..ab6faa82 100644 --- a/docs/docs/meshcentral/debugging.md +++ b/docs/docs/meshcentral/debugging.md @@ -6,7 +6,22 @@ Make sure you understand how MeshCentral works with your browser using chrome de -## Enabling trace in your browser Dev Tools +## MeshCentral Server + +### Useful config.js settings + + + +```json +"AgentsInRAM": false, +"AgentUpdateBlockSize": 2048, +"agentUpdateSystem": 1, +"noAgentUpdate": 1, +"WsCompression": false, +"AgentWsCompression": false, +``` + +### Enabling trace in your browser Dev Tools `Trace=1` as a parameter in chrome dev tools for debugging @@ -34,7 +49,7 @@ If you want to change node to meshcentral in journalctl, add this to /etc/system SyslogIdentifier=meshcentral ``` -## Server: Logging it all +### Logging it all To log everything that's possible, prepare the log directory. @@ -84,7 +99,7 @@ You'll then have 3 files: `log.txt` will now log everything in the Trace tab -## Restricting server to specific IP(s) +### Restricting server to specific IP(s) When doing debugging on my development server, I use this line in the settings section to block all agent connections except the agent I want: @@ -94,8 +109,101 @@ When doing debugging on my development server, I use this line in the settings s Of course, this is just for debugging. -## Finding system ID types +### Finding system ID types aka trying figure out what this is ![ID](images/determine-id.png) + +### Pull down cert .crt file from internet + +[See #1662](https://github.com/Ylianst/MeshCentral/issues/1662#issuecomment-666559391) We have run into this challenge before, where our .crt file expired and then all our agents were unable to connect. In our case, the TLS cert was available on the internet, and thus, we were able to use these commands to update it: + +```bash +echo -n \| openssl s_client -connect yourdomain.com:443 2> /dev/null\| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /opt/meshcentral/meshcentral-data/webserver-cert-public.crt +service meshcentral restart +``` + +## MeshAgent + +### Agent Debug Logs to server + +This automatically downloads all agent error logs into `meshcentral-data/agenterrorlogs.txt` + +[Set](https://github.com/Ylianst/MeshCentral/blob/aa58afcc3a5d738177ab7a7b6d0228d72af82b85/meshcentral-config-schema.json#L100) in `config.json` + +```json +"agentLogDump": true +``` + +### Determine Agent capabilities + +On the server goto the agents console tab. Type: + +``` +info +``` + +### Useful MeshAgent.msh flags + + + +```json +controlChannelDebug=1 +logUpdate=1 +``` + +### Obtain generated .msh File + +If you need a trick to get the .msh file, you can add ?debug=1 to the URL and click "Add Agent", there will be an extra link to download it. + +### MeshAgent Commands + +``` +MeshAgent run +MeshAgent dbTool.js list +``` + +Forcing Core version from Cmdline + +* Download meschore.js and rename to CoreModule.js and put it alongside MeshAgent.exe +* Stop MeshAgent service +* Run `MeshAgent.exe dbTool.js import CoreModule` + +### On the fly Patching MeshAgent + +[MeshAgent#89 (comment)](https://github.com/Ylianst/MeshAgent/issues/89#issuecomment-949901720) + +There are two ways to do this... When debugging, and making changes, you can modify the .js file directly, and just save it in the same folder as the agent binary... The agent will use the .js file from disc if it's there, if it's newer than the one compiled in the binary. You don't even need to restart the agent. You can just clear the core, and reload the core..... + +When you are satisfied with your changes to the .js file, you can use the clipboard, in the following fashion: + +```bash +meshagent -exec "require('clipboard').nativeAddCompressedModule('foo');process.exit();" +``` + +if the file you modified isn't in the same folder as the agent binary, you can use the following command if you don't want to move the file, and edit it directly in the modules folder: + +```bash +meshagent -exec "setModulePath('pathToFolder');require('clipboard').nativeAddCompressedModule('foo');process.exit();" +``` + +This command is just like the previous, except it searches for modules in the path specified. + +Just substitute foo, with the name of the module that you modified. It will load the module from disc, compress it, and save it into the clipboard.. So you can just load up your editor for ILibDuktape_Polyfills.c, and find where that particular module is defined... and paste directly from the clipboard... The clipboard will contain all the necessary C code to uncompress and load the module. + +If the compressed result is relatively long, it will auto break it up into multiple lines to work around an issue with visual studio's maximum string literal limitations. + +### Agent Debugging using MeshCore JS Debugger + +[(#119)](https://github.com/Ylianst/MeshAgent/issues/119) How to test changes to the meshagent and recompile them. + +* Copy duktape-debugger.js to the mesh directory on the target machine. +* From the console tab of the agent, enter this command, substituting the port number you want to use instead of 9999 +`eval "attachDebugger({ webport: 9999 })"` + +Then open your browser to http://localhost:9999 or whatever port you used. + +!!!note + If you pause the debugger, and happen to forget about it, the agent will automatically kill itself and restart because it will think that a thread is stuck. Default debugger timeout is 10 minutes, you may find a log entry saved to disk saying "Microstack Thread STUCK", or something similar. + diff --git a/docs/docs/meshcentral/devicetabs.md b/docs/docs/meshcentral/devicetabs.md new file mode 100644 index 00000000..4373a399 --- /dev/null +++ b/docs/docs/meshcentral/devicetabs.md @@ -0,0 +1,26 @@ +# Device Tabs + +## General + +### 7 Day Power State + +Legend + +1. Black color: device is powered om +2. purple color: device is in sleep state +3. blue/green color : device is connected trough amt/cira, but not powered on +4. grey color: device is powered off + +![](images/7daypowerstate.png) + +## Desktop + +## Terminal + +## Files + +## Events + +## Details + +## Console \ No newline at end of file diff --git a/docs/docs/meshcentral/images/2022-06-17-15-56-14.png b/docs/docs/meshcentral/images/2022-06-17-15-56-14.png new file mode 100644 index 00000000..3ad780dc Binary files /dev/null and b/docs/docs/meshcentral/images/2022-06-17-15-56-14.png differ diff --git a/docs/docs/meshcentral/images/2022-06-17-15-56-55.png b/docs/docs/meshcentral/images/2022-06-17-15-56-55.png new file mode 100644 index 00000000..dd50e316 Binary files /dev/null and b/docs/docs/meshcentral/images/2022-06-17-15-56-55.png differ diff --git a/docs/docs/meshcentral/images/2022-06-17-15-57-03.png b/docs/docs/meshcentral/images/2022-06-17-15-57-03.png new file mode 100644 index 00000000..65111b19 Binary files /dev/null and b/docs/docs/meshcentral/images/2022-06-17-15-57-03.png differ diff --git a/docs/docs/meshcentral/images/2022-06-17-15-57-15.png b/docs/docs/meshcentral/images/2022-06-17-15-57-15.png new file mode 100644 index 00000000..60810b55 Binary files /dev/null and b/docs/docs/meshcentral/images/2022-06-17-15-57-15.png differ diff --git a/docs/docs/meshcentral/images/2022-06-17-15-57-30.png b/docs/docs/meshcentral/images/2022-06-17-15-57-30.png new file mode 100644 index 00000000..2a8337c8 Binary files /dev/null and b/docs/docs/meshcentral/images/2022-06-17-15-57-30.png differ diff --git a/docs/docs/meshcentral/images/2022-06-17-15-57-52.png b/docs/docs/meshcentral/images/2022-06-17-15-57-52.png new file mode 100644 index 00000000..11f97e89 Binary files /dev/null and b/docs/docs/meshcentral/images/2022-06-17-15-57-52.png differ diff --git a/docs/docs/meshcentral/images/7daypowerstate.png b/docs/docs/meshcentral/images/7daypowerstate.png new file mode 100644 index 00000000..de545544 Binary files /dev/null and b/docs/docs/meshcentral/images/7daypowerstate.png differ diff --git a/docs/docs/meshcentral/index.md b/docs/docs/meshcentral/index.md index e975f8dc..9a56067e 100644 --- a/docs/docs/meshcentral/index.md +++ b/docs/docs/meshcentral/index.md @@ -111,6 +111,16 @@ Click on any computer and go into the “Desktop” and “Files” tabs to remo For advance users with console/command line interface experience, go into “Terminal” to perform scripting or quick tasks with CLI tools. +### Desktop Control + +
+ +
+ +Depending on how the agent is connected to the server, there are multiple methods to remote control. Mesh Agent, RDP, and AMT + +For RDP connections, if you have previously saved the credentials that is usable by all users on the system. If you want to remove those saved credentials that's under the `General Tab` > `Credentials`. Click pen to clear them. + ## Server Certificate As seen in the previous chapter, MeshCentral is setup with a self-signed certificate by default and the web browser will issue a warning concerning the validity of the certificate. @@ -448,6 +458,34 @@ This first line will load many of the “meshcentral-data” files into the data Note that MeshCentral does not currently support placing a Let’s Encrypt certificate in the database. Generally, one would use a reverse proxy with Let’s Encrypt support and TLS offload in the reverse proxy and then run MeshCentral in state-less mode in a Docket container. +## Commandline Options + +In general, doing `--option value` is the same as adding `"option": value` in the settings section of the config.json. + +Here are the most common options found by running `meshcentral --help` + +``` +Run as a background service + --install/uninstall Install MeshCentral as a background service. + --start/stop/restart Control MeshCentral background service. + +Run standalone, console application + --user [username] Always login as [username] if account exists. + --port [number] Web server port number. + --redirport [number] Creates an additional HTTP server to redirect users to the HTTPS server. + --exactports Server must run with correct ports or exit. + --noagentupdate Server will not update mesh agent native binaries. + --nedbtodb Transfer all NeDB records into current database. + --listuserids Show a list of a user identifiers in the database. + --cert [name], (country), (org) Create a web server certificate with [name] server name. + country and organization can optionally be set. + +Server recovery commands, use only when MeshCentral is offline. + --createaccount [userid] Create a new user account. + --resetaccount [userid] Unlock an account, disable 2FA and set a new account password. + --adminaccount [userid] Promote account to site administrator. +``` + ## TLS Offloading A good way for MeshCentral to handle a high traffic is to setup a TLS offload device at front of the server that takes care of doing all the TLS negotiation and encryption so that the server could offload this. There are many vendors who offer TLS or SSL offload as a software module (Nginx* or Apache*) so please contact your network administrator for the best solution that suits your setup. @@ -517,8 +555,6 @@ If you successfully setup a Let’s Encrypt certificate using the Let’s Encryp If Let’s Encrypt works for you, please consider donating to them as they provide a critical service to the Internet community. - - ## Server IP filtering For improved security, it’s good to limit access to MeshCentral with IP address. For example, we want to allow mesh agents and Intel AMT computers to connect from anywhere, but whitelist IP address for users that we allow to access MeshCentral. @@ -706,12 +742,19 @@ MeshCentral supports the local device group allowing devices that do not have an ![](images/2022-05-31-10-30-42.png) +To enable SSH support, add this line to the domain section of your config.json: + +```json +"ssh": true +``` + Video Walkthru
+ ### Raritan and WebPowerSwitch with Relay In addition to local device groups, the IP-KVM/Power switch device group was also improved to support a MeshAgent as a relay. This is big news for Raritan IP-KVM switch owners as you can now monitor your IP-KVM ports and access them remotely from the Internet. The same can be done with WebPowerSwitch allowing full out-of-band remote access to devices from anywhere in the world. @@ -724,6 +767,12 @@ In addition to local device groups, the IP-KVM/Power switch device group was als ## NGINX Reverse-Proxy Setup +### Video Walkthru + +
+ +
+ Sometimes it’s useful to setup MeshCentral with a reverse-proxy in front of it. This is useful if you need to host many services on a single public IP address, if you want to offload TLS and perform extra web caching. In this section we will setup NGINX, a popular reverse-proxy, in front of MeshCentral. NGNIX is available at: https://www.nginx.com/ ![](images/2022-05-19-00-23-11.png) @@ -1180,6 +1229,38 @@ mongorestore --archive=backup.archive This will re-import the database from the backup. You can then start MeshCentral again. +### Backup to Google Drive + +```bash +sudo systemctl stop meshcentral.service +nano /opt/meshcentral/meshcentral-data/config.json +``` + +Remove underscored items + +![](images/2022-06-17-15-56-14.png) + +```bash +sudo systemctl start meshcentral.service +sudo systemctl status meshcentral.service +``` + +Log into your MC: + +![](images/2022-06-17-15-56-55.png) + +![](images/2022-06-17-15-57-03.png) + +Create desktop app + +![](images/2022-06-17-15-57-15.png) + +Enter the Client ID and Client Secret into MC + +![](images/2022-06-17-15-57-30.png) + +![](images/2022-06-17-15-57-52.png) + ## HashiCorp Vault support MeshCentral has built-in support for HashiCorp Vault so that all configuration and certificates used by MeshCentral are retrieved from a Vault server. Vault is a secret store server and when used with MeshCentral, the MeshCentral server will not be storing any secrets locally. You can get started with Vault here: https://www.vaultproject.io/ @@ -1685,3 +1766,11 @@ su -c '/bin/bash -i' myOtherUser ``` This will run bash in interactive mode and work correctly. + +#### SSH and SFTP integration to the Terminal + +MeshCentral has built-in web-based integration of SSH in the "Termina" tab and SFTP in the "Files" tab. + +
+ +
\ No newline at end of file diff --git a/docs/docs/meshcentral/plugins.md b/docs/docs/meshcentral/plugins.md new file mode 100644 index 00000000..e9d664ff --- /dev/null +++ b/docs/docs/meshcentral/plugins.md @@ -0,0 +1,9 @@ +# Plugins + +## Installation + +1. Enable plugins in the configuration and restart MC as described. +2. Log into MC as full administrator. +3. Go my `My Server` -> `Plugins`, hit the Download plugin button. +4. A dialog opens requesting an URL, put in: +5. The plugin pops up in the plugin list below the download button, you can now configure and enable/disable it. diff --git a/docs/docs/meshcmd/index.md b/docs/docs/meshcmd/index.md index 1032d51b..38528f91 100644 --- a/docs/docs/meshcmd/index.md +++ b/docs/docs/meshcmd/index.md @@ -416,6 +416,12 @@ In this example, the CIRA setup script was run on a remote computer. After the s ## IDE Redirection +## Video Walkthru + +
+ +
+ MeshCmd has all the code needed to perform Intel AMT IDE Redirection from the command line. This allows disk images on the administrator’s computer to be remotely mounted to an Intel AMT computer. You need to start with a floppy disk .img file and/or an .iso CDROM file. ![](images/2022-05-15-15-42-01.png) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 9ea8f3dc..326c1f94 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -9,6 +9,7 @@ nav: - MeshCentral2: - 'MeshCentral2 Guide': 'meshcentral/index.md' - 'All Configuration Options': 'meshcentral/config.md' + - 'Device Tabs': 'meshcentral/devicetabs.md' - 'Tokens': 'meshcentral/tokens.md' - 'Assistant': 'meshcentral/assistant.md' - 'Code Signing': 'meshcentral/codesigning.md' diff --git a/docs/powerpoints/README.md b/docs/powerpoints/README.md new file mode 100644 index 00000000..159d630d --- /dev/null +++ b/docs/powerpoints/README.md @@ -0,0 +1 @@ +Please place Powerpoints and slides here \ No newline at end of file diff --git a/meshagent.js b/meshagent.js index 297c3b25..f4fa5419 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1889,7 +1889,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (!device.intelamt) { device.intelamt = {}; } if ((command.intelamt.Versions != null) && (typeof command.intelamt.Versions == 'object')) { if ((command.intelamt.Versions.AMT != null) && (typeof command.intelamt.Versions.AMT == 'string') && (command.intelamt.Versions.AMT.length < 12) && (device.intelamt.ver != command.intelamt.Versions.AMT)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.Versions.AMT; change = 1; log = 1; } - if ((command.intelamt.Versions.Sku != null) && (typeof command.intelamt.Versions.Sku == 'string')) { var sku = parseInt(command.intelamt.Versions.Sku); if (device.intelamt.sku !== command.intelamt.sku) { device.intelamt.sku = sku; change = 1; log = 1; } } + if ((command.intelamt.Versions.Sku != null) && (typeof command.intelamt.Versions.Sku == 'string')) { + const sku = parseInt(command.intelamt.Versions.Sku); + if (device.intelamt.sku !== sku) { device.intelamt.sku = sku; change = 1; log = 1; } + } } if ((command.intelamt.ProvisioningState != null) && (typeof command.intelamt.ProvisioningState == 'number') && (device.intelamt.state != command.intelamt.ProvisioningState)) { changes.push('AMT state'); device.intelamt.state = command.intelamt.ProvisioningState; change = 1; log = 1; } if ((command.intelamt.Flags != null) && (typeof command.intelamt.Flags == 'number') && (device.intelamt.flags != command.intelamt.Flags)) { diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index 7e41c70b..46060972 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -101,6 +101,8 @@ "agentCoreDump": { "type": "boolean", "default": false, "description": "Automatically activates and transfers any agent crash dump files to the server in meshcentral-data/coredumps." }, "agentCoreDumpUsers": { "type": "array", "description": "List of non-administrator users that have access to mesh agent crash dumps." }, "agentSignLock": { "type": "boolean", "default": false, "description": "When code signing an agent using authenticode, lock the agent to only allow connection to this server. (This is in testing, the default value will change to true in the future)." }, + "agentTimeStampServer": { "type": [ "boolean", "string" ], "default": "http://timestamp.comodoca.com/authenticode", "description": "The time stamping server to use when code signing Windows executables. When set to false, the executables are not time stamped." }, + "agentTimeStampProxy": { "type": [ "boolean", "string" ], "description": "The HTTP proxy to use when contacting the time stamping server, if false, no proxy is used. By default, the npmproxy value is used." }, "ignoreAgentHashCheck": { "type": [ "boolean", "string" ], "default": false, "description": "When true, the agent no longer checked the TLS certificate of the server. This should be used for debugging only. You can also set this to a comma seperated list of IP addresses to ignore, for example: \"192.168.2.100,192.168.1.0/24\"." }, "exactPorts": { "type": "boolean", "default": false, "description": "When set to true, MeshCentral will only grab the required TCP listening ports or fail. It will not try to use the next available port of it's busy." }, "allowLoginToken": { "type": "boolean", "default": false }, @@ -542,6 +544,20 @@ "backgroundColor": { "type": "string", "default": null, "description": "Background color, valid values are RBG in format 0,0,0 to 255,255,255 or format #000000 to #FFFFFF." } } }, + "agentFileInfo": { + "type": "object", + "additionalProperties": false, + "description": "Use this section to set resource metadata of the Windows agents prior to signing. In Windows, you can right-click and select properties to view these values.", + "properties": { + "fileDescription": { "type": "string", "description": "Executable file description." }, + "fileVersion": { "type": "string", "description": "Executable file version, generally in the form of 1.2.3.4." }, + "internalName": { "type": "string", "description": "Executable internal name." }, + "legalCopyright": { "type": "string", "description": "Executable legal copyright." }, + "originalFilename": { "type": "string", "description": "Executable original file name." }, + "productName": { "type": "string", "description": "Executable product name." }, + "productVersion": { "type": "string", "description": "Executable product version, generally in the form of 1.2.3.4." } + } + }, "assistantCustomization": { "type": "object", "additionalProperties": false, diff --git a/meshcentral.js b/meshcentral.js index 8043ff2e..3d5a0590 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -145,7 +145,7 @@ function CreateMeshCentralServer(config, args) { if ((obj.args.help == true) || (obj.args['?'] == true)) { console.log('MeshCentral v' + getCurrentVersion() + ', remote computer management web portal.'); console.log('This software is open source under Apache 2.0 license.'); - console.log('Details at: https://www.meshcommander.com/meshcentral2\r\n'); + console.log('Details at: https://www.meshcentral.com\r\n'); if ((obj.platform == 'win32') || (obj.platform == 'linux')) { console.log('Run as a background service'); console.log(' --install/uninstall Install MeshCentral as a background service.'); @@ -1617,275 +1617,282 @@ function CreateMeshCentralServer(config, args) { // Load the list of mesh agents and install scripts if ((obj.args.noagentupdate == 1) || (obj.args.noagentupdate == true)) { for (i in obj.meshAgentsArchitectureNumbers) { obj.meshAgentsArchitectureNumbers[i].update = false; } } - obj.updateMeshAgentsTable(obj.config.domains[''], function () { - obj.updateMeshAgentInstallScripts(); + obj.signMeshAgents(obj.config.domains[''], function () { + obj.updateMeshAgentsTable(obj.config.domains[''], function () { + obj.updateMeshAgentInstallScripts(); - // Setup and start the web server - obj.crypto.randomBytes(48, function (err, buf) { - // Setup Mesh Multi-Server if needed - obj.multiServer = require('./multiserver.js').CreateMultiServer(obj, obj.args); - if (obj.multiServer != null) { - if ((obj.db.databaseType != 3) || (obj.db.changeStream != true)) { console.log("ERROR: Multi-server support requires use of MongoDB with ReplicaSet and ChangeStream enabled."); process.exit(0); return; } - if (typeof obj.args.sessionkey != 'string') { console.log("ERROR: Multi-server support requires \"SessionKey\" be set in the settings section of config.json, same key for all servers."); process.exit(0); return; } - obj.serverId = obj.multiServer.serverid; - for (var serverid in obj.config.peers.servers) { obj.peerConnectivityByNode[serverid] = {}; } - } + // Setup and start the web server + obj.crypto.randomBytes(48, function (err, buf) { + // Setup Mesh Multi-Server if needed + obj.multiServer = require('./multiserver.js').CreateMultiServer(obj, obj.args); + if (obj.multiServer != null) { + if ((obj.db.databaseType != 3) || (obj.db.changeStream != true)) { console.log("ERROR: Multi-server support requires use of MongoDB with ReplicaSet and ChangeStream enabled."); process.exit(0); return; } + if (typeof obj.args.sessionkey != 'string') { console.log("ERROR: Multi-server support requires \"SessionKey\" be set in the settings section of config.json, same key for all servers."); process.exit(0); return; } + obj.serverId = obj.multiServer.serverid; + for (var serverid in obj.config.peers.servers) { obj.peerConnectivityByNode[serverid] = {}; } + } - // If the server is set to "nousers", allow only loopback unless IP filter is set - if ((obj.args.nousers == true) && (obj.args.userallowedip == null)) { obj.args.userallowedip = "::1,127.0.0.1"; } + // If the server is set to "nousers", allow only loopback unless IP filter is set + if ((obj.args.nousers == true) && (obj.args.userallowedip == null)) { obj.args.userallowedip = "::1,127.0.0.1"; } - // Set the session length to 60 minutes if not set and set a random key if needed - if ((obj.args.sessiontime != null) && ((typeof obj.args.sessiontime != 'number') || (obj.args.sessiontime < 1))) { delete obj.args.sessiontime; } - if (typeof obj.args.sessionkey != 'string') { obj.args.sessionkey = buf.toString('hex').toUpperCase(); } + // Set the session length to 60 minutes if not set and set a random key if needed + if ((obj.args.sessiontime != null) && ((typeof obj.args.sessiontime != 'number') || (obj.args.sessiontime < 1))) { delete obj.args.sessiontime; } + if (typeof obj.args.sessionkey != 'string') { obj.args.sessionkey = buf.toString('hex').toUpperCase(); } - // Create MQTT Broker to hook into webserver and mpsserver - if ((typeof obj.config.settings.mqtt == 'object') && (typeof obj.config.settings.mqtt.auth == 'object') && (typeof obj.config.settings.mqtt.auth.keyid == 'string') && (typeof obj.config.settings.mqtt.auth.key == 'string')) { obj.mqttbroker = require("./mqttbroker.js").CreateMQTTBroker(obj, obj.db, obj.args); } + // Create MQTT Broker to hook into webserver and mpsserver + if ((typeof obj.config.settings.mqtt == 'object') && (typeof obj.config.settings.mqtt.auth == 'object') && (typeof obj.config.settings.mqtt.auth.keyid == 'string') && (typeof obj.config.settings.mqtt.auth.key == 'string')) { obj.mqttbroker = require("./mqttbroker.js").CreateMQTTBroker(obj, obj.db, obj.args); } - // Start the web server and if needed, the redirection web server. - obj.webserver = require('./webserver.js').CreateWebServer(obj, obj.db, obj.args, obj.certificates, obj.StartEx5); - if (obj.redirserver != null) { obj.redirserver.hookMainWebServer(obj.certificates); } + // Start the web server and if needed, the redirection web server. + obj.webserver = require('./webserver.js').CreateWebServer(obj, obj.db, obj.args, obj.certificates, obj.StartEx5); + if (obj.redirserver != null) { obj.redirserver.hookMainWebServer(obj.certificates); } - // Update proxy certificates - if (obj.supportsProxyCertificatesRequest == true) { obj.updateProxyCertificates(true); } + // Start the HTTP relay web server if needed + if ((obj.args.relayport != null) && (obj.args.relayport != 0)) { + obj.webrelayserver = require('./webrelayserver.js').CreateWebRelayServer(obj, obj.db, obj.args, obj.certificates, function () { }); + } - // Setup the Intel AMT event handler - obj.amtEventHandler = require('./amtevents.js').CreateAmtEventsHandler(obj); + // Update proxy certificates + if (obj.supportsProxyCertificatesRequest == true) { obj.updateProxyCertificates(true); } - // Setup the Intel AMT local network scanner - if (obj.args.wanonly != true) { - if (obj.args.amtscanner != false) { obj.amtScanner = require('./amtscanner.js').CreateAmtScanner(obj).start(); } - if (obj.args.meshscanner != false) { obj.meshScanner = require('./meshscanner.js').CreateMeshScanner(obj).start(); } - } + // Setup the Intel AMT event handler + obj.amtEventHandler = require('./amtevents.js').CreateAmtEventsHandler(obj); - // Setup and start the MPS server - obj.mpsserver = require('./mpsserver.js').CreateMpsServer(obj, obj.db, obj.args, obj.certificates); + // Setup the Intel AMT local network scanner + if (obj.args.wanonly != true) { + if (obj.args.amtscanner != false) { obj.amtScanner = require('./amtscanner.js').CreateAmtScanner(obj).start(); } + if (obj.args.meshscanner != false) { obj.meshScanner = require('./meshscanner.js').CreateMeshScanner(obj).start(); } + } - // Setup the Intel AMT manager - if (obj.args.amtmanager !== false) { - obj.amtManager = require('./amtmanager.js').CreateAmtManager(obj); - } + // Setup and start the MPS server + obj.mpsserver = require('./mpsserver.js').CreateMpsServer(obj, obj.db, obj.args, obj.certificates); - // Setup and start the legacy swarm server - if ((obj.certificates.swarmserver != null) && (obj.args.swarmport != null) && (obj.args.swarmport !== 0)) { - obj.swarmserver = require('./swarmserver.js').CreateSwarmServer(obj, obj.db, obj.args, obj.certificates); - } + // Setup the Intel AMT manager + if (obj.args.amtmanager !== false) { + obj.amtManager = require('./amtmanager.js').CreateAmtManager(obj); + } - // Setup the main email server - if (obj.config.sendgrid != null) { - // Sendgrid server - obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); - obj.mailserver.verify(); - if (obj.args.lanonly == true) { addServerWarning("SendGrid server has limited use in LAN mode.", 17); } - } else if (obj.config.smtp != null) { - // SMTP server - obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); - obj.mailserver.verify(); - if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode.", 18); } - } else if (obj.config.sendmail != null) { - // Sendmail server - obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); - obj.mailserver.verify(); - if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode.", 18); } - } + // Setup and start the legacy swarm server + if ((obj.certificates.swarmserver != null) && (obj.args.swarmport != null) && (obj.args.swarmport !== 0)) { + obj.swarmserver = require('./swarmserver.js').CreateSwarmServer(obj, obj.db, obj.args, obj.certificates); + } - // Setup the email server for each domain - for (i in obj.config.domains) { - if (obj.config.domains[i].sendgrid != null) { + // Setup the main email server + if (obj.config.sendgrid != null) { // Sendgrid server - obj.config.domains[i].mailserver = require('./meshmail.js').CreateMeshMail(obj, obj.config.domains[i]); - obj.config.domains[i].mailserver.verify(); + obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); + obj.mailserver.verify(); if (obj.args.lanonly == true) { addServerWarning("SendGrid server has limited use in LAN mode.", 17); } - } else if ((obj.config.domains[i].smtp != null) && (obj.config.domains[i].smtp.host != null) && (obj.config.domains[i].smtp.from != null)) { + } else if (obj.config.smtp != null) { // SMTP server - obj.config.domains[i].mailserver = require('./meshmail.js').CreateMeshMail(obj, obj.config.domains[i]); - obj.config.domains[i].mailserver.verify(); + obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); + obj.mailserver.verify(); if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode.", 18); } - } else if (obj.config.domains[i].sendmail != null) { + } else if (obj.config.sendmail != null) { // Sendmail server - obj.config.domains[i].mailserver = require('./meshmail.js').CreateMeshMail(obj, obj.config.domains[i]); - obj.config.domains[i].mailserver.verify(); + obj.mailserver = require('./meshmail.js').CreateMeshMail(obj); + obj.mailserver.verify(); if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode.", 18); } - } else { - // Setup the parent mail server for this domain - if (obj.mailserver != null) { obj.config.domains[i].mailserver = obj.mailserver; } } - } - // Setup SMS gateway - if (config.sms != null) { - obj.smsserver = require('./meshsms.js').CreateMeshSMS(obj); - if ((obj.smsserver != null) && (obj.args.lanonly == true)) { addServerWarning("SMS gateway has limited use in LAN mode.", 19); } - } - - // Setup web based push notifications - if ((typeof config.settings.webpush == 'object') && (typeof config.settings.webpush.email == 'string')) { - obj.webpush = require('web-push'); - var vapidKeys = null; - try { vapidKeys = JSON.parse(obj.fs.readFileSync(obj.path.join(obj.datapath, 'vapid.json')).toString()); } catch (ex) { } - if ((vapidKeys == null) || (typeof vapidKeys.publicKey != 'string') || (typeof vapidKeys.privateKey != 'string')) { - console.log("Generating web push VAPID keys..."); - vapidKeys = obj.webpush.generateVAPIDKeys(); - obj.fs.writeFileSync(obj.path.join(obj.datapath, 'vapid.json'), JSON.stringify(vapidKeys)); - } - obj.webpush.vapidPublicKey = vapidKeys.publicKey; - obj.webpush.setVapidDetails('mailto:' + config.settings.webpush.email, vapidKeys.publicKey, vapidKeys.privateKey); - if (typeof config.settings.webpush.gcmapi == 'string') { webpush.setGCMAPIKey(config.settings.webpush.gcmapi); } - } - - // Setup Firebase - if ((config.firebase != null) && (typeof config.firebase.senderid == 'string') && (typeof config.firebase.serverkey == 'string')) { - obj.firebase = require('./firebase').CreateFirebase(obj, config.firebase.senderid, config.firebase.serverkey); - } else if ((typeof config.firebaserelay == 'object') && (typeof config.firebaserelay.url == 'string')) { - // Setup the push messaging relay - obj.firebase = require('./firebase').CreateFirebaseRelay(obj, config.firebaserelay.url, config.firebaserelay.key); - } else if (obj.config.settings.publicpushnotifications === true) { - // Setup the Firebase push messaging relay using https://meshcentral.com, this is the public push notification server. - obj.firebase = require('./firebase').CreateFirebaseRelay(obj, 'https://meshcentral.com/firebaserelay.aspx'); - } - - // Start periodic maintenance - obj.maintenanceTimer = setInterval(obj.maintenanceActions, 1000 * 60 * 60); // Run this every hour - - // Dispatch an event that the server is now running - obj.DispatchEvent(['*'], obj, { etype: 'server', action: 'started', msg: 'Server started' }); - - // Plugin hook. Need to run something at server startup? This is the place. - if (obj.pluginHandler) { obj.pluginHandler.callHook('server_startup'); } - - // Setup the login cookie encryption key - if ((obj.config) && (obj.config.settings) && (typeof obj.config.settings.logincookieencryptionkey == 'string')) { - // We have a string, hash it and use that as a key - try { obj.loginCookieEncryptionKey = Buffer.from(obj.config.settings.logincookieencryptionkey, 'hex'); } catch (ex) { } - if ((obj.loginCookieEncryptionKey == null) || (obj.loginCookieEncryptionKey.length != 80)) { addServerWarning("Invalid \"LoginCookieEncryptionKey\" in config.json.", 20); obj.loginCookieEncryptionKey = null; } - } - - // Login cookie encryption key not set, use one from the database - if (obj.loginCookieEncryptionKey == null) { - obj.db.Get('LoginCookieEncryptionKey', function (err, docs) { - if ((docs != null) && (docs.length > 0) && (docs[0].key != null) && (obj.args.logintokengen == null) && (docs[0].key.length >= 160)) { - obj.loginCookieEncryptionKey = Buffer.from(docs[0].key, 'hex'); + // Setup the email server for each domain + for (i in obj.config.domains) { + if (obj.config.domains[i].sendgrid != null) { + // Sendgrid server + obj.config.domains[i].mailserver = require('./meshmail.js').CreateMeshMail(obj, obj.config.domains[i]); + obj.config.domains[i].mailserver.verify(); + if (obj.args.lanonly == true) { addServerWarning("SendGrid server has limited use in LAN mode.", 17); } + } else if ((obj.config.domains[i].smtp != null) && (obj.config.domains[i].smtp.host != null) && (obj.config.domains[i].smtp.from != null)) { + // SMTP server + obj.config.domains[i].mailserver = require('./meshmail.js').CreateMeshMail(obj, obj.config.domains[i]); + obj.config.domains[i].mailserver.verify(); + if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode.", 18); } + } else if (obj.config.domains[i].sendmail != null) { + // Sendmail server + obj.config.domains[i].mailserver = require('./meshmail.js').CreateMeshMail(obj, obj.config.domains[i]); + obj.config.domains[i].mailserver.verify(); + if (obj.args.lanonly == true) { addServerWarning("SMTP server has limited use in LAN mode.", 18); } } else { - obj.loginCookieEncryptionKey = obj.generateCookieKey(); obj.db.Set({ _id: 'LoginCookieEncryptionKey', key: obj.loginCookieEncryptionKey.toString('hex'), time: Date.now() }); + // Setup the parent mail server for this domain + if (obj.mailserver != null) { obj.config.domains[i].mailserver = obj.mailserver; } + } + } + + // Setup SMS gateway + if (config.sms != null) { + obj.smsserver = require('./meshsms.js').CreateMeshSMS(obj); + if ((obj.smsserver != null) && (obj.args.lanonly == true)) { addServerWarning("SMS gateway has limited use in LAN mode.", 19); } + } + + // Setup web based push notifications + if ((typeof config.settings.webpush == 'object') && (typeof config.settings.webpush.email == 'string')) { + obj.webpush = require('web-push'); + var vapidKeys = null; + try { vapidKeys = JSON.parse(obj.fs.readFileSync(obj.path.join(obj.datapath, 'vapid.json')).toString()); } catch (ex) { } + if ((vapidKeys == null) || (typeof vapidKeys.publicKey != 'string') || (typeof vapidKeys.privateKey != 'string')) { + console.log("Generating web push VAPID keys..."); + vapidKeys = obj.webpush.generateVAPIDKeys(); + obj.fs.writeFileSync(obj.path.join(obj.datapath, 'vapid.json'), JSON.stringify(vapidKeys)); + } + obj.webpush.vapidPublicKey = vapidKeys.publicKey; + obj.webpush.setVapidDetails('mailto:' + config.settings.webpush.email, vapidKeys.publicKey, vapidKeys.privateKey); + if (typeof config.settings.webpush.gcmapi == 'string') { webpush.setGCMAPIKey(config.settings.webpush.gcmapi); } + } + + // Setup Firebase + if ((config.firebase != null) && (typeof config.firebase.senderid == 'string') && (typeof config.firebase.serverkey == 'string')) { + obj.firebase = require('./firebase').CreateFirebase(obj, config.firebase.senderid, config.firebase.serverkey); + } else if ((typeof config.firebaserelay == 'object') && (typeof config.firebaserelay.url == 'string')) { + // Setup the push messaging relay + obj.firebase = require('./firebase').CreateFirebaseRelay(obj, config.firebaserelay.url, config.firebaserelay.key); + } else if (obj.config.settings.publicpushnotifications === true) { + // Setup the Firebase push messaging relay using https://meshcentral.com, this is the public push notification server. + obj.firebase = require('./firebase').CreateFirebaseRelay(obj, 'https://meshcentral.com/firebaserelay.aspx'); + } + + // Start periodic maintenance + obj.maintenanceTimer = setInterval(obj.maintenanceActions, 1000 * 60 * 60); // Run this every hour + + // Dispatch an event that the server is now running + obj.DispatchEvent(['*'], obj, { etype: 'server', action: 'started', msg: 'Server started' }); + + // Plugin hook. Need to run something at server startup? This is the place. + if (obj.pluginHandler) { obj.pluginHandler.callHook('server_startup'); } + + // Setup the login cookie encryption key + if ((obj.config) && (obj.config.settings) && (typeof obj.config.settings.logincookieencryptionkey == 'string')) { + // We have a string, hash it and use that as a key + try { obj.loginCookieEncryptionKey = Buffer.from(obj.config.settings.logincookieencryptionkey, 'hex'); } catch (ex) { } + if ((obj.loginCookieEncryptionKey == null) || (obj.loginCookieEncryptionKey.length != 80)) { addServerWarning("Invalid \"LoginCookieEncryptionKey\" in config.json.", 20); obj.loginCookieEncryptionKey = null; } + } + + // Login cookie encryption key not set, use one from the database + if (obj.loginCookieEncryptionKey == null) { + obj.db.Get('LoginCookieEncryptionKey', function (err, docs) { + if ((docs != null) && (docs.length > 0) && (docs[0].key != null) && (obj.args.logintokengen == null) && (docs[0].key.length >= 160)) { + obj.loginCookieEncryptionKey = Buffer.from(docs[0].key, 'hex'); + } else { + obj.loginCookieEncryptionKey = obj.generateCookieKey(); obj.db.Set({ _id: 'LoginCookieEncryptionKey', key: obj.loginCookieEncryptionKey.toString('hex'), time: Date.now() }); + } + }); + } + + // Load the invitation link encryption key from the database + obj.db.Get('InvitationLinkEncryptionKey', function (err, docs) { + if ((docs != null) && (docs.length > 0) && (docs[0].key != null) && (docs[0].key.length >= 160)) { + obj.invitationLinkEncryptionKey = Buffer.from(docs[0].key, 'hex'); + } else { + obj.invitationLinkEncryptionKey = obj.generateCookieKey(); obj.db.Set({ _id: 'InvitationLinkEncryptionKey', key: obj.invitationLinkEncryptionKey.toString('hex'), time: Date.now() }); } }); - } - // Load the invitation link encryption key from the database - obj.db.Get('InvitationLinkEncryptionKey', function (err, docs) { - if ((docs != null) && (docs.length > 0) && (docs[0].key != null) && (docs[0].key.length >= 160)) { - obj.invitationLinkEncryptionKey = Buffer.from(docs[0].key, 'hex'); - } else { - obj.invitationLinkEncryptionKey = obj.generateCookieKey(); obj.db.Set({ _id: 'InvitationLinkEncryptionKey', key: obj.invitationLinkEncryptionKey.toString('hex'), time: Date.now() }); + // Setup Intel AMT hello server + if ((typeof config.settings.amtprovisioningserver == 'object') && (typeof config.settings.amtprovisioningserver.devicegroup == 'string') && (typeof config.settings.amtprovisioningserver.newmebxpassword == 'string') && (typeof config.settings.amtprovisioningserver.trustedfqdn == 'string') && (typeof config.settings.amtprovisioningserver.ip == 'string')) { + obj.amtProvisioningServer = require('./amtprovisioningserver').CreateAmtProvisioningServer(obj, config.settings.amtprovisioningserver); } - }); - // Setup Intel AMT hello server - if ((typeof config.settings.amtprovisioningserver == 'object') && (typeof config.settings.amtprovisioningserver.devicegroup == 'string') && (typeof config.settings.amtprovisioningserver.newmebxpassword == 'string') && (typeof config.settings.amtprovisioningserver.trustedfqdn == 'string') && (typeof config.settings.amtprovisioningserver.ip == 'string')) { - obj.amtProvisioningServer = require('./amtprovisioningserver').CreateAmtProvisioningServer(obj, config.settings.amtprovisioningserver); - } + // Start collecting server stats every 5 minutes + obj.trafficStats = obj.webserver.getTrafficStats(); + setInterval(function () { + obj.serverStatsCounter++; + var hours = 720; // Start with all events lasting 30 days. + if (((obj.serverStatsCounter) % 2) == 1) { hours = 3; } // Half of the event get removed after 3 hours. + else if ((Math.floor(obj.serverStatsCounter / 2) % 2) == 1) { hours = 8; } // Another half of the event get removed after 8 hours. + else if ((Math.floor(obj.serverStatsCounter / 4) % 2) == 1) { hours = 24; } // Another half of the event get removed after 24 hours. + else if ((Math.floor(obj.serverStatsCounter / 8) % 2) == 1) { hours = 48; } // Another half of the event get removed after 48 hours. + else if ((Math.floor(obj.serverStatsCounter / 16) % 2) == 1) { hours = 72; } // Another half of the event get removed after 72 hours. + const expire = new Date(); + expire.setTime(expire.getTime() + (60 * 60 * 1000 * hours)); - // Start collecting server stats every 5 minutes - obj.trafficStats = obj.webserver.getTrafficStats(); - setInterval(function () { - obj.serverStatsCounter++; - var hours = 720; // Start with all events lasting 30 days. - if (((obj.serverStatsCounter) % 2) == 1) { hours = 3; } // Half of the event get removed after 3 hours. - else if ((Math.floor(obj.serverStatsCounter / 2) % 2) == 1) { hours = 8; } // Another half of the event get removed after 8 hours. - else if ((Math.floor(obj.serverStatsCounter / 4) % 2) == 1) { hours = 24; } // Another half of the event get removed after 24 hours. - else if ((Math.floor(obj.serverStatsCounter / 8) % 2) == 1) { hours = 48; } // Another half of the event get removed after 48 hours. - else if ((Math.floor(obj.serverStatsCounter / 16) % 2) == 1) { hours = 72; } // Another half of the event get removed after 72 hours. - const expire = new Date(); - expire.setTime(expire.getTime() + (60 * 60 * 1000 * hours)); + // Get traffic data + var trafficStats = obj.webserver.getTrafficDelta(obj.trafficStats); + obj.trafficStats = trafficStats.current; - // Get traffic data - var trafficStats = obj.webserver.getTrafficDelta(obj.trafficStats); - obj.trafficStats = trafficStats.current; + var data = { + time: new Date(), + expire: expire, + mem: process.memoryUsage(), + conn: { + ca: Object.keys(obj.webserver.wsagents).length, + cu: Object.keys(obj.webserver.wssessions).length, + us: Object.keys(obj.webserver.wssessions2).length, + rs: obj.webserver.relaySessionCount + }, + traffic: trafficStats.delta + }; + try { data.cpu = require('os').loadavg(); } catch (ex) { } + if (obj.mpsserver != null) { + data.conn.am = 0; + for (var i in obj.mpsserver.ciraConnections) { data.conn.am += obj.mpsserver.ciraConnections[i].length; } + } + if (obj.firstStats === true) { delete obj.firstStats; data.first = true; } + if (obj.multiServer != null) { data.s = obj.multiServer.serverid; } + obj.db.SetServerStats(data); // Save the stats to the database + obj.DispatchEvent(['*'], obj, { action: 'servertimelinestats', data: data }); // Event the server stats + }, 300000); - var data = { - time: new Date(), - expire: expire, - mem: process.memoryUsage(), - conn: { - ca: Object.keys(obj.webserver.wsagents).length, - cu: Object.keys(obj.webserver.wssessions).length, - us: Object.keys(obj.webserver.wssessions2).length, - rs: obj.webserver.relaySessionCount - }, - traffic: trafficStats.delta - }; - try { data.cpu = require('os').loadavg(); } catch (ex) { } - if (obj.mpsserver != null) { - data.conn.am = 0; - for (var i in obj.mpsserver.ciraConnections) { data.conn.am += obj.mpsserver.ciraConnections[i].length; } + obj.debug('main', "Server started"); + if (obj.args.nousers == true) { obj.updateServerState('nousers', '1'); } + obj.updateServerState('state', "running"); + + // Setup auto-backup defaults + if (obj.config.settings.autobackup == null) { obj.config.settings.autobackup = { backupintervalhours: 24, keeplastdaysbackup: 10 }; } + else if (obj.config.settings.autobackup === false) { delete obj.config.settings.autobackup; } + + // Check that autobackup path is not within the "meshcentral-data" folder. + if ((typeof obj.config.settings.autobackup == 'object') && (typeof obj.config.settings.autobackup.backuppath == 'string') && (obj.path.normalize(obj.config.settings.autobackup.backuppath).startsWith(obj.path.normalize(obj.datapath)))) { + addServerWarning("Backup path can't be set within meshcentral-data folder, backup settings ignored.", 21); + delete obj.config.settings.autobackup; } - if (obj.firstStats === true) { delete obj.firstStats; data.first = true; } - if (obj.multiServer != null) { data.s = obj.multiServer.serverid; } - obj.db.SetServerStats(data); // Save the stats to the database - obj.DispatchEvent(['*'], obj, { action: 'servertimelinestats', data: data }); // Event the server stats - }, 300000); - obj.debug('main', "Server started"); - if (obj.args.nousers == true) { obj.updateServerState('nousers', '1'); } - obj.updateServerState('state', "running"); + // Load Intel AMT passwords from the "amtactivation.log" file + obj.loadAmtActivationLogPasswords(function (amtPasswords) { + obj.amtPasswords = amtPasswords; + }); - // Setup auto-backup defaults - if (obj.config.settings.autobackup == null) { obj.config.settings.autobackup = { backupintervalhours: 24, keeplastdaysbackup: 10 }; } - else if (obj.config.settings.autobackup === false) { delete obj.config.settings.autobackup; } - - // Check that autobackup path is not within the "meshcentral-data" folder. - if ((typeof obj.config.settings.autobackup == 'object') && (typeof obj.config.settings.autobackup.backuppath == 'string') && (obj.path.normalize(obj.config.settings.autobackup.backuppath).startsWith(obj.path.normalize(obj.datapath)))) { - addServerWarning("Backup path can't be set within meshcentral-data folder, backup settings ignored.", 21); - delete obj.config.settings.autobackup; - } - - // Load Intel AMT passwords from the "amtactivation.log" file - obj.loadAmtActivationLogPasswords(function (amtPasswords) { - obj.amtPasswords = amtPasswords; - }); - - // Setup users that can see all device groups - if (typeof obj.config.settings.managealldevicegroups == 'string') { obj.config.settings.managealldevicegroups = obj.config.settings.managealldevicegroups.split(','); } - else if (Array.isArray(obj.config.settings.managealldevicegroups) == false) { obj.config.settings.managealldevicegroups = []; } - for (i in obj.config.domains) { - if (Array.isArray(obj.config.domains[i].managealldevicegroups)) { - for (var j in obj.config.domains[i].managealldevicegroups) { - if (typeof obj.config.domains[i].managealldevicegroups[j] == 'string') { - const u = 'user/' + i + '/' + obj.config.domains[i].managealldevicegroups[j]; - if (obj.config.settings.managealldevicegroups.indexOf(u) == -1) { obj.config.settings.managealldevicegroups.push(u); } + // Setup users that can see all device groups + if (typeof obj.config.settings.managealldevicegroups == 'string') { obj.config.settings.managealldevicegroups = obj.config.settings.managealldevicegroups.split(','); } + else if (Array.isArray(obj.config.settings.managealldevicegroups) == false) { obj.config.settings.managealldevicegroups = []; } + for (i in obj.config.domains) { + if (Array.isArray(obj.config.domains[i].managealldevicegroups)) { + for (var j in obj.config.domains[i].managealldevicegroups) { + if (typeof obj.config.domains[i].managealldevicegroups[j] == 'string') { + const u = 'user/' + i + '/' + obj.config.domains[i].managealldevicegroups[j]; + if (obj.config.settings.managealldevicegroups.indexOf(u) == -1) { obj.config.settings.managealldevicegroups.push(u); } + } } } } - } - obj.config.settings.managealldevicegroups.sort(); + obj.config.settings.managealldevicegroups.sort(); - // Start watchdog timer if needed - // This is used to monitor if NodeJS is servicing IO correctly or getting held up a lot. Add this line to the settings section of config.json - // "watchDog": { "interval": 100, "timeout": 150 } - // This will check every 100ms, if the timer is more than 150ms late, it will warn. - if ((typeof config.settings.watchdog == 'object') && (typeof config.settings.watchdog.interval == 'number') && (typeof config.settings.watchdog.timeout == 'number') && (config.settings.watchdog.interval >= 50) && (config.settings.watchdog.timeout >= 50)) { - obj.watchdogtime = Date.now(); - obj.watchdogmax = 0; - obj.watchdogmaxtime = null; - obj.watchdogtable = []; - obj.watchdog = setInterval(function () { - const now = Date.now(), delta = now - obj.watchdogtime - config.settings.watchdog.interval; - if (delta > obj.watchdogmax) { obj.watchdogmax = delta; obj.watchdogmaxtime = new Date().toLocaleString(); } - if (delta > config.settings.watchdog.timeout) { - const msg = obj.common.format("Watchdog timer timeout, {0}ms.", delta); - obj.watchdogtable.push(new Date().toLocaleString() + ', ' + delta + 'ms'); - while (obj.watchdogtable.length > 10) { obj.watchdogtable.shift(); } - obj.debug('main', msg); - try { - var errlogpath = null; - if (typeof obj.args.mesherrorlogpath == 'string') { errlogpath = obj.path.join(obj.args.mesherrorlogpath, 'mesherrors.txt'); } else { errlogpath = obj.getConfigFilePath('mesherrors.txt'); } - obj.fs.appendFileSync(errlogpath, new Date().toLocaleString() + ': ' + msg + '\r\n'); - } catch (ex) { console.log('ERROR: Unable to write to mesherrors.txt.'); } - } - obj.watchdogtime = now; - }, config.settings.watchdog.interval); - obj.debug('main', "Started watchdog timer."); - } + // Start watchdog timer if needed + // This is used to monitor if NodeJS is servicing IO correctly or getting held up a lot. Add this line to the settings section of config.json + // "watchDog": { "interval": 100, "timeout": 150 } + // This will check every 100ms, if the timer is more than 150ms late, it will warn. + if ((typeof config.settings.watchdog == 'object') && (typeof config.settings.watchdog.interval == 'number') && (typeof config.settings.watchdog.timeout == 'number') && (config.settings.watchdog.interval >= 50) && (config.settings.watchdog.timeout >= 50)) { + obj.watchdogtime = Date.now(); + obj.watchdogmax = 0; + obj.watchdogmaxtime = null; + obj.watchdogtable = []; + obj.watchdog = setInterval(function () { + const now = Date.now(), delta = now - obj.watchdogtime - config.settings.watchdog.interval; + if (delta > obj.watchdogmax) { obj.watchdogmax = delta; obj.watchdogmaxtime = new Date().toLocaleString(); } + if (delta > config.settings.watchdog.timeout) { + const msg = obj.common.format("Watchdog timer timeout, {0}ms.", delta); + obj.watchdogtable.push(new Date().toLocaleString() + ', ' + delta + 'ms'); + while (obj.watchdogtable.length > 10) { obj.watchdogtable.shift(); } + obj.debug('main', msg); + try { + var errlogpath = null; + if (typeof obj.args.mesherrorlogpath == 'string') { errlogpath = obj.path.join(obj.args.mesherrorlogpath, 'mesherrors.txt'); } else { errlogpath = obj.getConfigFilePath('mesherrors.txt'); } + obj.fs.appendFileSync(errlogpath, new Date().toLocaleString() + ': ' + msg + '\r\n'); + } catch (ex) { console.log('ERROR: Unable to write to mesherrors.txt.'); } + } + obj.watchdogtime = now; + }, config.settings.watchdog.interval); + obj.debug('main', "Started watchdog timer."); + } + }); }); }); }; @@ -2841,46 +2848,60 @@ function CreateMeshCentralServer(config, args) { 10006: { id: 10006, localname: 'MeshCentralAssistant.exe', rname: 'MeshCentralAssistant.exe', desc: 'MeshCentral Assistant for Windows', update: false, amt: false, platform: 'win32' } // MeshCentral Assistant }; - // Update the list of available mesh agents - obj.updateMeshAgentsTable = function (domain, func) { + // Sign windows agents + obj.signMeshAgents = function (domain, func) { // Setup the domain is specified var objx = domain, suffix = ''; if (domain.id == '') { objx = obj; } else { suffix = '-' + domain.id; objx.meshAgentBinaries = {}; } // Check if a custom agent signing certificate is available - var agentSignCertInfo = require('./authenticode.js').loadCertificates([ obj.path.join(obj.datapath, 'agentsigningcert.pem') ]); + var agentSignCertInfo = require('./authenticode.js').loadCertificates([obj.path.join(obj.datapath, 'agentsigningcert.pem')]); // If not using a custom signing cert, get agent code signature certificate ready with the full cert chain if ((agentSignCertInfo == null) && (obj.certificates.codesign != null)) { agentSignCertInfo = { cert: obj.certificateOperations.forge.pki.certificateFromPem(obj.certificates.codesign.cert), key: obj.certificateOperations.forge.pki.privateKeyFromPem(obj.certificates.codesign.key), - extraCerts: [obj.certificateOperations.forge.pki.certificateFromPem(obj.certificates.root.cert) ] + extraCerts: [obj.certificateOperations.forge.pki.certificateFromPem(obj.certificates.root.cert)] } } + if (agentSignCertInfo == null) { func(); return; } // No code signing certificate, nothing to do. + + // Setup the domain is specified + var objx = domain, suffix = ''; + if (domain.id == '') { objx = obj; } else { suffix = '-' + domain.id; objx.meshAgentBinaries = {}; } // Generate the agent signature description and URL - var serverSignedAgentsPath, signDesc, signUrl; - if (agentSignCertInfo != null) { - serverSignedAgentsPath = obj.path.join(obj.datapath, 'signedagents' + suffix); - signDesc = (domain.title ? domain.title : agentSignCertInfo.cert.subject.hash); - var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified - signUrl = 'https://' + ((domain.dns != null) ? domain.dns : obj.certificates.CommonName); - if (httpsPort != 443) { signUrl += ':' + httpsPort; } - var xdomain = (domain.dns == null) ? domain.id : ''; - if (xdomain != '') xdomain += '/'; - signUrl += '/' + xdomain; + const serverSignedAgentsPath = obj.path.join(obj.datapath, 'signedagents' + suffix); + const signDesc = (domain.title ? domain.title : agentSignCertInfo.cert.subject.hash); + const httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified + var httpsHost = ((domain.dns != null) ? domain.dns : obj.certificates.CommonName); + if (obj.args.agentaliasdns != null) { httpsHost = obj.args.agentaliasdns; } + var signUrl = 'https://' + httpsHost; + if (httpsPort != 443) { signUrl += ':' + httpsPort; } + var xdomain = (domain.dns == null) ? domain.id : ''; + if (xdomain != '') xdomain += '/'; + signUrl += '/' + xdomain; - // If requested, lock the agent to this server - if (obj.config.settings.agentsignlock) { signUrl += '?ServerID=' + obj.certificateOperations.getPublicKeyHash(obj.certificates.agent.cert).toUpperCase(); } - } + // If requested, lock the agent to this server + if (obj.config.settings.agentsignlock) { signUrl += '?ServerID=' + obj.certificateOperations.getPublicKeyHash(obj.certificates.agent.cert).toUpperCase(); } - // Load agent information file. This includes the data & time of the agent. - const agentInfo = []; - try { agentInfo = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'agents', 'hashagents.json'), 'utf8')); } catch (ex) { } + // Setup the time server + var timeStampUrl = 'http://timestamp.comodoca.com/authenticode'; + if (args.agenttimestampserver === false) { timeStampUrl = null; } + else if (typeof args.agenttimestampserver == 'string') { timeStampUrl = args.agenttimestampserver; } + + // Setup the time server proxy + var timeStampProxy = null; + if (typeof args.agenttimestampproxy == 'string') { timeStampProxy = args.agenttimestampproxy; } + else if ((args.agenttimestampproxy !== false) && (typeof args.npmproxy == 'string')) { timeStampProxy = args.npmproxy; } + + // Setup the pending operations counter + var pendingOperations = 1; - var archcount = 0; for (var archid in obj.meshAgentsArchitectureNumbers) { + if (obj.meshAgentsArchitectureNumbers[archid].codesign !== true) continue; + var agentpath; if (domain.id == '') { // Load all agents when processing the default domain @@ -2893,46 +2914,137 @@ function CreateMeshCentralServer(config, args) { if (obj.fs.existsSync(agentpath)) { delete obj.meshAgentsArchitectureNumbers[archid].codesign; } else { continue; } // If the agent is not present in "meshcentral-data/agents" skip. } + // Open the original agent with authenticode + const signeedagentpath = obj.path.join(serverSignedAgentsPath, obj.meshAgentsArchitectureNumbers[archid].localname); + const originalAgent = require('./authenticode.js').createAuthenticodeHandler(agentpath); + if (originalAgent != null) { + // Check if the agent is already signed correctly + const destinationAgent = require('./authenticode.js').createAuthenticodeHandler(signeedagentpath); + var destinationAgentOk = ( + (destinationAgent != null) && + (destinationAgent.fileHashSigned != null) && + (Buffer.compare(destinationAgent.fileHashSigned, destinationAgent.fileHashActual) == 0) && + (destinationAgent.signingAttribs.indexOf(signUrl) >= 0) && + (destinationAgent.signingAttribs.indexOf(signDesc) >= 0) + ); + + if (destinationAgent != null) { + // If the agent is signed correctly, look to see if the resources in the destination agent are correct + var orgVersionStrings = originalAgent.getVersionInfo(); + if (destinationAgentOk == true) { + var versionStrings = destinationAgent.getVersionInfo(); + var versionProperties = ['FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright', 'OriginalFilename', 'ProductName', 'ProductVersion']; + for (var i in versionProperties) { + const prop = versionProperties[i], propl = prop.toLowerCase(); + if ((domain.agentfileinfo != null) && (typeof domain.agentfileinfo == 'object') && (typeof domain.agentfileinfo[propl] == 'string')) { + if (domain.agentfileinfo[propl] != versionStrings[prop]) { destinationAgentOk = false; } // If the resource we want is not the same as the destination executable, we need to re-sign the agent. + } else { + if (orgVersionStrings[prop] != versionStrings[prop]) { destinationAgentOk = false; } // if the resource of the orginal agent not the same as the destination executable, we need to re-sign the agent. + } + } + } + + // If everything looks ok, runs a hash of the original and destination agent skipping the CRC, resource and signature blocks. If different, sign the agent again. + if ((destinationAgentOk == true) && (originalAgent.getHashNoResources('sha384').compare(destinationAgent.getHashNoResources('sha384')) != 0)) { destinationAgentOk = false; } + + // We are done comparing the destination agent, close it. + destinationAgent.close(); + } + + if (destinationAgentOk == false) { + // If not signed correctly, sign it. First, create the server signed agent folder if needed + try { obj.fs.mkdirSync(serverSignedAgentsPath); } catch (ex) { } + const xagentSignedFunc = function agentSignedFunc(err, size) { + if (err == null) { + // Agent was signed succesfuly + console.log(obj.common.format('Code signed agent {0}.', agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname)); + } else { + // Failed to sign agent + addServerWarning('Failed to sign agent \"' + agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname + '\": ' + err, 22, [ agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname, err ]); + } + if (--pendingOperations === 0) { agentSignedFunc.func(); } + } + pendingOperations++; + xagentSignedFunc.func = func; + xagentSignedFunc.objx = objx; + xagentSignedFunc.archid = archid; + xagentSignedFunc.signeedagentpath = signeedagentpath; + + // Parse the resources in the executable and make any required changes + var resChanges = false, versionStrings = null; + if ((domain.agentfileinfo != null) && (typeof domain.agentfileinfo == 'object')) { + versionStrings = originalAgent.getVersionInfo(); + var versionProperties = ['FileDescription', 'FileVersion', 'InternalName', 'LegalCopyright', 'OriginalFilename', 'ProductName', 'ProductVersion']; + for (var i in versionProperties) { + const prop = versionProperties[i], propl = prop.toLowerCase(); + if (domain.agentfileinfo[propl] && (domain.agentfileinfo[propl] != versionStrings[prop])) { versionStrings[prop] = domain.agentfileinfo[propl]; resChanges = true; } + } + if (resChanges == true) { originalAgent.setVersionInfo(versionStrings); } + } + + const signingArguments = { out: signeedagentpath, desc: signDesc, url: signUrl, time: timeStampUrl, proxy: timeStampProxy }; // Shallow clone + obj.debug('main', "Code signing agent with arguments: " + JSON.stringify(signingArguments)); + if (resChanges == false) { + // Sign the agent the simple way, without changing any resources. + originalAgent.sign(agentSignCertInfo, signingArguments, xagentSignedFunc); + } else { + // Change the agent resources and sign the agent, this is a much more involved process. + // NOTE: This is experimental and could corupt the agent. + originalAgent.writeExecutable(signingArguments, agentSignCertInfo, xagentSignedFunc); + } + } else { + // Signed agent is already ok, use it. + originalAgent.close(); + } + } + } + + if (--pendingOperations === 0) { func(); } + } + + // Update the list of available mesh agents + obj.updateMeshAgentsTable = function (domain, func) { + // Check if a custom agent signing certificate is available + var agentSignCertInfo = require('./authenticode.js').loadCertificates([obj.path.join(obj.datapath, 'agentsigningcert.pem')]); + + // If not using a custom signing cert, get agent code signature certificate ready with the full cert chain + if ((agentSignCertInfo == null) && (obj.certificates.codesign != null)) { + agentSignCertInfo = { + cert: obj.certificateOperations.forge.pki.certificateFromPem(obj.certificates.codesign.cert), + key: obj.certificateOperations.forge.pki.privateKeyFromPem(obj.certificates.codesign.key), + extraCerts: [obj.certificateOperations.forge.pki.certificateFromPem(obj.certificates.root.cert)] + } + } + + // Setup the domain is specified + var objx = domain, suffix = ''; + if (domain.id == '') { objx = obj; } else { suffix = '-' + domain.id; objx.meshAgentBinaries = {}; } + + // Load agent information file. This includes the data & time of the agent. + const agentInfo = []; + try { agentInfo = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'agents', 'hashagents.json'), 'utf8')); } catch (ex) { } + + var archcount = 0; + for (var archid in obj.meshAgentsArchitectureNumbers) { + var agentpath; + if (domain.id == '') { + // Load all agents when processing the default domain + agentpath = obj.path.join(__dirname, 'agents' + suffix, obj.meshAgentsArchitectureNumbers[archid].localname); + const agentpath2 = obj.path.join(obj.datapath, 'signedagents' + suffix, obj.meshAgentsArchitectureNumbers[archid].localname); + if (obj.fs.existsSync(agentpath2)) { agentpath = agentpath2; } // If the agent is present in "meshcentral-data/signedagents", use that one instead. + const agentpath3 = obj.path.join(obj.datapath, 'agents' + suffix, obj.meshAgentsArchitectureNumbers[archid].localname); + if (obj.fs.existsSync(agentpath3)) { agentpath = agentpath3; } // If the agent is present in "meshcentral-data/agents", use that one instead. + } else { + // When processing an extra domain, only load agents that are specific to that domain + var agentpath = obj.path.join(obj.datapath, 'agents' + suffix, obj.meshAgentsArchitectureNumbers[archid].localname); + if (obj.fs.existsSync(agentpath)) { delete obj.meshAgentsArchitectureNumbers[archid].codesign; } else { continue; } // If the agent is not present in "meshcentral-data/agents" skip. + } + // Fetch agent binary information var stats = null; try { stats = obj.fs.statSync(agentpath); } catch (ex) { } if ((stats == null)) continue; // If this agent does not exist, skip it. - // Check if we need to sign this agent, if so, check if it's already been signed - if ((obj.meshAgentsArchitectureNumbers[archid].codesign === true) && (agentSignCertInfo != null)) { - // Open the original agent with authenticode - var signeedagentpath = obj.path.join(serverSignedAgentsPath, obj.meshAgentsArchitectureNumbers[archid].localname); - const originalAgent = require('./authenticode.js').createAuthenticodeHandler(agentpath); - if (originalAgent != null) { - // Check if the agent is already signed correctly - const destinationAgent = require('./authenticode.js').createAuthenticodeHandler(signeedagentpath); - var destinationAgentOk = ( - (destinationAgent != null) && - (destinationAgent.fileHashSigned != null) && - (Buffer.compare(destinationAgent.fileHashSigned, destinationAgent.fileHashActual) == 0) && - ((Buffer.compare(destinationAgent.fileHashSigned, originalAgent.getHash(destinationAgent.fileHashAlgo))) == 0) && - (destinationAgent.signingAttribs.indexOf(signUrl) >= 0) && - (destinationAgent.signingAttribs.indexOf(signDesc) >= 0) - ); - if (destinationAgent != null) { destinationAgent.close(); } - if (destinationAgentOk == false) { - // If not signed correctly, sign it. First, create the server signed agent folder if needed - try { obj.fs.mkdirSync(serverSignedAgentsPath); } catch (ex) { } - if (originalAgent.sign(agentSignCertInfo, { out: signeedagentpath, desc: signDesc, url: signUrl }) == true) { - // Agent was signed succesfuly - agentpath = signeedagentpath; - console.log(obj.common.format('Code signed agent {0}.', obj.meshAgentsArchitectureNumbers[archid].localname)); - } else { - console.log(obj.common.format('Failed to sign agent {0}.', obj.meshAgentsArchitectureNumbers[archid].localname)); - } - } else { - // Signed agent is already ok, use it. - agentpath = signeedagentpath; - } - originalAgent.close(); - } - } - // Setup agent information archcount++; objx.meshAgentBinaries[archid] = Object.assign({}, obj.meshAgentsArchitectureNumbers[archid]); @@ -2952,7 +3064,7 @@ function CreateMeshCentralServer(config, args) { // Load the agent with a random msh added to it. const outStream = new require('stream').Duplex(); outStream.meshAgentBinary = objx.meshAgentBinaries[archid]; - outStream.meshAgentBinary.randomMsh = agentSignCertInfo.cert.subject.hash; + if (agentSignCertInfo) { outStream.meshAgentBinary.randomMsh = agentSignCertInfo.cert.subject.hash; } else { outStream.meshAgentBinary.randomMsh = obj.crypto.randomBytes(16).toString('hex'); } outStream.bufferList = []; outStream._write = function (chunk, encoding, callback) { this.bufferList.push(chunk); if (callback) callback(); }; // Append the chuck. outStream._read = function (size) { }; // Do nothing, this is not going to be called. diff --git a/meshrelay.js b/meshrelay.js index d2915e67..aab96b60 100644 --- a/meshrelay.js +++ b/meshrelay.js @@ -43,6 +43,8 @@ const MESHRIGHT_ADMIN = 0xFFFFFFFF; // 10 = Web-RDP // 11 = Web-SSH // 12 = Web-VNC +// 13 = Web-SSH-Files +// 14 = Web-TCP // 100 = Intel AMT WSMAN // 101 = Intel AMT Redirection // 200 = Messenger diff --git a/meshuser.js b/meshuser.js index 2c2ec115..aa2fe965 100644 --- a/meshuser.js +++ b/meshuser.js @@ -696,7 +696,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Request a list of all nodes db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', command.id, function (err, docs) { - //console.log(docs); + //console.log(err, docs); if (docs == null) { docs = []; } parent.common.unEscapeAllLinksFieldName(docs); @@ -2867,8 +2867,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if ((command.actiontype == 400) && common.validateInt(command.time, 1, 30000)) { routeCommandToNode({ action: 'msg', type: 'console', nodeid: node._id, value: 'flash ' + command.time }, MESHRIGHT_ADMIN, 0); } if ((command.actiontype == 401) && common.validateInt(command.time, 1, 30000)) { routeCommandToNode({ action: 'msg', type: 'console', nodeid: node._id, value: 'vibrate ' + command.time }, MESHRIGHT_ADMIN, 0); } } else { - // Check we have the rights to delete this device - if ((rights & MESHRIGHT_RESETOFF) == 0) return; + // Check we have the rights to perform this operation + if ((command.actiontype == 302) && ((rights & MESHRIGHT_WAKEDEVICE) == 0)) return; // This is a Intel AMT power on operation, check if we have WAKE rights + if ((command.actiontype != 302) && ((rights & MESHRIGHT_RESETOFF) == 0)) return; // For all other operations, check that we have RESET/OFF rights // If this device is connected on MQTT, send a power action. if ((parent.parent.mqttbroker != null) && (command.actiontype >= 0) && (command.actiontype <= 4)) { parent.parent.mqttbroker.publish(node._id, 'powerAction', ['', '', 'poweroff', 'reset', 'sleep'][command.actiontype]); } @@ -2913,7 +2914,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Perform input validation try { if (common.validateStrArray(command.nodeids, 1, 256) == false) { err = "Invalid nodeids"; } // Check nodeids - else if (common.validateString(command.title, 1, 512) == false) { err = "Invalid title"; } // Check title else if (common.validateString(command.msg, 1, 4096) == false) { err = "Invalid message"; } // Check message else { var nodeids = []; @@ -2928,6 +2928,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } + // Check the title, if needed, use a default one + if (common.validateString(command.title, 1, 512) == false) { delete command.title } // Check title + if ((command.title == null) && (typeof domain.notificationmessages == 'object') && (typeof domain.notificationmessages.title == 'string')) { command.title = domain.notificationmessages.title; } + if ((command.title == null) && (typeof domain.title == 'string')) { command.title = domain.title; } + if (command.title == null) { command.title = "MeshCentral"; } + for (i in command.nodeids) { // Get the node and the rights for this node parent.GetNodeWithRights(domain, user, command.nodeids[i], function (node, rights, visible) { @@ -3020,6 +3026,22 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } } + if ((typeof command.httpport == 'number') && (command.httpport > 0) && (command.httpport < 65536)) { + if ((command.httpport == 80) && (node.httpport != null)) { + delete node.httpport; change = 1; changes.push('httpport'); // Delete the HTTP port + } else { + node.httpport = command.httpport; change = 1; changes.push('httpport'); // Set the HTTP port + } + } + + if ((typeof command.httpsport == 'number') && (command.httpsport > 0) && (command.httpsport < 65536)) { + if ((command.httpsport == 443) && (node.httpsport != null)) { + delete node.httpsport; change = 1; changes.push('httpsport'); // Delete the HTTPS port + } else { + node.httpsport = command.httpsport; change = 1; changes.push('httpsport'); // Set the HTTPS port + } + } + if ((typeof command.ssh == 'number') && (command.ssh == 0)) { if ((node.ssh != null) && (node.ssh[user._id] != null)) { delete node.ssh[user._id]; change = 1; changes.push('ssh'); } // Delete the SSH cendentials } diff --git a/mpsserver.js b/mpsserver.js index 11ec460c..cacc4241 100644 --- a/mpsserver.js +++ b/mpsserver.js @@ -484,7 +484,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // We are under the limit, create the new device. // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, icon: (socket.tag.meiState.isBatteryPowered) ? 2 : 1, host: hostname, domain: domainid, intelamt: { user: (typeof socket.tag.meiState.amtuser == 'string') ? socket.tag.meiState.amtuser : '', pass: (typeof socket.tag.meiState.amtpass == 'string') ? socket.tag.meiState.amtpass : '', tls: 0, state: 2 } }; - if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if (socket.tag.meiState != null) { + if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if ((typeof socket.tag.meiState.Versions == 'object') && (typeof socket.tag.meiState.Versions.Sku == 'string')) { device.intelamt.sku = parseInt(socket.tag.meiState.Versions.Sku); } + } obj.db.Set(device); // Event the new node @@ -506,7 +509,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, icon: (socket.tag.meiState.isBatteryPowered) ? 2 : 1, host: hostname, domain: domainid, intelamt: { user: (typeof socket.tag.meiState.amtuser == 'string') ? socket.tag.meiState.amtuser : '', pass: (typeof socket.tag.meiState.amtpass == 'string') ? socket.tag.meiState.amtpass : '', tls: 0, state: 2 } }; - if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if (socket.tag.meiState != null) { + if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if ((typeof socket.tag.meiState.Versions == 'object') && (typeof socket.tag.meiState.Versions.Sku == 'string')) { device.intelamt.sku = parseInt(socket.tag.meiState.Versions.Sku); } + } obj.db.Set(device); // Event the new node @@ -707,7 +713,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // We are under the limit, create the new device. // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, icon: (socket.tag.meiState.isBatteryPowered) ? 2 : 1, host: hostname, domain: initialMesh.domain, intelamt: { user: (typeof socket.tag.meiState.amtuser == 'string') ? socket.tag.meiState.amtuser : '', pass: (typeof socket.tag.meiState.amtpass == 'string') ? socket.tag.meiState.amtpass : '', tls: 0, state: 2 } }; - if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if (socket.tag.meiState != null) { + if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if ((typeof socket.tag.meiState.Versions == 'object') && (typeof socket.tag.meiState.Versions.Sku == 'string')) { device.intelamt.sku = parseInt(socket.tag.meiState.Versions.Sku); } + } obj.db.Set(device); // Event the new node @@ -733,7 +742,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, icon: (socket.tag.meiState && socket.tag.meiState.isBatteryPowered) ? 2 : 1, host: hostname, domain: initialMesh.domain, intelamt: { user: ((socket.tag.meiState) && (typeof socket.tag.meiState.amtuser == 'string')) ? socket.tag.meiState.amtuser : '', pass: ((socket.tag.meiState) && (typeof socket.tag.meiState.amtpass == 'string')) ? socket.tag.meiState.amtpass : '', tls: 0, state: 2 } }; - if ((socket.tag.meiState != null) && (typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if (socket.tag.meiState != null) { + if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if ((typeof socket.tag.meiState.Versions == 'object') && (typeof socket.tag.meiState.Versions.Sku == 'string')) { device.intelamt.sku = parseInt(socket.tag.meiState.Versions.Sku); } + } obj.db.Set(device); // Event the new node @@ -793,7 +805,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 2, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: hostname, icon: (socket.tag.meiState && socket.tag.meiState.isBatteryPowered) ? 2 : 1, host: hostname, domain: initialMesh.domain, intelamt: { user: ((socket.tag.meiState) && (typeof socket.tag.meiState.amtuser == 'string')) ? socket.tag.meiState.amtuser : '', pass: ((socket.tag.meiState) && (typeof socket.tag.meiState.amtpass == 'string')) ? socket.tag.meiState.amtpass : '', tls: 0, state: 2, agent: { id: 0, caps: 0 } } }; - if ((socket.tag.meiState != null) && (typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if (socket.tag.meiState != null) { + if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if ((typeof socket.tag.meiState.Versions == 'object') && (typeof socket.tag.meiState.Versions.Sku == 'string')) { device.intelamt.sku = parseInt(socket.tag.meiState.Versions.Sku); } + } obj.db.Set(device); // Event the new node @@ -827,9 +842,11 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 2, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: hostname, icon: (socket.tag.meiState && socket.tag.meiState.isBatteryPowered) ? 2 : 1, host: hostname, domain: initialMesh.domain, agent: { ver: 0, id: 0, caps: 0 }, intelamt: { uuid: socket.tag.SystemId, user: ((socket.tag.meiState) && (typeof socket.tag.meiState.amtuser == 'string')) ? socket.tag.meiState.amtuser : '', pass: ((socket.tag.meiState) && (typeof socket.tag.meiState.amtpass == 'string')) ? socket.tag.meiState.amtpass : '', tls: 0, state: 2 } }; - if ((socket.tag.meiState != null) && (typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if (socket.tag.meiState != null) { + if ((typeof socket.tag.meiState.desc == 'string') && (socket.tag.meiState.desc.length > 0) && (socket.tag.meiState.desc.length < 1024)) { device.desc = socket.tag.meiState.desc; } + if ((typeof socket.tag.meiState.Versions == 'object') && (typeof socket.tag.meiState.Versions.Sku == 'string')) { device.intelamt.sku = parseInt(socket.tag.meiState.Versions.Sku); } + } obj.db.Set(device); - console.log('ADDED', device); // Event the new node addedDeviceCount++; diff --git a/package.json b/package.json index 5753a7d6..644f28f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "1.0.36", + "version": "1.0.45", "keywords": [ "Remote Device Management", "Remote Device Monitoring", diff --git a/public/scripts/agent-desktop-0.0.2-min.js b/public/scripts/agent-desktop-0.0.2-min.js index 8496d77a..bffc1eba 100644 --- a/public/scripts/agent-desktop-0.0.2-min.js +++ b/public/scripts/agent-desktop-0.0.2-min.js @@ -1 +1 @@ -Uint8Array.prototype.slice||Object.defineProperty(Uint8Array.prototype,"slice",{value:function(e,t){return new Uint8Array(Array.prototype.slice.call(this,e,t))}});var CreateAgentRemoteDesktop=function(e,t){var p={};"string"==typeof(p.CanvasId=e)&&(p.CanvasId=Q(e)),p.Canvas=p.CanvasId.getContext("2d"),p.scrolldiv=t,p.State=0,p.PendingOperations=[],p.tilesReceived=0,p.TilesDrawn=0,p.KillDraw=0,p.ipad=!1,p.tabletKeyboardVisible=!1,p.LastX=0,p.LastY=0,p.touchenabled=0,p.submenuoffset=0,p.touchtimer=null,p.TouchArray={},p.connectmode=0,p.connectioncount=0,p.rotation=0,p.protocol=2,p.debugmode=0,p.firstUpKeys=[],p.stopInput=!1,p.localKeyMap=!0,p.remoteKeyMap=!1,p.pressedKeys=[],p.sessionid=0,p.username,p.oldie=!1,p.ImageType=1,p.CompressionLevel=50,p.ScalingLevel=1024,p.FrameRateTimer=100,p.SwapMouse=!1,p.UseExtendedKeyFlag=!0,p.FirstDraw=!1,p.onRemoteInputLockChanged=null,p.RemoteInputLock=null,p.onKeyboardStateChanged=null,p.KeyboardState=0,p.ScreenWidth=960,p.ScreenHeight=701,p.width=960,p.height=960,p.displays=null,p.selectedDisplay=null,p.onScreenSizeChange=null,p.onMessage=null,p.onConnectCountChanged=null,p.onDebugMessage=null,p.onTouchEnabledChanged=null,p.onDisplayinfo=null;var S=!(p.accumulator=null),v="default";p.mouseCursorActive=function(e){S!=e&&(S=e,p.CanvasId.style.cursor=1==e?v:"default")};var C=["default","progress","crosshair","pointer","help","text","no-drop","move","nesw-resize","ns-resize","nwse-resize","w-resize","alias","wait","none","not-allowed","col-resize","row-resize","copy","zoom-in","zoom-out"];p.Start=function(){p.State=0,p.accumulator=null},p.Stop=function(){p.setRotation(0),p.UnGrabKeyInput(),p.UnGrabMouseInput(),p.touchenabled=0,null!=p.onScreenSizeChange&&p.onScreenSizeChange(p,p.ScreenWidth,p.ScreenHeight,p.CanvasId),p.Canvas.clearRect(0,0,p.CanvasId.width,p.CanvasId.height)},p.xxStateChange=function(e){p.State!=e&&(p.State=e,p.CanvasId.style.cursor="default",0===e&&p.Stop())},p.send=function(e){2>32)+p.intToStr(32&o)):(p.recordedSize+=n.length,p.shortToStr(e)+p.shortToStr(t)+p.intToStr(n.length)+p.intToStr(o>>32)+p.intToStr(32&o)+n)}return p.SendKeyMsg=function(e,t){var n,o;null!=e&&(t=t||window.event,n=!1,0==(n=(p.UseExtendedKeyFlag||1==urlargs.extkeys)&&"string"==typeof t.code&&(t.code.startsWith("Arrow")||0<=r.indexOf(t.code))?!0:n)&&t.code&&0==t.code.startsWith("NumPad")&&0==p.localKeyMap?null!=(o=(o=t).code.startsWith("Key")&&4==o.code.length?o.code.charCodeAt(3):o.code.startsWith("Digit")&&6==o.code.length?o.code.charCodeAt(5):o.code.startsWith("Numpad")&&7==o.code.length?o.code.charCodeAt(6)+48:a[o.code])&&p.SendKeyMsgKC(e,o,n):(59==(o=t.keyCode)?o=186:173==o?o=189:61==o&&(o=187),p.SendKeyMsgKC(e,o,n)))},p.SendRemoteInputLock=function(e){p.send(String.fromCharCode(0,87,0,5,e))},p.SendMessage=function(e){3==p.State&&p.send(String.fromCharCode(0,17)+p.shortToStr(4+e.length)+e)},p.SendKeyMsgKC=function(e,t,n){if(3==p.State)if("object"==typeof e)for(var o in e)p.SendKeyMsgKC(e[o][0],e[o][1],e[o][2]);else{1==e?-1==p.pressedKeys.indexOf(t)&&p.pressedKeys.unshift(t):2==e&&-1!=(o=p.pressedKeys.indexOf(t))&&p.pressedKeys.splice(o,1),0>8),255-(255&Math.abs(r))):(s=r>>8,255&r),String.fromCharCode(0,p.InputType.MOUSE,0,12,0,0,n/256&255,255&n,o/256&255,255&o,s,t)):String.fromCharCode(0,p.InputType.MOUSE,0,10,0,e==p.KeyAction.DOWN?a:2*a&255,n/256&255,255&n,o/256&255,255&o),p.Action==p.KeyAction.NONE?0==p.Alternate||p.ipad?(p.send(i),p.Alternate=1):p.Alternate=0:p.send(i)))},p.GetDisplayNumbers=function(){p.send(String.fromCharCode(0,11,0,4))},p.SetDisplay=function(e){p.send(String.fromCharCode(0,12,0,6,e>>8,255&e))},p.intToStr=function(e){return String.fromCharCode(e>>24&255,e>>16&255,e>>8&255,255&e)},p.shortToStr=function(e){return String.fromCharCode(e>>8&255,255&e)},p.onResize=function(){0!=p.ScreenWidth&&0!=p.ScreenHeight&&(p.Canvas.canvas.width==p.ScreenWidth&&p.Canvas.canvas.height==p.ScreenHeight||(p.FirstDraw&&(p.Canvas.canvas.width=p.ScreenWidth,p.Canvas.canvas.height=p.ScreenHeight,p.Canvas.fillRect(0,0,p.ScreenWidth,p.ScreenHeight),null!=p.onScreenSizeChange&&p.onScreenSizeChange(p,p.ScreenWidth,p.ScreenHeight,p.CanvasId)),p.FirstDraw=!1,1>32)+p.intToStr(32&o)):(p.recordedSize+=n.length,p.shortToStr(e)+p.shortToStr(t)+p.intToStr(n.length)+p.intToStr(o>>32)+p.intToStr(32&o)+n)}return p.SendKeyMsg=function(e,t){var n,o;null!=e&&(t=t||window.event,n=!1,0==(n=(p.UseExtendedKeyFlag||1==urlargs.extkeys)&&"string"==typeof t.code&&(t.code.startsWith("Arrow")||0<=r.indexOf(t.code))?!0:n)&&t.code&&0==t.code.startsWith("NumPad")&&0==p.localKeyMap?null!=(o=(o=t).code.startsWith("Key")&&4==o.code.length?o.code.charCodeAt(3):o.code.startsWith("Digit")&&6==o.code.length?o.code.charCodeAt(5):o.code.startsWith("Numpad")&&7==o.code.length?o.code.charCodeAt(6)+48:a[o.code])&&p.SendKeyMsgKC(e,o,n):(59==(o=t.keyCode)?o=186:173==o?o=189:61==o&&(o=187),p.SendKeyMsgKC(e,o,n)))},p.SendRemoteInputLock=function(e){p.send(String.fromCharCode(0,87,0,5,e))},p.SendMessage=function(e){3==p.State&&p.send(String.fromCharCode(0,17)+p.shortToStr(4+e.length)+e)},p.SendKeyMsgKC=function(e,t,n){if(3==p.State)if("object"==typeof e)for(var o in e)p.SendKeyMsgKC(e[o][0],e[o][1],e[o][2]);else{1==e?-1==p.pressedKeys.indexOf(t)&&p.pressedKeys.unshift(t):2==e&&-1!=(o=p.pressedKeys.indexOf(t))&&p.pressedKeys.splice(o,1),0>8),255-(255&Math.abs(r))):(s=r>>8,255&r),String.fromCharCode(0,p.InputType.MOUSE,0,12,0,0,n/256&255,255&n,o/256&255,255&o,s,t)):String.fromCharCode(0,p.InputType.MOUSE,0,10,0,e==p.KeyAction.DOWN?a:2*a&255,n/256&255,255&n,o/256&255,255&o),p.Action==p.KeyAction.NONE?0==p.Alternate||p.ipad?(p.send(i),p.Alternate=1):p.Alternate=0:p.send(i)))},p.GetDisplayNumbers=function(){p.send(String.fromCharCode(0,11,0,4))},p.SetDisplay=function(e){p.send(String.fromCharCode(0,12,0,6,e>>8,255&e))},p.intToStr=function(e){return String.fromCharCode(e>>24&255,e>>16&255,e>>8&255,255&e)},p.shortToStr=function(e){return String.fromCharCode(e>>8&255,255&e)},p.onResize=function(){0!=p.ScreenWidth&&0!=p.ScreenHeight&&(p.Canvas.canvas.width==p.ScreenWidth&&p.Canvas.canvas.height==p.ScreenHeight||(p.FirstDraw&&(p.Canvas.canvas.width=p.ScreenWidth,p.Canvas.canvas.height=p.ScreenHeight,p.Canvas.fillRect(0,0,p.ScreenWidth,p.ScreenHeight),null!=p.onScreenSizeChange&&p.onScreenSizeChange(p,p.ScreenWidth,p.ScreenHeight,p.CanvasId)),p.FirstDraw=!1,1a.ScreenWidth||t.y>a.ScreenHeight))return a.mouseNagleData=["mouse",t.x,t.y,0,!1],null==a.mouseNagleTimer&&(a.mouseNagleTimer=setTimeout(function(){a.socket.send(JSON.stringify(a.mouseNagleData)),a.mouseNagleTimer=null},50)),e.preventDefault(),!1}},a.m.mouseup=function(e){if(a.socket&&3==a.State){var t=s(e);if(!(t.x<0||t.y<0||t.x>a.ScreenWidth||t.y>a.ScreenHeight))return null!=a.mouseNagleTimer&&(clearTimeout(a.mouseNagleTimer),a.mouseNagleTimer=null),a.socket.send(JSON.stringify(["mouse",t.x,t.y,n(e.button),!1])),e.preventDefault(),!1}},a.m.mousedown=function(e){if(a.socket&&3==a.State){var t=s(e);if(!(t.x<0||t.y<0||t.x>a.ScreenWidth||t.y>a.ScreenHeight))return null!=a.mouseNagleTimer&&(clearTimeout(a.mouseNagleTimer),a.mouseNagleTimer=null),a.socket.send(JSON.stringify(["mouse",t.x,t.y,n(e.button),!0])),e.preventDefault(),!1}},a.m.handleKeyUp=function(e){if(a.socket&&3==a.State)return a.socket.send(JSON.stringify(["scancode",Mstsc.scancode(e),!1])),e.preventDefault(),!1},a.m.handleKeyDown=function(e){if(a.socket&&3==a.State)return a.socket.send(JSON.stringify(["scancode",Mstsc.scancode(e),!0])),e.preventDefault(),!1},a.m.mousewheel=function(e){if(a.socket&&3==a.State){var t=s(e);if(!(t.x<0||t.y<0||t.x>a.ScreenWidth||t.y>a.ScreenHeight)){null!=a.mouseNagleTimer&&(clearTimeout(a.mouseNagleTimer),a.mouseNagleTimer=null);var n=0;return e.detail?n=120*e.detail:e.wheelDelta&&(n=3*e.wheelDelta),0!=n&&a.socket.send(JSON.stringify(["wheel",t.x,t.y,n,!1,!1])),e.preventDefault(),!1}}},a.m.SendStringUnicode=function(e){a.socket&&3==a.State&&a.socket.send(JSON.stringify(["utype",e]))},a.m.SendKeyMsgKC=function(e,t,n){if(3==a.State)if("object"==typeof e)for(var s in e)a.m.SendKeyMsgKC(e[s][0],e[s][1],e[s][2]);else{t=i[t];null!=t&&a.socket.send(JSON.stringify(["scancode",t,0!=(1&e)]))}},a.m.mousedblclick=function(){},a.m.handleKeyPress=function(){},a.m.setRotation=function(){},a.m.sendcad=function(){a.socket.send(JSON.stringify(["scancode",29,!0])),a.socket.send(JSON.stringify(["scancode",56,!0])),a.socket.send(JSON.stringify(["scancode",57427,!0])),a.socket.send(JSON.stringify(["scancode",57427,!1])),a.socket.send(JSON.stringify(["scancode",56,!1])),a.socket.send(JSON.stringify(["scancode",29,!1]))};var i={9:15,16:42,17:29,18:56,27:1,33:57417,34:57425,35:57423,36:57415,37:57419,38:57416,39:57421,40:57424,44:57399,45:57426,46:57427,65:30,66:48,67:46,68:32,69:18,70:33,71:34,72:35,73:23,74:36,75:37,76:38,77:50,78:49,79:24,80:25,81:16,82:19,83:31,84:20,85:22,86:47,87:17,88:45,89:21,90:44,91:57435,112:59,113:60,114:61,115:62,116:63,117:64,118:65,119:66,120:67,121:68,122:87,123:88};return a} \ No newline at end of file +var CreateRDPDesktop=function(e){var a={m:{KeyAction:{NONE:0,DOWN:1,UP:2,SCROLL:3,EXUP:4,EXDOWN:5,DBLCLICK:6}},State:0};a.canvas=Q(e),"string"==typeof(a.CanvasId=e)&&(a.CanvasId=Q(e)),a.Canvas=a.CanvasId.getContext("2d"),a.ScreenWidth=a.width=1280,a.ScreenHeight=a.height=1024,a.m.onClipboardChanged=null;var o=!(a.onConsoleMessageChange=null),i="default";function n(e){return(!0===a.m.SwapMouse?[2,0,1,0,0]:[1,0,2,0,0])[e]}function r(e){a.State!=e&&(a.State=e,null!=a.onStateChanged&&a.onStateChanged(a,a.State))}function s(e){var t=a.Canvas.canvas.height/a.CanvasId.clientHeight,n=a.Canvas.canvas.width/a.CanvasId.clientWidth,s=function(e){var t=Array(2);for(t[0]=t[1]=0;e;)t[0]+=e.offsetLeft,t[1]+=e.offsetTop,e=e.offsetParent;return t}(a.Canvas.canvas),n=(e.pageX-s[0])*n,t=(e.pageY-s[1])*t;return e.addx&&(n+=e.addx),e.addy&&(t+=e.addy),{x:n,y:t}}a.mouseCursorActive=function(e){o!=e&&(o=e,a.CanvasId.style.cursor=1==e?i:"default")},a.Start=function(e,t,n){r(1),a.nodeid=e,a.port=t;var s={savepass:(a.credentials=n).savecred,useServerCreds:n.servercred,width:n.width,height:n.height,flags:n.flags,workingDir:n.workdir,alternateShell:n.altshell};n.width&&n.height&&(s.width=a.ScreenWidth=a.width=n.width,s.height=a.ScreenHeight=a.height=n.height,delete n.width,delete n.height),a.render=new Mstsc.Canvas.create(a.canvas),a.socket=new WebSocket("wss://"+window.location.host+"/mstscrelay.ashx"),a.socket.binaryType="arraybuffer",a.socket.onopen=function(){r(2),a.socket.send(JSON.stringify(["infos",{ip:a.nodeid,port:a.port,screen:{width:a.width,height:a.height},domain:n.domain,username:n.username,password:n.password,options:s,locale:Mstsc.locale()}]))},a.socket.onmessage=function(e){if("string"==typeof e.data){var t=JSON.parse(e.data);switch(t[0]){case"rdp-connect":r(3),a.rotation=0,a.Canvas.setTransform(1,0,0,1,0,0),a.Canvas.canvas.width=a.ScreenWidth,a.Canvas.canvas.height=a.ScreenHeight,a.Canvas.fillRect(0,0,a.ScreenWidth,a.ScreenHeight),null!=a.m.onScreenSizeChange&&a.m.onScreenSizeChange(a,a.ScreenWidth,a.ScreenHeight,a.CanvasId);break;case"rdp-bitmap":if(null==a.bitmapData)break;var n=t[1];n.data=a.bitmapData,delete a.bitmapData,a.render.update(n);break;case"rdp-pointer":n=t[1];i=n,o&&(a.CanvasId.style.cursor=n);break;case"rdp-close":a.Stop();break;case"rdp-error":switch(a.consoleMessageTimeout=5,a.consoleMessage=t[1],delete a.consoleMessageArgs,2a.ScreenWidth||t.y>a.ScreenHeight))return a.mouseNagleData=["mouse",t.x,t.y,0,!1],null==a.mouseNagleTimer&&(a.mouseNagleTimer=setTimeout(function(){a.socket.send(JSON.stringify(a.mouseNagleData)),a.mouseNagleTimer=null},50)),e.preventDefault(),!1}},a.m.mouseup=function(e){if(a.socket&&3==a.State){var t=s(e);if(!(t.x<0||t.y<0||t.x>a.ScreenWidth||t.y>a.ScreenHeight))return null!=a.mouseNagleTimer&&(clearTimeout(a.mouseNagleTimer),a.mouseNagleTimer=null),a.socket.send(JSON.stringify(["mouse",t.x,t.y,n(e.button),!1])),e.preventDefault(),!1}},a.m.mousedown=function(e){if(a.socket&&3==a.State){var t=s(e);if(!(t.x<0||t.y<0||t.x>a.ScreenWidth||t.y>a.ScreenHeight))return null!=a.mouseNagleTimer&&(clearTimeout(a.mouseNagleTimer),a.mouseNagleTimer=null),a.socket.send(JSON.stringify(["mouse",t.x,t.y,n(e.button),!0])),e.preventDefault(),!1}},a.m.handleKeyUp=function(e){if(a.socket&&3==a.State)return a.socket.send(JSON.stringify(["scancode",Mstsc.scancode(e),!1])),e.preventDefault(),!1},a.m.handleKeyDown=function(e){if(a.socket&&3==a.State)return a.socket.send(JSON.stringify(["scancode",Mstsc.scancode(e),!0])),e.preventDefault(),!1},a.m.mousewheel=function(e){if(a.socket&&3==a.State){var t=s(e);if(!(t.x<0||t.y<0||t.x>a.ScreenWidth||t.y>a.ScreenHeight)){null!=a.mouseNagleTimer&&(clearTimeout(a.mouseNagleTimer),a.mouseNagleTimer=null);var n=0;return e.detail?n=120*e.detail:e.wheelDelta&&(n=3*e.wheelDelta),a.m.ReverseMouseWheel&&(n*=-1),0!=n&&a.socket.send(JSON.stringify(["wheel",t.x,t.y,n,!1,!1])),e.preventDefault(),!1}}},a.m.SendStringUnicode=function(e){a.socket&&3==a.State&&a.socket.send(JSON.stringify(["utype",e]))},a.m.SendKeyMsgKC=function(e,t,n){if(3==a.State)if("object"==typeof e)for(var s in e)a.m.SendKeyMsgKC(e[s][0],e[s][1],e[s][2]);else{t=c[t];null!=t&&a.socket.send(JSON.stringify(["scancode",t,0!=(1&e)]))}},a.m.mousedblclick=function(){},a.m.handleKeyPress=function(){},a.m.setRotation=function(){},a.m.sendcad=function(){a.socket.send(JSON.stringify(["scancode",29,!0])),a.socket.send(JSON.stringify(["scancode",56,!0])),a.socket.send(JSON.stringify(["scancode",57427,!0])),a.socket.send(JSON.stringify(["scancode",57427,!1])),a.socket.send(JSON.stringify(["scancode",56,!1])),a.socket.send(JSON.stringify(["scancode",29,!1]))};var c={9:15,16:42,17:29,18:56,27:1,33:57417,34:57425,35:57423,36:57415,37:57419,38:57416,39:57421,40:57424,44:57399,45:57426,46:57427,65:30,66:48,67:46,68:32,69:18,70:33,71:34,72:35,73:23,74:36,75:37,76:38,77:50,78:49,79:24,80:25,81:16,82:19,83:31,84:20,85:22,86:47,87:17,88:45,89:21,90:44,91:57435,112:59,113:60,114:61,115:62,116:63,117:64,118:65,119:66,120:67,121:68,122:87,123:88};return a} \ No newline at end of file diff --git a/public/scripts/agent-rdp-0.0.1.js b/public/scripts/agent-rdp-0.0.1.js index 41412436..9c298870 100644 --- a/public/scripts/agent-rdp-0.0.1.js +++ b/public/scripts/agent-rdp-0.0.1.js @@ -18,6 +18,10 @@ var CreateRDPDesktop = function (canvasid) { obj.m.onClipboardChanged = null; obj.onConsoleMessageChange = null; + var xMouseCursorActive = true; + var xMouseCursorCurrent = 'default'; + obj.mouseCursorActive = function (x) { if (xMouseCursorActive == x) return; xMouseCursorActive = x; obj.CanvasId.style.cursor = ((x == true) ? xMouseCursorCurrent : 'default'); } + function mouseButtonMap(button) { // Swap mouse buttons if needed if (obj.m.SwapMouse === true) return [2, 0, 1, 0, 0][button]; @@ -75,6 +79,12 @@ var CreateRDPDesktop = function (canvasid) { obj.render.update(bitmap); break; } + case 'rdp-pointer': { + var pointer = msg[1]; + xMouseCursorCurrent = pointer; + if (xMouseCursorActive) { obj.CanvasId.style.cursor = pointer; } + break; + } case 'rdp-close': { obj.Stop(); break; @@ -198,6 +208,7 @@ var CreateRDPDesktop = function (canvasid) { if (obj.mouseNagleTimer != null) { clearTimeout(obj.mouseNagleTimer); obj.mouseNagleTimer = null; } var delta = 0; if (e.detail) { delta = (e.detail * 120); } else if (e.wheelDelta) { delta = (e.wheelDelta * 3); } + if (obj.m.ReverseMouseWheel) { delta = -1 * delta; } // Reverse the mouse wheel if (delta != 0) { obj.socket.send(JSON.stringify(['wheel', m.x, m.y, delta, false, false])); } e.preventDefault(); return false; diff --git a/public/scripts/amt-desktop-0.0.2-min.js b/public/scripts/amt-desktop-0.0.2-min.js index d974f7c5..590f4787 100644 --- a/public/scripts/amt-desktop-0.0.2-min.js +++ b/public/scripts/amt-desktop-0.0.2-min.js @@ -1 +1 @@ -var CreateAmtRemoteDesktop=function(e,t){var S={};function g(e){return String.fromCharCode.apply(null,e)}function p(e,t,a,n,r,o,i){var s,c,h,d,l=e[t++],v={},u=0,m=0;if(0==l){if(2==S.bpp)for(d=0;d>8&248)+","+(c>>3&252)+","+((31&c)<<3))+")");var f=k(a);n=x(0,n),a=f,S.canvas.fillRect(a,n,r,o)}else if(1>d&p],u++)}else{for(d=0;d>d&p],u++)}w(S.spare,a,n)}else if(128==l){if(2==S.bpp)for(;u>8&248,S.spare.data[r+1]=e>>3&252,S.spare.data[r+2]=(31&e)<<3}function b(e,t,a){if(S.graymode){var n=t<<2;for(S.lowcolor&&(e<<=4);0<=--a;)S.spare.data[n]=S.spare.data[n+1]=S.spare.data[n+2]=e,n+=4}else for(var n=t<<2,r=224&e,o=(28&e)<<3,i=T((3&e)<<6);0<=--a;)S.spare.data[n]=r,S.spare.data[n+1]=o,S.spare.data[n+2]=i,n+=4}function D(e,t,a){for(var n=t<<2,r=e>>8&248,o=e>>3&252,i=(31&e)<<3;0<=--a;)S.spare.data[n]=r,S.spare.data[n+1]=o,S.spare.data[n+2]=i,n+=4}function k(e){return 0==S.rotation||1==S.rotation?e:2==S.rotation?e-S.canvas.canvas.width:3==S.rotation?e-S.canvas.canvas.height:0}function x(e,t){return 0==S.rotation?t:1==S.rotation?t-S.canvas.canvas.width:2==S.rotation?t-S.canvas.canvas.height:3==S.rotation?t:0}function T(e){return 127>32)+IntToStr(32&n)):(S.recordedSize+=a.length,ShortToStr(e)+ShortToStr(t)+IntToStr(a.length)+IntToStr(n>>32)+IntToStr(32&n)+a)}return S.GrabMouseInput=function(){var e;1!=n&&((e=S.canvas.canvas).onmouseup=S.mouseup,e.onmousedown=S.mousedown,e.onmousemove=S.mousemove,e.onwheel=S.mousewheel,n=!0)},S.UnGrabMouseInput=function(){var e;0!=n&&((e=S.canvas.canvas).onmousemove=null,e.onmouseup=null,e.onmousedown=null,e.onwheel=null,n=!1)},S.GrabKeyInput=function(){1!=o&&(document.onkeyup=S.handleKeyUp,document.onkeydown=S.handleKeyDown,document.onkeypress=S.handleKeys,o=!0)},S.UnGrabKeyInput=function(){0!=o&&(document.onkeyup=null,document.onkeydown=null,document.onkeypress=null,o=!1)},S.handleKeys=function(e){return S.haltEvent(e)},S.handleKeyUp=function(e){return a(0,e)},S.handleKeyDown=function(e){return a(1,e)},S.haltEvent=function(e){return e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),!1},S.mousedblclick=function(e){},S.mousewheel=function(e){var t=0;if("number"==typeof e.deltaY?t=-1*e.deltaY:"number"==typeof e.detail?t=-1*e.detail:"number"==typeof e.wheelDelta&&(t=e.wheelDelta),0!=t){var a=S.buttonmask;return S.buttonmask|=1<<(0>8,255&S.width,S.height>>8,255&S.height)+S.DeskRecordServerInit.substring(4),S.recordedData.push(I(2,1,S.DeskRecordServerInit)),S.recordedData.push(I(3,0,atob(S.CanvasId.toDataURL("image/png").split(",")[1]))),!0)},S.StopRecording=function(){if(null!=S.recordedData){var e=S.recordedData;return e.push(I(3,0,"MeshCentralMCREC")),delete S.recordedData,delete S.recordedStart,delete S.recordedSize,e}},S} \ No newline at end of file +var CreateAmtRemoteDesktop=function(e,t){var S={};function g(e){return String.fromCharCode.apply(null,e)}function p(e,t,a,n,r,o,i){var s,c,h,d,l=e[t++],v={},u=0,m=0;if(0==l){if(2==S.bpp)for(d=0;d>8&248)+","+(c>>3&252)+","+((31&c)<<3))+")");var f=k(a);n=x(0,n),a=f,S.canvas.fillRect(a,n,r,o)}else if(1>d&p],u++)}else{for(d=0;d>d&p],u++)}w(S.spare,a,n)}else if(128==l){if(2==S.bpp)for(;u>8&248,S.spare.data[r+1]=e>>3&252,S.spare.data[r+2]=(31&e)<<3}function b(e,t,a){if(S.graymode){var n=t<<2;for(S.lowcolor&&(e<<=4);0<=--a;)S.spare.data[n]=S.spare.data[n+1]=S.spare.data[n+2]=e,n+=4}else for(var n=t<<2,r=224&e,o=(28&e)<<3,i=T((3&e)<<6);0<=--a;)S.spare.data[n]=r,S.spare.data[n+1]=o,S.spare.data[n+2]=i,n+=4}function D(e,t,a){for(var n=t<<2,r=e>>8&248,o=e>>3&252,i=(31&e)<<3;0<=--a;)S.spare.data[n]=r,S.spare.data[n+1]=o,S.spare.data[n+2]=i,n+=4}function k(e){return 0==S.rotation||1==S.rotation?e:2==S.rotation?e-S.canvas.canvas.width:3==S.rotation?e-S.canvas.canvas.height:0}function x(e,t){return 0==S.rotation?t:1==S.rotation?t-S.canvas.canvas.width:2==S.rotation?t-S.canvas.canvas.height:3==S.rotation?t:0}function T(e){return 127>32)+IntToStr(32&n)):(S.recordedSize+=a.length,ShortToStr(e)+ShortToStr(t)+IntToStr(a.length)+IntToStr(n>>32)+IntToStr(32&n)+a)}return S.GrabMouseInput=function(){var e;1!=n&&((e=S.canvas.canvas).onmouseup=S.mouseup,e.onmousedown=S.mousedown,e.onmousemove=S.mousemove,e.onwheel=S.mousewheel,n=!0)},S.UnGrabMouseInput=function(){var e;0!=n&&((e=S.canvas.canvas).onmousemove=null,e.onmouseup=null,e.onmousedown=null,e.onwheel=null,n=!1)},S.GrabKeyInput=function(){1!=o&&(document.onkeyup=S.handleKeyUp,document.onkeydown=S.handleKeyDown,document.onkeypress=S.handleKeys,o=!0)},S.UnGrabKeyInput=function(){0!=o&&(document.onkeyup=null,document.onkeydown=null,document.onkeypress=null,o=!1)},S.handleKeys=function(e){return S.haltEvent(e)},S.handleKeyUp=function(e){return a(0,e)},S.handleKeyDown=function(e){return a(1,e)},S.haltEvent=function(e){return e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),!1},S.mousedblclick=function(e){},S.mousewheel=function(e){var t=0;if("number"==typeof e.deltaY?t=-1*e.deltaY:"number"==typeof e.detail?t=-1*e.detail:"number"==typeof e.wheelDelta&&(t=e.wheelDelta),0!=t){S.ReverseMouseWheel&&(t*=-1);var a=S.buttonmask;return S.buttonmask|=1<<(0>8,255&S.width,S.height>>8,255&S.height)+S.DeskRecordServerInit.substring(4),S.recordedData.push(I(2,1,S.DeskRecordServerInit)),S.recordedData.push(I(3,0,atob(S.CanvasId.toDataURL("image/png").split(",")[1]))),!0)},S.StopRecording=function(){if(null!=S.recordedData){var e=S.recordedData;return e.push(I(3,0,"MeshCentralMCREC")),delete S.recordedData,delete S.recordedStart,delete S.recordedSize,e}},S} \ No newline at end of file diff --git a/public/scripts/amt-desktop-0.0.2.js b/public/scripts/amt-desktop-0.0.2.js index ceb550c2..9cde5b2e 100644 --- a/public/scripts/amt-desktop-0.0.2.js +++ b/public/scripts/amt-desktop-0.0.2.js @@ -931,6 +931,10 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) { else if (typeof e.detail == 'number') { v = -1 * e.detail; } else if (typeof e.wheelDelta == 'number') { v = e.wheelDelta; } if (v == 0) return; + + // Reverse mouse wheel if needed + if (obj.ReverseMouseWheel) { v = -1 * v; } + var tmpmask = obj.buttonmask; obj.buttonmask |= (1 << ((v > 0) ? 3 : 4)); obj.mousemove(e, 1); diff --git a/public/translate.bat b/public/translate.bat index 2b94c869..b1320d12 100644 --- a/public/translate.bat +++ b/public/translate.bat @@ -1,7 +1,7 @@ @ECHO OFF CD ..\translate -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js minifyall -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js translateall -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js extractall +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node translate.js minifyall +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node translate.js translateall +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node translate.js extractall DEL ..\emails\translations\*-min_* Pause \ No newline at end of file diff --git a/rdp/core/layer.js b/rdp/core/layer.js index 2f7e9a66..7aa92d3b 100644 --- a/rdp/core/layer.js +++ b/rdp/core/layer.js @@ -22,7 +22,7 @@ var fs = require('fs'); var type = require('./type'); var log = require('./log'); var tls = require('tls'); -var crypto = require('crypto'); +//var crypto = require('crypto'); var events = require('events'); /** diff --git a/rdp/protocol/pdu/data.js b/rdp/protocol/pdu/data.js index 7c79012d..dec3ffd8 100644 --- a/rdp/protocol/pdu/data.js +++ b/rdp/protocol/pdu/data.js @@ -186,7 +186,7 @@ var FastPathUpdateType = { FASTPATH_UPDATETYPE_PTR_NULL : 0x5, FASTPATH_UPDATETYPE_PTR_DEFAULT : 0x6, FASTPATH_UPDATETYPE_PTR_POSITION : 0x8, - FASTPATH_UPDATETYPE_COLOR : 0x9, + FASTPATH_UPDATETYPE_COLOR : 0x9, // Mouse cursor FASTPATH_UPDATETYPE_CACHED : 0xA, FASTPATH_UPDATETYPE_POINTER : 0xB }; @@ -1075,7 +1075,7 @@ function clipPDU() { * @param opt {object} type option * @returns {type.Component} */ -function fastPathBitmapUpdateDataPDU (opt) { +function fastPathBitmapUpdateDataPDU(opt) { var self = { __FASTPATH_UPDATE_TYPE__ : FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP, header : new type.UInt16Le(FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP, { constant : true }), @@ -1093,13 +1093,67 @@ function fastPathBitmapUpdateDataPDU (opt) { return new type.Component(self, opt); } +// This is a table of cursorid to cursor name. +// Created by movering the mouse over this page: https://www.w3schools.com/csSref/tryit.asp?filename=trycss_cursor +const cursorIdTable = { + // Normal style mouse cursor + 903013897: 'alias', + 370524792: 'all-scroll', + 853046751: 'cell', + 2101250798: 'col-resize', + 703681364: 'copy', + 992638936: 'crosshair', + 1539083673: 'ew-resize', + 1919796298: 'grab', + 1010243511: 'grabbing', + 1247283057: 'help', + 1390892051: 'none', + 885751489: 'not-allowed', + 1732952247: 'row-resize', + 747144997: 'url', + 2018345610: 'zoom-in', + 347367048: 'zoom-out', + 1872942890: 'default', + 1737852989: 'text', + 1932827019: 'ns-resize', + 1884471290: 'nesw-resize', + 1204065391: 'nwse-resize', + 2030531519: 'progress', + 1050842114: 'pointer', + + // Black style cursors + 1258195498: 'default', + 219484254: 'all-scroll', + 399295089: 'text', + 1912613597: 'wait', + 864127801: 'ew-resize', + 23245044: 'nesw-resize', + 1966995494: 'not-allowed', + 1873216615: 'help', + 255126408: 'nesw-resize', + 157191894: 'ns-resize', + 1768446509: 'pointer', + 1032011501: 'crosshair' +} + +function fastPathPointerUpdateDataPDU(opt, cursorId, cursorStr) { + var self = { + __FASTPATH_UPDATE_TYPE__: FastPathUpdateType.FASTPATH_UPDATETYPE_COLOR, + header: new type.UInt16Le(FastPathUpdateType.FASTPATH_UPDATETYPE_COLOR, { constant: true }), + cursorId: cursorId, + cursorStr: cursorStr + }; + + return new type.Component(self, opt); +} + /** * @see http://msdn.microsoft.com/en-us/library/cc240622.aspx * @param updateData {type.Component} * @param opt {object} type option * @returns {type.Component} */ -function fastPathUpdatePDU (updateData, opt) { +function fastPathUpdatePDU(updateData, opt) { var self = { updateHeader : new type.UInt8( function () { return self.updateData.obj.__FASTPATH_UPDATE_TYPE__; @@ -1116,12 +1170,27 @@ function fastPathUpdatePDU (updateData, opt) { }) }; switch (self.updateHeader.value & 0xf) { - case FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP: - self.updateData = fastPathBitmapUpdateDataPDU(options).read(s); - break; - default: - self.updateData = new type.BinaryString(null, options).read(s); - log.debug('unknown fast path pdu type ' + (self.updateHeader.value & 0xf)); + case FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP: { + self.updateData = fastPathBitmapUpdateDataPDU(options).read(s); + break; + } + case FastPathUpdateType.FASTPATH_UPDATETYPE_COLOR: { + var data = new type.BinaryString(null, options).read(s); + + // Hash the data to get a cursor id. + // This is a hack since the cursor bitmap is sent but we can't use that, we has hash the bitmap and use that as a hint as to what cursor we need to display + const hasher = require('crypto').createHash('sha384'); + hasher.update(data.value); + const cursorid = Math.abs(hasher.digest().readInt32BE(0)); + const cursorStr = cursorIdTable[cursorid]; + //if (cursorStr == null) { console.log('Unknown cursorId: ' + cursorid); } + self.updateData = fastPathPointerUpdateDataPDU(options, cursorid, cursorStr); + break; + } + default: { + self.updateData = new type.BinaryString(null, options).read(s); + log.debug('unknown fast path pdu type ' + (self.updateHeader.value & 0xf)); + } } }) }; diff --git a/rdp/protocol/pdu/global.js b/rdp/protocol/pdu/global.js index a3f5766d..5fc3ddd7 100644 --- a/rdp/protocol/pdu/global.js +++ b/rdp/protocol/pdu/global.js @@ -268,11 +268,16 @@ Client.prototype.recvServerFontMapPDU = function(s) { */ Client.prototype.recvFastPath = function (secFlag, s) { while (s.availableLength() > 0) { - var pdu = data.fastPathUpdatePDU().read(s); + var pdu = data.fastPathUpdatePDU().read(s); switch (pdu.obj.updateHeader.value & 0xf) { - case data.FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP: - this.emit('bitmap', pdu.obj.updateData.obj.rectangles.obj); - break; + case data.FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP: { + this.emit('bitmap', pdu.obj.updateData.obj.rectangles.obj); + break; + } + case data.FastPathUpdateType.FASTPATH_UPDATETYPE_COLOR: { + this.emit('pointer', pdu.obj.updateData.obj.cursorId, pdu.obj.updateData.obj.cursorStr); + break; + } default: } } diff --git a/rdp/protocol/rdp.js b/rdp/protocol/rdp.js index c58e2e1c..41d71c9a 100644 --- a/rdp/protocol/rdp.js +++ b/rdp/protocol/rdp.js @@ -160,6 +160,8 @@ function RdpClient(config) { }).on('close', function () { self.connected = false; self.emit('close'); + }).on('pointer', function (cursorId, cursorStr) { + self.emit('pointer', cursorId, cursorStr); }).on('bitmap', function (bitmaps) { for (var bitmap in bitmaps) { var bitmapData = bitmaps[bitmap].obj.bitmapDataStream.value; diff --git a/redirserver.js b/redirserver.js index aadbcd96..54f69b30 100644 --- a/redirserver.js +++ b/redirserver.js @@ -142,7 +142,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) { obj.parent.updateServerState('redirect-port', port); func(obj.port); }).on('error', function (err) { - if ((err.code == 'EACCES') && (port < 65535)) { StartRedirServer(port + 1); } else { console.log(err); func(obj.port); } + if ((err.code == 'EACCES') && (port < 65535)) { StartRedirServer(port + 1, addr); } else { console.log(err); func(obj.port); } }); } diff --git a/sample-config-advanced.json b/sample-config-advanced.json index c2ff425d..a3cc0f76 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -10,7 +10,7 @@ "_WANonly": true, "_LANonly": true, "_maintenanceMode": true, - "_certificatePrivateKeyPassword": [ "password1", "password2" ], + "_certificatePrivateKeyPassword": ["password1", "password2"], "_sessionTime": 60, "_sessionKey": "MyReallySecretPassword1", "_sessionSameSite": "strict", @@ -38,6 +38,8 @@ "_agentCoreDump": true, "_agentCoreDumpUsers": "user1,user2", "_agentSignLock": true, + "_agentTimeStampServer": "http://timestamp.digicert.com", + "_agentTimeStampProxy": "http://1.2.3.4:80", "_ignoreAgentHashCheck": true, "_exactPorts": true, "_allowLoginToken": true, @@ -72,14 +74,15 @@ "_webPush": { "email": "xxxxx@xxxxx.com" }, "_publicPushNotifications": true, "_desktopMultiplex": true, + "_ipBlockedUserRedirect": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "_userAllowedIP": "127.0.0.1,192.168.1.0/24", "_userBlockedIP": "127.0.0.1,::1,192.168.0.100", "_agentAllowedIP": "192.168.0.100/24", "_agentBlockedIP": "127.0.0.1,::1", "_authLog": "c:\\temp\\auth.log", - "_InterUserMessaging": [ "user//admin" ], - "_manageAllDeviceGroups": [ "user//admin" ], - "_manageCrossDomain": [ "user//admin" ], + "_InterUserMessaging": ["user//admin"], + "_manageAllDeviceGroups": ["user//admin"], + "_manageCrossDomain": ["user//admin"], "_localDiscovery": { "name": "Local server name", "info": "Information about this server" @@ -91,6 +94,7 @@ "_mpsAliasPort": 4433, "_mpsAliasHost": "mps.mydomain.com", "_mpsTlsOffload": true, + "_mpsHighSecurity": true, "_no2FactorAuth": true, "_runOnServerStarted": "c:\\tmp\\mcstart.bat", "_runOnServerUpdated": "c:\\tmp\\mcupdate.bat", @@ -162,19 +166,21 @@ "title2": "Servername", "_titlePicture": "title-sample.png", "_loginPicture": "title-sample.png", + "_rootRedirect": "https://www.youtube.com/watch?v=Gs069dndIYk", + "_mobileSite": false, + "_unknownUserRootRedirect": "https://www.youtube.com/watch?v=2Q_ZzBGPdqE", + "_nightMode": 1, "_userQuota": 1048576, "_meshQuota": 248576, + "_loginKey": ["abc", "123"], + "_agentKey": ["abc", "123"], + "_ipkvm": false, "minify": true, - "_guestDeviceSharing" : false, - "_AutoRemoveInactiveDevices": 37, - "_DeviceSearchBarServerAndClientName": false, - "_loginKey": [ "abc", "123" ], - "_agentKey": [ "abc", "123" ], "_newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "_userNameIsEmail": true, - "_newAccountEmailDomains": [ "sample.com" ], - "_newAccountsRights": [ "nonewgroups", "notools" ], + "_newAccountEmailDomains": ["sample.com"], + "_newAccountsRights": ["nonewgroups", "notools"], "_welcomeText": "Sample Text on Login Page.", "_welcomePicture": "mainwelcome.jpg", "_welcomePictureFullScreen": false, @@ -184,6 +190,13 @@ "_hide": 4, "_footer": "Twitter", "_loginfooter": "This is a private server.", + "_allowSavingDeviceCredentials": false, + "_guestDeviceSharing": false, + "_AutoRemoveInactiveDevices": 37, + "_DeviceSearchBarServerAndClientName": false, + "_agentSelfGuestSharing": { + "expire": 120 + }, "_certUrl": "https://192.168.2.106:443/", "_altMessenging": { "name": "Jitsi", @@ -199,7 +212,7 @@ "protocol": "http", "port": 80, "_ip": "192.168.1.100", - "_filter": [ "mesh/(domainid)/(meshid)", "node/(domainid)/(nodeid)" ] + "_filter": ["mesh/(domainid)/(meshid)", "node/(domainid)/(nodeid)"] }, { "name": "HTTPS", @@ -210,7 +223,7 @@ }, "PreconfiguredRemoteInput": [ { - "name": "CompagnyUrl", + "name": "CompanyUrl", "value": "https://help.mycompany.com/" }, { @@ -221,7 +234,7 @@ "name": "Welcome", "value": "Default welcome text" } - ], + ], "myServer": { "Backup": false, "Restore": false, @@ -274,6 +287,15 @@ "image": "agent-logo.png", "fileName": "compagnyagent" }, + "_agentFileInfo": { + "_filedescription": "sample_filedescription", + "_fileversion": "0.1.2.3", + "_internalname": "sample_internalname", + "_legalcopyright": "sample_legalcopyright", + "_originalfilename": "sample_originalfilename", + "_productname": "sample_productname", + "_productversion": "0.1.2.3" + }, "_assistantCustomization": { "title": "Company® Product™", "image": "assistant-logo.png", @@ -324,14 +346,24 @@ "log": "amtactivation.log", "certs": { "mycertname": { - "certfiles": [ "amtacm-leafcert.crt", "amtacm-intermediate1.crt", "amtacm-intermediate2.crt", "amtacm-rootcert.crt" ], + "certfiles": [ + "amtacm-leafcert.crt", + "amtacm-intermediate1.crt", + "amtacm-intermediate2.crt", + "amtacm-rootcert.crt" + ], "keyfile": "amtacm-leafcert.key" } } }, "_amtManager": { "adminAccounts": [{ "user": "admin", "pass": "MyP@ssw0rd" }], - "environmentDetection": [ "domain1.com", "domain2.com", "domain3.com", "domain4.com" ], + "environmentDetection": [ + "domain1.com", + "domain2.com", + "domain3.com", + "domain4.com" + ], "wifiProfiles": [ { "name": "Profile1", @@ -354,8 +386,8 @@ "Strict-Transport-Security": "max-age=360000", "x-frame-options": "SAMEORIGIN" }, - "_agentConfig": [ "webSocketMaskOverride=1", "coreDumpEnabled=1" ], - "_assistantConfig": [ "disableUpdate=1" ], + "_agentConfig": ["webSocketMaskOverride=1", "coreDumpEnabled=1"], + "_assistantConfig": ["disableUpdate=1"], "_sessionRecording": { "_onlySelectedUsers": true, "_onlySelectedUserGroups": true, @@ -366,42 +398,42 @@ "_maxRecordingDays": 15, "_maxRecordingSizeMegabytes": 3, "__protocols__": "Is an array: 1 = Terminal, 2 = Desktop, 5 = Files, 100 = Intel AMT WSMAN, 101 = Intel AMT Redirection, 200 = Messenger", - "protocols": [ 1, 2, 101 ] + "protocols": [1, 2, 101] }, "_authStrategies": { "__comment__": "This section is used to allow users to login using other accounts. You will need to get an API key from the services and register callback URL's", "twitter": { "_callbackurl": "https://server/auth-twitter-callback", "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "clientid": "xxxxxxxxxxxxxxxxxxxxxxx", "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, "google": { "_callbackurl": "https://server/auth-google-callback", "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "clientid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com", "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxx" }, "github": { "_callbackurl": "https://server/auth-github-callback", "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "clientid": "xxxxxxxxxxxxxxxxxxxxxxx", "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, "reddit": { "_callbackurl": "https://server/auth-reddit-callback", "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "clientid": "xxxxxxxxxxxxxxxxxxxxxxx", "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, "azure": { "_callbackurl": "https://server/auth-azure-callback", "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "clientid": "00000000-0000-0000-0000-000000000000", "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "tenantid": "00000000-0000-0000-0000-000000000000" @@ -409,7 +441,7 @@ "jumpcloud": { "_callbackurl": "https://server/auth-jumpcloud-callback", "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], "entityid": "meshcentral", "idpurl": "https://sso.jumpcloud.com/saml2/saml2", "cert": "jumpcloud-saml.pem" @@ -418,8 +450,8 @@ "_callbackurl": "https://server/auth-saml-callback", "_disableRequestedAuthnContext": true, "newAccounts": true, - "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ], - "_newAccountsRights": [ "nonewgroups", "notools" ], + "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"], + "_newAccountsRights": ["nonewgroups", "notools"], "entityid": "meshcentral", "idpurl": "https://server/saml2", "cert": "saml.pem" @@ -455,7 +487,7 @@ "uid": "anneonyme", "mail": "anneonyme@example.com", "email": "anneonyme@example.com", - "otherMail": [ "other.anneonyme@example.com", "anneonyme@example.com" ] + "otherMail": ["other.anneonyme@example.com", "anneonyme@example.com"] }, "so": { "displayName": "Sticker Sophie", @@ -463,7 +495,7 @@ "uid": "ssticker", "mail": "ssticker@example.com", "email": "ssticker@example.com", - "otherMail": [ "other.ssticker@example.com", "ssticker@example.com" ] + "otherMail": ["other.ssticker@example.com", "ssticker@example.com"] } }, "__LDAPOptions": { @@ -512,7 +544,7 @@ "_sendmail": { "newline": "unix", "path": "/usr/sbin/sendmail", - "_args": [ "-f", "foo@example.com" ] + "_args": ["-f", "foo@example.com"] }, "_sms": { "provider": "twilio", diff --git a/translate/translate-node12.bat b/translate/translate-node12.bat deleted file mode 100644 index 9a98a8da..00000000 --- a/translate/translate-node12.bat +++ /dev/null @@ -1,4 +0,0 @@ -@ECHO OFF -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js minifyall -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js translateall -%LOCALAPPDATA%\..\Roaming\nvm\v12.13.0\node translate.js extractall \ No newline at end of file diff --git a/translate/translate-node14.bat b/translate/translate-node14.bat new file mode 100644 index 00000000..7bff1afb --- /dev/null +++ b/translate/translate-node14.bat @@ -0,0 +1,4 @@ +@ECHO OFF +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node translate.js minifyall +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node translate.js translateall +%LOCALAPPDATA%\..\Roaming\nvm\v14.16.0\node translate.js extractall \ No newline at end of file diff --git a/translate/translate.json b/translate/translate.json index b5eaea62..2190ef49 100644 --- a/translate/translate.json +++ b/translate/translate.json @@ -46,8 +46,8 @@ "zh-chs": " + CIRA", "zh-cht": " + CIRA", "xloc": [ - "default.handlebars->41->1899", - "default.handlebars->41->1901" + "default.handlebars->45->1914", + "default.handlebars->45->1916" ] }, { @@ -73,7 +73,7 @@ "zh-cht": " - 1天后重設。", "xloc": [ "default-mobile.handlebars->11->57", - "default.handlebars->41->76" + "default.handlebars->45->76" ] }, { @@ -99,7 +99,7 @@ "zh-cht": " - 1小時後重設。", "xloc": [ "default-mobile.handlebars->11->55", - "default.handlebars->41->74" + "default.handlebars->45->74" ] }, { @@ -125,7 +125,7 @@ "zh-cht": " - 1分鐘後重設。", "xloc": [ "default-mobile.handlebars->11->53", - "default.handlebars->41->72" + "default.handlebars->45->72" ] }, { @@ -151,7 +151,7 @@ "zh-cht": " - 在{0}天內重置。", "xloc": [ "default-mobile.handlebars->11->58", - "default.handlebars->41->77" + "default.handlebars->45->77" ] }, { @@ -177,7 +177,7 @@ "zh-cht": " - 在{0}小時內重置。", "xloc": [ "default-mobile.handlebars->11->56", - "default.handlebars->41->75" + "default.handlebars->45->75" ] }, { @@ -203,7 +203,7 @@ "zh-cht": " - 在{0}分鐘內重置。", "xloc": [ "default-mobile.handlebars->11->54", - "default.handlebars->41->73" + "default.handlebars->45->73" ] }, { @@ -230,8 +230,8 @@ "xloc": [ "default-mobile.handlebars->11->51", "default-mobile.handlebars->11->52", - "default.handlebars->41->70", - "default.handlebars->41->71" + "default.handlebars->45->70", + "default.handlebars->45->71" ] }, { @@ -299,7 +299,7 @@ "zh-chs": " 可以使用密码提示,但不建议使用。", "zh-cht": " 可以使用密碼提示,但不建議使用。", "xloc": [ - "default.handlebars->41->1778" + "default.handlebars->45->1793" ] }, { @@ -324,8 +324,8 @@ "zh-chs": " 用户需要先登录到该服务器一次,然后才能将其添加到设备组。", "zh-cht": " 用戶需要先登入到該伺服器一次,然後才能將其新增到裝置群。", "xloc": [ - "default.handlebars->41->2019", - "default.handlebars->41->2574" + "default.handlebars->45->2034", + "default.handlebars->45->2589" ] }, { @@ -444,7 +444,7 @@ "zh-chs": " TLS。", "zh-cht": " TLS。", "xloc": [ - "default.handlebars->41->253" + "default.handlebars->45->254" ] }, { @@ -469,7 +469,7 @@ "zh-chs": " 没有TLS。", "zh-cht": " 沒有TLS。", "xloc": [ - "default.handlebars->41->254" + "default.handlebars->45->255" ] }, { @@ -789,7 +789,7 @@ "zh-chs": "(可选的)", "zh-cht": "(可選的)", "xloc": [ - "default.handlebars->41->512" + "default.handlebars->45->515" ] }, { @@ -834,8 +834,8 @@ "zh-chs": "* 8个字符,1个大写,1个小写,1个数字,1个非字母数字。", "zh-cht": "* 8個字符,1個大寫,1個小寫,1個數字,1個非字母數字。", "xloc": [ - "default.handlebars->41->1979", - "default.handlebars->41->474" + "default.handlebars->45->1994", + "default.handlebars->45->477" ] }, { @@ -860,7 +860,7 @@ "zh-chs": "*对于BSD,首先运行“ pkg install wget sudo bash ”。", "zh-cht": "*對於BSD,首先運行“ pkg install wget sudo bash ”。", "xloc": [ - "default.handlebars->41->565" + "default.handlebars->45->568" ] }, { @@ -928,10 +928,14 @@ "zh-chs": ",", "zh-cht": ",", "xloc": [ + "default-mobile.handlebars->11->558", + "default-mobile.handlebars->11->560", "default-mobile.handlebars->11->700", - "default.handlebars->41->2093", - "default.handlebars->41->2357", - "default.handlebars->41->892" + "default.handlebars->45->1455", + "default.handlebars->45->1457", + "default.handlebars->45->2108", + "default.handlebars->45->2372", + "default.handlebars->45->900" ] }, { @@ -998,7 +1002,7 @@ "zh-cht": ",只適用於Intel®AMT", "xloc": [ "default-mobile.handlebars->11->186", - "default.handlebars->41->330" + "default.handlebars->45->331" ] }, { @@ -1022,7 +1026,7 @@ "tr": ", Yerel Cihazlar", "zh-chs": ", 本地设备", "xloc": [ - "default.handlebars->41->332" + "default.handlebars->45->333" ] }, { @@ -1048,7 +1052,7 @@ "zh-cht": ",MQTT在線", "xloc": [ "default-mobile.handlebars->11->604", - "default.handlebars->41->1487" + "default.handlebars->45->1502" ] }, { @@ -1072,8 +1076,8 @@ "tr": ", İzin Yok", "zh-chs": ", 不同意", "xloc": [ - "default.handlebars->41->1937", - "default.handlebars->41->977" + "default.handlebars->45->1952", + "default.handlebars->45->991" ] }, { @@ -1098,8 +1102,8 @@ "zh-chs": ",提示同意", "zh-cht": ",提示同意", "xloc": [ - "default.handlebars->41->1938", - "default.handlebars->41->978" + "default.handlebars->45->1953", + "default.handlebars->45->992" ] }, { @@ -1107,8 +1111,9 @@ "nl": ", RDP", "pl": ", RDP", "ru": ", RDP", + "fr": ", RDP", "xloc": [ - "default.handlebars->41->1229" + "default.handlebars->45->1244" ] }, { @@ -1128,8 +1133,8 @@ "ru": ", Ежедневно", "tr": ", Günlük yinelenen", "xloc": [ - "default.handlebars->41->1934", - "default.handlebars->41->974" + "default.handlebars->45->1949", + "default.handlebars->45->988" ] }, { @@ -1149,8 +1154,8 @@ "ru": ", Еженедельно", "tr": ", Haftalık yinelenen", "xloc": [ - "default.handlebars->41->1935", - "default.handlebars->41->975" + "default.handlebars->45->1950", + "default.handlebars->45->989" ] }, { @@ -1179,8 +1184,9 @@ "nl": ", Doorgestuurde apparaten", "pl": ", Urządzenia Przekierowane", "ru": ", Ретранслируемые устройства", + "fr": ", Appareils relayés", "xloc": [ - "default.handlebars->41->331" + "default.handlebars->45->332" ] }, { @@ -1188,9 +1194,10 @@ "nl": ", SFTP", "pl": ", SFTP", "ru": ", SFTP", + "fr": ", SFTP", "xloc": [ "default-mobile.handlebars->11->468", - "default.handlebars->41->1337" + "default.handlebars->45->1352" ] }, { @@ -1198,8 +1205,9 @@ "nl": ", SSH", "pl": ", SSH", "ru": ", SSH", + "fr": ", SSH", "xloc": [ - "default.handlebars->41->1305" + "default.handlebars->45->1320" ] }, { @@ -1224,7 +1232,7 @@ "zh-chs": ",软体KVM", "zh-cht": ",軟體KVM", "xloc": [ - "default.handlebars->41->1212", + "default.handlebars->45->1227", "sharing.handlebars->11->12" ] }, @@ -1249,8 +1257,8 @@ "tr": ", Araç Çubuğu", "zh-chs": ", 工具栏", "xloc": [ - "default.handlebars->41->1939", - "default.handlebars->41->979" + "default.handlebars->45->1954", + "default.handlebars->45->993" ] }, { @@ -1291,8 +1299,8 @@ "ru": ", Только просмотр рабочего стола", "tr": ", Yalnızca masaüstünü görüntüle", "xloc": [ - "default.handlebars->41->1936", - "default.handlebars->41->976" + "default.handlebars->45->1951", + "default.handlebars->45->990" ] }, { @@ -1320,9 +1328,9 @@ "default-mobile.handlebars->11->411", "default-mobile.handlebars->11->446", "default-mobile.handlebars->11->469", - "default.handlebars->41->1228", - "default.handlebars->41->1306", - "default.handlebars->41->1338", + "default.handlebars->45->1243", + "default.handlebars->45->1321", + "default.handlebars->45->1353", "sharing.handlebars->11->19", "sharing.handlebars->11->27", "sharing.handlebars->11->44", @@ -1518,7 +1526,7 @@ "zh-chs": ",{0}观看", "zh-cht": ",{0}觀看", "xloc": [ - "default.handlebars->41->1223", + "default.handlebars->45->1238", "sharing.handlebars->11->13" ] }, @@ -1539,6 +1547,7 @@ "pt-br": "-", "ru": "-", "xloc": [ + "default.handlebars->container->column_l->p14->p14title->5", "default.handlebars->container->column_l->p2->p2info->p2createMeshLink1", "ssh.handlebars->p11->deskarea0->deskarea1->3", "xterm.handlebars->p11->deskarea0->deskarea1->3" @@ -1624,9 +1633,9 @@ "xloc": [ "default-mobile.handlebars->11->139", "default-mobile.handlebars->11->475", - "default.handlebars->41->1348", - "default.handlebars->41->2154", - "default.handlebars->41->2772", + "default.handlebars->45->1363", + "default.handlebars->45->2169", + "default.handlebars->45->2787", "sharing.handlebars->11->50" ] }, @@ -1788,7 +1797,7 @@ "zh-chs": "1个活跃时段", "zh-cht": "1個活躍時段", "xloc": [ - "default.handlebars->41->2662" + "default.handlebars->45->2677" ] }, { @@ -1815,7 +1824,7 @@ "xloc": [ "default-mobile.handlebars->11->149", "default-mobile.handlebars->11->744", - "default.handlebars->41->2178", + "default.handlebars->45->2193", "download.handlebars->3->1", "download2.handlebars->5->1", "sharing.handlebars->11->96" @@ -1854,7 +1863,7 @@ "zh-chs": "1条连接", "zh-cht": "1位聯絡文", "xloc": [ - "default.handlebars->41->1225", + "default.handlebars->45->1240", "sharing.handlebars->11->15" ] }, @@ -1880,9 +1889,9 @@ "zh-chs": "1天", "zh-cht": "1天", "xloc": [ - "default.handlebars->41->261", - "default.handlebars->41->503", - "default.handlebars->41->517" + "default.handlebars->45->262", + "default.handlebars->45->506", + "default.handlebars->45->520" ] }, { @@ -1907,7 +1916,7 @@ "zh-chs": "1组", "zh-cht": "1群", "xloc": [ - "default.handlebars->41->2621" + "default.handlebars->45->2636" ] }, { @@ -1932,9 +1941,9 @@ "zh-chs": "1小时", "zh-cht": "1小時", "xloc": [ - "default.handlebars->41->259", - "default.handlebars->41->501", - "default.handlebars->41->515" + "default.handlebars->45->260", + "default.handlebars->45->504", + "default.handlebars->45->518" ] }, { @@ -1959,8 +1968,8 @@ "zh-chs": "1分钟", "zh-cht": "1分鐘", "xloc": [ - "default.handlebars->41->1057", - "default.handlebars->41->1743" + "default.handlebars->45->1072", + "default.handlebars->45->1758" ] }, { @@ -1985,7 +1994,7 @@ "zh-chs": "1分钟之后断开连接", "zh-cht": "1分鐘之後離線", "xloc": [ - "default.handlebars->41->80" + "default.handlebars->45->80" ] }, { @@ -2010,9 +2019,9 @@ "zh-chs": "1个月", "zh-cht": "1個月", "xloc": [ - "default.handlebars->41->263", - "default.handlebars->41->505", - "default.handlebars->41->519" + "default.handlebars->45->264", + "default.handlebars->45->508", + "default.handlebars->45->522" ] }, { @@ -2037,7 +2046,7 @@ "zh-chs": "有1个用户没有显示,请使用搜索框查找用户...", "zh-cht": "有1個用戶沒有顯示,請使用搜尋框搜尋用戶...", "xloc": [ - "default.handlebars->41->2389" + "default.handlebars->45->2404" ] }, { @@ -2062,7 +2071,7 @@ "zh-chs": "1个节点", "zh-cht": "1個節點", "xloc": [ - "default.handlebars->41->597" + "default.handlebars->45->600" ] }, { @@ -2129,7 +2138,7 @@ "zh-chs": "1秒", "xloc": [ "default-mobile.handlebars->11->361", - "default.handlebars->41->1092" + "default.handlebars->45->1107" ] }, { @@ -2154,7 +2163,7 @@ "zh-chs": "1秒之后断开连接", "zh-cht": "1秒之後離線", "xloc": [ - "default.handlebars->41->78" + "default.handlebars->45->78" ] }, { @@ -2178,7 +2187,7 @@ "tr": "1 seçili cihaz çevrimdışı.", "zh-chs": "1 个选定的设备处于离线状态。", "xloc": [ - "default.handlebars->41->663" + "default.handlebars->45->666" ] }, { @@ -2202,7 +2211,7 @@ "tr": "1 seçili cihaz çevrimiçi.", "zh-chs": "1 个选定的设备在线。", "xloc": [ - "default.handlebars->41->661" + "default.handlebars->45->664" ] }, { @@ -2234,14 +2243,14 @@ "default-mobile.handlebars->11->218", "default-mobile.handlebars->11->222", "default-mobile.handlebars->11->226", - "default.handlebars->41->2393", - "default.handlebars->41->399", - "default.handlebars->41->402", - "default.handlebars->41->406", - "default.handlebars->41->410", - "default.handlebars->41->414", - "default.handlebars->41->418", - "default.handlebars->41->422" + "default.handlebars->45->2408", + "default.handlebars->45->402", + "default.handlebars->45->405", + "default.handlebars->45->409", + "default.handlebars->45->413", + "default.handlebars->45->417", + "default.handlebars->45->421", + "default.handlebars->45->425" ] }, { @@ -2266,9 +2275,9 @@ "zh-chs": "1周", "zh-cht": "1週", "xloc": [ - "default.handlebars->41->262", - "default.handlebars->41->504", - "default.handlebars->41->518" + "default.handlebars->45->263", + "default.handlebars->45->507", + "default.handlebars->45->521" ] }, { @@ -2421,8 +2430,8 @@ "zh-chs": "10分钟", "zh-cht": "10分鐘", "xloc": [ - "default.handlebars->41->1059", - "default.handlebars->41->1745" + "default.handlebars->45->1074", + "default.handlebars->45->1760" ] }, { @@ -2447,7 +2456,7 @@ "zh-chs": "10 秒", "xloc": [ "default-mobile.handlebars->11->363", - "default.handlebars->41->1094" + "default.handlebars->45->1109" ] }, { @@ -2615,8 +2624,8 @@ "zh-chs": "12小时", "zh-cht": "12小時", "xloc": [ - "default.handlebars->41->1067", - "default.handlebars->41->1753" + "default.handlebars->45->1082", + "default.handlebars->45->1768" ] }, { @@ -2769,8 +2778,8 @@ "zh-chs": "15分钟", "zh-cht": "15分鐘", "xloc": [ - "default.handlebars->41->1060", - "default.handlebars->41->1746" + "default.handlebars->45->1075", + "default.handlebars->45->1761" ] }, { @@ -2795,8 +2804,8 @@ "zh-chs": "16小时", "zh-cht": "16小時", "xloc": [ - "default.handlebars->41->1068", - "default.handlebars->41->1754" + "default.handlebars->45->1083", + "default.handlebars->45->1769" ] }, { @@ -2952,8 +2961,8 @@ "zh-chs": "2天", "zh-cht": "2天", "xloc": [ - "default.handlebars->41->1070", - "default.handlebars->41->1756" + "default.handlebars->45->1085", + "default.handlebars->45->1771" ] }, { @@ -2978,8 +2987,8 @@ "zh-chs": "2小时", "zh-cht": "2小時", "xloc": [ - "default.handlebars->41->1064", - "default.handlebars->41->1750" + "default.handlebars->45->1079", + "default.handlebars->45->1765" ] }, { @@ -3004,7 +3013,7 @@ "zh-chs": "两步登录激活失败。", "zh-cht": "兩步登入啟用失敗。", "xloc": [ - "default.handlebars->41->207" + "default.handlebars->45->208" ] }, { @@ -3029,7 +3038,7 @@ "zh-chs": "两步登录激活删除失败。", "zh-cht": "兩步登入啟用刪除失敗。", "xloc": [ - "default.handlebars->41->212" + "default.handlebars->45->213" ] }, { @@ -3157,8 +3166,8 @@ "zh-chs": "24小时", "zh-cht": "24小時", "xloc": [ - "default.handlebars->41->1069", - "default.handlebars->41->1755" + "default.handlebars->45->1084", + "default.handlebars->45->1770" ] }, { @@ -3232,7 +3241,7 @@ "zh-chs": "2FA备份代码已清除", "zh-cht": "2FA備份代碼已清除", "xloc": [ - "default.handlebars->41->2289" + "default.handlebars->45->2304" ] }, { @@ -3240,9 +3249,10 @@ "nl": "2FA is vergrendeld", "pl": "2FA jest zablokowane", "ru": "2FA заблокирована", + "fr": "2FA est bloqué", "xloc": [ "default-mobile.handlebars->11->60", - "default.handlebars->41->194" + "default.handlebars->45->195" ] }, { @@ -3251,8 +3261,9 @@ "pl": "dwuetapowe", "pt-br": "2ª Etapa", "ru": "2-oй фактор", + "fr": "Second facteur", "xloc": [ - "default.handlebars->41->2808" + "default.handlebars->45->2823" ] }, { @@ -3277,8 +3288,8 @@ "zh-chs": "启用第二因素身份验证", "zh-cht": "啟用第二因素身份驗證", "xloc": [ - "default.handlebars->41->2407", - "default.handlebars->41->2645" + "default.handlebars->45->2422", + "default.handlebars->45->2660" ] }, { @@ -3427,8 +3438,8 @@ "zh-chs": "30分钟", "zh-cht": "30分鐘", "xloc": [ - "default.handlebars->41->1061", - "default.handlebars->41->1747" + "default.handlebars->45->1076", + "default.handlebars->45->1762" ] }, { @@ -3453,7 +3464,7 @@ "zh-chs": "32 位", "xloc": [ "default-mobile.handlebars->11->512", - "default.handlebars->41->1401" + "default.handlebars->45->1416" ] }, { @@ -3478,8 +3489,8 @@ "zh-chs": "MeshAgent的32位版本", "zh-cht": "MeshAgent的32位版本", "xloc": [ - "default.handlebars->41->555", - "default.handlebars->41->583" + "default.handlebars->45->558", + "default.handlebars->45->586" ] }, { @@ -3531,8 +3542,8 @@ "zh-chs": "4天", "zh-cht": "4天", "xloc": [ - "default.handlebars->41->1071", - "default.handlebars->41->1757" + "default.handlebars->45->1086", + "default.handlebars->45->1772" ] }, { @@ -3557,8 +3568,8 @@ "zh-chs": "4个小时", "zh-cht": "4個小時", "xloc": [ - "default.handlebars->41->1065", - "default.handlebars->41->1751" + "default.handlebars->45->1080", + "default.handlebars->45->1766" ] }, { @@ -3686,8 +3697,8 @@ "zh-chs": "45分钟", "zh-cht": "45分鐘", "xloc": [ - "default.handlebars->41->1062", - "default.handlebars->41->1748" + "default.handlebars->45->1077", + "default.handlebars->45->1763" ] }, { @@ -3737,8 +3748,8 @@ "zh-chs": "5分钟", "zh-cht": "5分鐘", "xloc": [ - "default.handlebars->41->1058", - "default.handlebars->41->1744" + "default.handlebars->45->1073", + "default.handlebars->45->1759" ] }, { @@ -3763,7 +3774,7 @@ "zh-chs": "5秒", "xloc": [ "default-mobile.handlebars->11->362", - "default.handlebars->41->1093" + "default.handlebars->45->1108" ] }, { @@ -3919,8 +3930,8 @@ "zh-chs": "60分钟", "zh-cht": "60分鐘", "xloc": [ - "default.handlebars->41->1063", - "default.handlebars->41->1749" + "default.handlebars->45->1078", + "default.handlebars->45->1764" ] }, { @@ -3997,7 +4008,7 @@ "zh-chs": "64 位", "xloc": [ "default-mobile.handlebars->11->514", - "default.handlebars->41->1403" + "default.handlebars->45->1418" ] }, { @@ -4062,7 +4073,7 @@ "zh-chs": "64位版本的macOS Mesh Agent", "zh-cht": "64位版本的macOS Mesh Agent", "xloc": [ - "default.handlebars->41->570" + "default.handlebars->45->573" ] }, { @@ -4087,8 +4098,8 @@ "zh-chs": "MeshAgent的64位版本", "zh-cht": "MeshAgent的64位版本", "xloc": [ - "default.handlebars->41->559", - "default.handlebars->41->586" + "default.handlebars->45->562", + "default.handlebars->45->589" ] }, { @@ -4157,7 +4168,7 @@ "zh-chs": "7天电源状态", "zh-cht": "7天電源狀態", "xloc": [ - "default.handlebars->41->1127" + "default.handlebars->45->1142" ] }, { @@ -4166,8 +4177,9 @@ "pl": "7 dni", "pt-br": "7 dias", "ru": "7 дней", + "fr": "7 jours", "xloc": [ - "default.handlebars->41->1758" + "default.handlebars->45->1773" ] }, { @@ -4245,10 +4257,10 @@ "zh-chs": "8小時", "zh-cht": "8小時", "xloc": [ - "default.handlebars->41->1066", - "default.handlebars->41->1752", - "default.handlebars->41->502", - "default.handlebars->41->516" + "default.handlebars->45->1081", + "default.handlebars->45->1767", + "default.handlebars->45->505", + "default.handlebars->45->519" ] }, { @@ -4401,7 +4413,7 @@ "zh-chs": "硬件密钥用作辅助登录身份验证。", "zh-cht": "硬件密鑰用作輔助登入身份驗證。", "xloc": [ - "default.handlebars->41->221" + "default.handlebars->45->222" ] }, { @@ -4573,8 +4585,8 @@ "zh-cht": "ACM", "xloc": [ "default-mobile.handlebars->11->297", - "default.handlebars->41->1917", - "default.handlebars->41->810" + "default.handlebars->45->1932", + "default.handlebars->45->818" ] }, { @@ -4643,8 +4655,8 @@ "zh-chs": "AMT", "zh-cht": "AMT", "xloc": [ - "default.handlebars->41->380", - "default.handlebars->41->632" + "default.handlebars->45->381", + "default.handlebars->45->635" ] }, { @@ -4668,7 +4680,7 @@ "tr": "AMT-OS", "zh-chs": "操作系统", "xloc": [ - "default.handlebars->41->2930" + "default.handlebars->45->2945" ] }, { @@ -4687,7 +4699,7 @@ "ru": "AMT-Redir", "tr": "AMT-Yönlendirme", "xloc": [ - "default.handlebars->41->2815" + "default.handlebars->45->2830" ] }, { @@ -4706,7 +4718,7 @@ "ru": "AMT-WSMAN", "tr": "AMT-WSMAN", "xloc": [ - "default.handlebars->41->2814" + "default.handlebars->45->2829" ] }, { @@ -4732,7 +4744,7 @@ "zh-cht": "ARM-Linaro", "xloc": [ "default-mobile.handlebars->11->30", - "default.handlebars->41->37" + "default.handlebars->45->37" ] }, { @@ -4758,7 +4770,7 @@ "zh-cht": "ARMADA/CORTEX-A53/MUSL (OpenWRT)", "xloc": [ "default-mobile.handlebars->11->47", - "default.handlebars->41->54" + "default.handlebars->45->54" ] }, { @@ -4784,7 +4796,7 @@ "zh-cht": "ARMv6l / ARMv7l", "xloc": [ "default-mobile.handlebars->11->31", - "default.handlebars->41->38" + "default.handlebars->45->38" ] }, { @@ -4810,7 +4822,7 @@ "zh-cht": "ARMv6l / ARMv7l / NoKVM", "xloc": [ "default-mobile.handlebars->11->33", - "default.handlebars->41->40" + "default.handlebars->45->40" ] }, { @@ -4836,7 +4848,7 @@ "zh-cht": "ARMv8 64位", "xloc": [ "default-mobile.handlebars->11->32", - "default.handlebars->41->39" + "default.handlebars->45->39" ] }, { @@ -4862,8 +4874,8 @@ "xloc": [ "default-mobile.handlebars->11->516", "default-mobile.handlebars->11->518", - "default.handlebars->41->829", - "default.handlebars->41->831" + "default.handlebars->45->837", + "default.handlebars->45->839" ] }, { @@ -4889,7 +4901,7 @@ "zh-cht": "拒絕存取", "xloc": [ "default-mobile.handlebars->11->605", - "default.handlebars->41->1488" + "default.handlebars->45->1503" ] }, { @@ -4965,7 +4977,7 @@ "zh-chs": "访问服务器档案", "zh-cht": "存取伺服器檔案", "xloc": [ - "default.handlebars->41->2580" + "default.handlebars->45->2595" ] }, { @@ -5074,11 +5086,11 @@ "default-mobile.handlebars->11->264", "default-mobile.handlebars->11->266", "default-mobile.handlebars->container->page_content->column_l->p3->p3info->3->p3AccountActions->p2AccountSecurity->1->0", - "default.handlebars->41->1787", - "default.handlebars->41->1789", - "default.handlebars->41->2983", - "default.handlebars->41->770", - "default.handlebars->41->772" + "default.handlebars->45->1802", + "default.handlebars->45->1804", + "default.handlebars->45->2998", + "default.handlebars->45->778", + "default.handlebars->45->780" ] }, { @@ -5103,7 +5115,7 @@ "zh-chs": "帐号设定", "xloc": [ "default-mobile.handlebars->11->711", - "default.handlebars->41->2859" + "default.handlebars->45->2874" ] }, { @@ -5179,7 +5191,7 @@ "zh-chs": "帐户已更改:{0}", "zh-cht": "帳戶已更改:{0}", "xloc": [ - "default.handlebars->41->2262" + "default.handlebars->45->2277" ] }, { @@ -5204,7 +5216,7 @@ "zh-chs": "创建帐户,电子邮件为{0}", "zh-cht": "創建帳戶,電子郵件為{0}", "xloc": [ - "default.handlebars->41->2261" + "default.handlebars->45->2276" ] }, { @@ -5224,7 +5236,7 @@ "ru": "Аккаунт создан, имя {0}.", "tr": "Hesap oluşturuldu, ad {0}.", "xloc": [ - "default.handlebars->41->2324" + "default.handlebars->45->2339" ] }, { @@ -5249,7 +5261,7 @@ "zh-chs": "创建帐户,用户名是{0}", "zh-cht": "帳戶已創建,用戶名是{0}", "xloc": [ - "default.handlebars->41->2260" + "default.handlebars->45->2275" ] }, { @@ -5275,9 +5287,9 @@ "zh-cht": "帳戶已被鎖定", "xloc": [ "default-mobile.handlebars->11->64", - "default.handlebars->41->198", - "default.handlebars->41->2409", - "default.handlebars->41->2577" + "default.handlebars->45->199", + "default.handlebars->45->2424", + "default.handlebars->45->2592" ] }, { @@ -5303,7 +5315,7 @@ "zh-cht": "達到帳戶限制。", "xloc": [ "default-mobile.handlebars->11->723", - "default.handlebars->41->2871", + "default.handlebars->45->2886", "login-mobile.handlebars->5->6", "login.handlebars->5->6", "login2.handlebars->7->8" @@ -5358,7 +5370,7 @@ "zh-chs": "帐号登录", "zh-cht": "帳號登錄", "xloc": [ - "default.handlebars->41->2197" + "default.handlebars->45->2212" ] }, { @@ -5382,7 +5394,7 @@ "tr": "{0}, {1}, {2} adresinden hesap girişi", "zh-chs": "来自 {0}、{1}、{2} 的帐户登录", "xloc": [ - "default.handlebars->41->2303" + "default.handlebars->45->2318" ] }, { @@ -5407,7 +5419,7 @@ "zh-chs": "帐户登出", "zh-cht": "帳戶登出", "xloc": [ - "default.handlebars->41->2198" + "default.handlebars->45->2213" ] }, { @@ -5459,7 +5471,7 @@ "zh-chs": "帐户密码已更改:{0}", "zh-cht": "帳戶密碼已更改:{0}", "xloc": [ - "default.handlebars->41->2270" + "default.handlebars->45->2285" ] }, { @@ -5484,7 +5496,7 @@ "zh-chs": "帐户已删除", "zh-cht": "帳戶已刪除", "xloc": [ - "default.handlebars->41->2259" + "default.handlebars->45->2274" ] }, { @@ -5535,7 +5547,7 @@ "zh-cht": "指令", "xloc": [ "default-mobile.handlebars->11->611", - "default.handlebars->41->1494", + "default.handlebars->45->1509", "default.handlebars->container->column_l->p42->p42tbl->1->0->8" ] }, @@ -5561,8 +5573,8 @@ "zh-chs": "动作档案", "zh-cht": "動作檔案", "xloc": [ - "default.handlebars->41->1173", - "default.handlebars->41->1175" + "default.handlebars->45->1188", + "default.handlebars->45->1190" ] }, { @@ -5591,7 +5603,7 @@ "default-mobile.handlebars->container->page_content->column_l->p10->p10desktop->deskarea4->1->3", "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->0->1->1", "default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea4->1->3", - "default.handlebars->41->893", + "default.handlebars->45->901", "default.handlebars->container->column_l->p11->deskarea0->deskarea1->1", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->1", "default.handlebars->container->column_l->p13->p13toolbar->1->0->1->1" @@ -5619,7 +5631,7 @@ "zh-chs": "使用FAT格式的USB密钥在管理控制模式(ACM)中激活英特尔®AMT。将setup.bin放在其上,然后使用此键引导一台或多台计算机。", "zh-cht": "使用FAT格式的USB密鑰在管理控制模式(ACM)中激活英特爾®AMT。將setup.bin放在其上,然後使用此鍵引導一台或多台計算機。", "xloc": [ - "default.handlebars->41->468" + "default.handlebars->45->471" ] }, { @@ -5694,7 +5706,7 @@ "zh-chs": "如果ACM失败,则激活到CCM", "zh-cht": "如果ACM失敗,則激活到CCM", "xloc": [ - "default.handlebars->41->1970" + "default.handlebars->45->1985" ] }, { @@ -5721,10 +5733,10 @@ "xloc": [ "default-mobile.handlebars->11->292", "default-mobile.handlebars->11->294", - "default-mobile.handlebars->11->567", - "default.handlebars->41->1449", - "default.handlebars->41->803", - "default.handlebars->41->805" + "default-mobile.handlebars->11->566", + "default.handlebars->45->1463", + "default.handlebars->45->811", + "default.handlebars->45->813" ] }, { @@ -5749,7 +5761,7 @@ "zh-chs": "激活", "zh-cht": "啟動", "xloc": [ - "default.handlebars->41->301" + "default.handlebars->45->302" ] }, { @@ -5774,8 +5786,8 @@ "zh-chs": "主动设备共享", "zh-cht": "主動設備共享", "xloc": [ - "default.handlebars->41->1921", - "default.handlebars->41->961" + "default.handlebars->45->1936", + "default.handlebars->45->975" ] }, { @@ -5799,7 +5811,7 @@ "tr": "Aktif Giriş Anahtarları", "zh-chs": "活动登录令牌", "xloc": [ - "default.handlebars->41->1818" + "default.handlebars->45->1833" ] }, { @@ -5819,7 +5831,7 @@ "ru": "Активный пользователь", "tr": "Aktif Kullanıcı", "xloc": [ - "default.handlebars->41->847" + "default.handlebars->45->855" ] }, { @@ -5839,7 +5851,7 @@ "ru": "Активные пользователи", "tr": "Aktif Kullanıcılar", "xloc": [ - "default.handlebars->41->846" + "default.handlebars->45->854" ] }, { @@ -5886,8 +5898,8 @@ "zh-chs": "添加", "xloc": [ "default-mobile.handlebars->11->438", - "default.handlebars->41->1260", - "default.handlebars->41->1265" + "default.handlebars->45->1275", + "default.handlebars->45->1280" ] }, { @@ -5914,7 +5926,7 @@ { "cs": "Přidat a znovu odeslat mapu ...", "da": "Tilføj &Relay Map...", - "de": "&Relay-Karte hinzufügen...", + "de": "&Relay-Zuordnung hinzufügen...", "en": "Add &Relay Map...", "es": "Agregar y retransmitir mapa ...", "fi": "Lisää ja välitä kartta ...", @@ -5954,8 +5966,8 @@ "zh-chs": "添加代理", "zh-cht": "新增代理", "xloc": [ - "default.handlebars->41->1911", - "default.handlebars->41->440" + "default.handlebars->45->1926", + "default.handlebars->45->443" ] }, { @@ -6002,10 +6014,10 @@ "zh-chs": "添加设备", "zh-cht": "新增裝置", "xloc": [ - "default.handlebars->41->1915", - "default.handlebars->41->2552", - "default.handlebars->41->2711", - "default.handlebars->41->444" + "default.handlebars->45->1930", + "default.handlebars->45->2567", + "default.handlebars->45->2726", + "default.handlebars->45->447" ] }, { @@ -6030,7 +6042,7 @@ "zh-chs": "添加设备日志", "zh-cht": "新增裝置日誌", "xloc": [ - "default.handlebars->41->1034" + "default.handlebars->45->1048" ] }, { @@ -6055,10 +6067,10 @@ "zh-chs": "添加设备组", "zh-cht": "新增裝置群", "xloc": [ - "default.handlebars->41->2055", - "default.handlebars->41->2546", - "default.handlebars->41->2699", - "default.handlebars->41->356" + "default.handlebars->45->2070", + "default.handlebars->45->2561", + "default.handlebars->45->2714", + "default.handlebars->45->357" ] }, { @@ -6083,7 +6095,7 @@ "zh-chs": "添加设备组权限", "zh-cht": "新增裝置群權限", "xloc": [ - "default.handlebars->41->2052" + "default.handlebars->45->2067" ] }, { @@ -6108,8 +6120,8 @@ "zh-chs": "添加设备权限", "zh-cht": "新增裝置權限", "xloc": [ - "default.handlebars->41->2057", - "default.handlebars->41->2059" + "default.handlebars->45->2072", + "default.handlebars->45->2074" ] }, { @@ -6156,7 +6168,7 @@ "zh-chs": "添加英特尔®AMT设备", "zh-cht": "新增Intel® AMT裝置", "xloc": [ - "default.handlebars->41->464" + "default.handlebars->45->467" ] }, { @@ -6181,7 +6193,7 @@ "zh-chs": "新增密钥", "zh-cht": "新增密鑰", "xloc": [ - "default.handlebars->41->225" + "default.handlebars->45->226" ] }, { @@ -6206,13 +6218,13 @@ "zh-chs": "添加本地", "zh-cht": "新增本地", "xloc": [ - "default.handlebars->41->434" + "default.handlebars->45->437" ] }, { "cs": "Přidat mapu ...", "da": "Tilføj kort...", - "de": "Karte hinzufügen...", + "de": "Zuordnung hinzufügen...", "en": "Add Map...", "es": "Agregar mapa ...", "fi": "Lisää kartta ...", @@ -6252,7 +6264,7 @@ "zh-chs": "添加成员身份", "zh-cht": "新增成員身份", "xloc": [ - "default.handlebars->41->2731" + "default.handlebars->45->2746" ] }, { @@ -6277,13 +6289,13 @@ "zh-chs": "添加 Mesh Agent", "zh-cht": "新增 Mesh Agent", "xloc": [ - "default.handlebars->41->596" + "default.handlebars->45->599" ] }, { "cs": "Přidat mapu relé ...", "da": "Tilføj Relay kort", - "de": "Relaiskarte hinzufügen...", + "de": "Relay-Zuordnung hinzufügen...", "en": "Add Relay Map...", "es": "Agregar mapa de retransmisiones ...", "fi": "Lisää välityskartta ...", @@ -6323,12 +6335,12 @@ "zh-chs": "添加安全密钥", "zh-cht": "新增安全密鑰", "xloc": [ - "default.handlebars->41->1533", - "default.handlebars->41->1534", - "default.handlebars->41->229", - "default.handlebars->41->231", - "default.handlebars->41->234", - "default.handlebars->41->236" + "default.handlebars->45->1548", + "default.handlebars->45->1549", + "default.handlebars->45->230", + "default.handlebars->45->232", + "default.handlebars->45->235", + "default.handlebars->45->237" ] }, { @@ -6354,7 +6366,7 @@ "zh-cht": "新增用戶", "xloc": [ "default-mobile.handlebars->11->636", - "default.handlebars->41->953" + "default.handlebars->45->967" ] }, { @@ -6379,7 +6391,7 @@ "zh-chs": "添加用户设备权限", "zh-cht": "新增用戶裝置權限", "xloc": [ - "default.handlebars->41->2062" + "default.handlebars->45->2077" ] }, { @@ -6404,10 +6416,10 @@ "zh-chs": "添加用户组", "zh-cht": "新增用戶群", "xloc": [ - "default.handlebars->41->1907", - "default.handlebars->41->2054", - "default.handlebars->41->2705", - "default.handlebars->41->954" + "default.handlebars->45->1922", + "default.handlebars->45->2069", + "default.handlebars->45->2720", + "default.handlebars->45->968" ] }, { @@ -6432,7 +6444,7 @@ "zh-chs": "添加用户组设备权限", "zh-cht": "新增用戶群裝置權限", "xloc": [ - "default.handlebars->41->2064" + "default.handlebars->45->2079" ] }, { @@ -6504,8 +6516,8 @@ "zh-chs": "添加用户", "zh-cht": "新增用戶", "xloc": [ - "default.handlebars->41->1906", - "default.handlebars->41->2541" + "default.handlebars->45->1921", + "default.handlebars->45->2556" ] }, { @@ -6530,7 +6542,7 @@ "zh-chs": "将用户添加到设备组", "zh-cht": "將用戶新增到裝置群", "xloc": [ - "default.handlebars->41->2051" + "default.handlebars->45->2066" ] }, { @@ -6555,7 +6567,7 @@ "zh-chs": "将用户添加到用户组", "zh-cht": "將用戶新增到用戶群", "xloc": [ - "default.handlebars->41->2576" + "default.handlebars->45->2591" ] }, { @@ -6580,7 +6592,7 @@ "zh-chs": "添加YubiKey®OTP", "zh-cht": "新增YubiKey®OTP", "xloc": [ - "default.handlebars->41->226" + "default.handlebars->45->227" ] }, { @@ -6604,7 +6616,7 @@ "tr": "\\\"{0}\\\" cihaz grubuna yerel bir cihaz ekleyin.", "zh-chs": "将本地设备添加到设备组 \\\"{0}\\\"。", "xloc": [ - "default.handlebars->41->445" + "default.handlebars->45->448" ] }, { @@ -6629,7 +6641,7 @@ "zh-chs": "通过扫描本地网络添加新的英特尔®AMT计算机。", "zh-cht": "通過掃描本地網絡新增新的Intel® AMT電腦。", "xloc": [ - "default.handlebars->41->435" + "default.handlebars->45->438" ] }, { @@ -6676,7 +6688,7 @@ "zh-chs": "添加位于本地网络上的新英特尔®AMT计算机。", "zh-cht": "新增位於本地網絡上的新Intel® AMT電腦。", "xloc": [ - "default.handlebars->41->433" + "default.handlebars->45->436" ] }, { @@ -6701,7 +6713,7 @@ "zh-chs": "将新的英特尔®AMT设备添加到设备组“{0}”。", "zh-cht": "將新的Intel® AMT裝置新增到裝置群“{0}”。", "xloc": [ - "default.handlebars->41->454" + "default.handlebars->45->457" ] }, { @@ -6726,8 +6738,8 @@ "zh-chs": "通过安装Mesh Agent将新计算机添加到该设备组。", "zh-cht": "通過安裝Mesh Agent將新電腦新增到該裝置群。", "xloc": [ - "default.handlebars->41->1910", - "default.handlebars->41->439" + "default.handlebars->45->1925", + "default.handlebars->45->442" ] }, { @@ -6751,8 +6763,8 @@ "tr": "Yerel ağda bulunan cihazı ekleyin.", "zh-chs": "添加位于本地网络上的设备。", "xloc": [ - "default.handlebars->41->1914", - "default.handlebars->41->443" + "default.handlebars->45->1929", + "default.handlebars->45->446" ] }, { @@ -6776,7 +6788,7 @@ "tr": "Yerel cihaz ekle", "zh-chs": "添加本地设备", "xloc": [ - "default.handlebars->41->453" + "default.handlebars->45->456" ] }, { @@ -6801,7 +6813,7 @@ "zh-chs": "添加标签", "zh-cht": "新增標籤", "xloc": [ - "default.handlebars->41->677" + "default.handlebars->45->680" ] }, { @@ -6826,7 +6838,7 @@ "zh-chs": "通过定期在远程设备上以管理员身份运行MeshCmd,添加,激活和配置Intel®AMT以将“{0}”分组。", "zh-cht": "通過定期在遠程設備上以管理員身份運行MeshCmd,添加,激活和配置Intel®AMT以將“{0}”分組。", "xloc": [ - "default.handlebars->41->465" + "default.handlebars->45->468" ] }, { @@ -6851,7 +6863,7 @@ "zh-chs": "添加了身份验证应用程序", "zh-cht": "添加了身份驗證應用程序", "xloc": [ - "default.handlebars->41->2286" + "default.handlebars->45->2301" ] }, { @@ -6876,7 +6888,7 @@ "zh-chs": "已将设备共享{0}从{1}添加到{2}", "zh-cht": "已將設備共享{0}從{1}添加到{2}", "xloc": [ - "default.handlebars->41->2297" + "default.handlebars->45->2312" ] }, { @@ -6896,7 +6908,7 @@ "ru": "Добавлен ежедневный общий доступ к устройству {0}.", "tr": "Her gün yinelenen {0} cihaz paylaşımı eklendi.", "xloc": [ - "default.handlebars->41->2334" + "default.handlebars->45->2349" ] }, { @@ -6916,7 +6928,7 @@ "ru": "Добавлен еженедельный общий доступ к устройству {0}.", "tr": "Haftalık olarak yinelenen {0} cihaz paylaşımı eklendi.", "xloc": [ - "default.handlebars->41->2335" + "default.handlebars->45->2350" ] }, { @@ -6936,7 +6948,7 @@ "ru": "Добавлен общий доступ к устройству {0} с неограниченным временем.", "tr": "Sınırsız süre ile cihaz paylaşımı {0} eklendi.", "xloc": [ - "default.handlebars->41->2327" + "default.handlebars->45->2342" ] }, { @@ -6961,8 +6973,8 @@ "zh-chs": "已将设备{0}添加到设备组{1}", "zh-cht": "已將設備{0}添加到設備組{1}", "xloc": [ - "default.handlebars->41->2253", - "default.handlebars->41->2280" + "default.handlebars->45->2268", + "default.handlebars->45->2295" ] }, { @@ -6986,7 +6998,7 @@ "tr": "Giriş anahtarı eklendi", "zh-chs": "添加登录令牌", "xloc": [ - "default.handlebars->41->2311" + "default.handlebars->45->2326" ] }, { @@ -7010,7 +7022,7 @@ "tr": "Anında iletme bildirimi kimlik doğrulama cihazı eklendi", "zh-chs": "新增推送通知认证装置", "xloc": [ - "default.handlebars->41->2309" + "default.handlebars->45->2324" ] }, { @@ -7035,7 +7047,7 @@ "zh-chs": "添加了安全密钥", "zh-cht": "添加了安全密鑰", "xloc": [ - "default.handlebars->41->2291" + "default.handlebars->45->2306" ] }, { @@ -7060,7 +7072,7 @@ "zh-chs": "已将用户组{0}添加到设备组{1}", "zh-cht": "已將用戶組{0}添加到設備組{1}", "xloc": [ - "default.handlebars->41->2264" + "default.handlebars->45->2279" ] }, { @@ -7085,8 +7097,8 @@ "zh-chs": "已将用户{0}添加到用户组{1}", "zh-cht": "已將用戶{0}添加到用戶組{1}", "xloc": [ - "default.handlebars->41->2267", - "default.handlebars->41->2276" + "default.handlebars->45->2282", + "default.handlebars->45->2291" ] }, { @@ -7111,7 +7123,7 @@ "zh-chs": "地址", "zh-cht": "地址", "xloc": [ - "default.handlebars->41->351" + "default.handlebars->45->352" ] }, { @@ -7161,8 +7173,8 @@ "zh-chs": "管理员控制模式(ACM)", "zh-cht": "管理員控制模式(ACM)", "xloc": [ - "default-mobile.handlebars->11->569", - "default.handlebars->41->1451" + "default-mobile.handlebars->11->568", + "default.handlebars->45->1465" ] }, { @@ -7187,8 +7199,8 @@ "zh-chs": "管理员凭证", "zh-cht": "管理員憑證", "xloc": [ - "default-mobile.handlebars->11->575", - "default.handlebars->41->1457" + "default-mobile.handlebars->11->574", + "default.handlebars->45->1471" ] }, { @@ -7239,7 +7251,7 @@ "zh-chs": "管理领域", "zh-cht": "管理領域", "xloc": [ - "default.handlebars->41->2625" + "default.handlebars->45->2640" ] }, { @@ -7290,7 +7302,7 @@ "zh-chs": "管理领域", "zh-cht": "管理領域", "xloc": [ - "default.handlebars->41->2474" + "default.handlebars->45->2489" ] }, { @@ -7315,7 +7327,7 @@ "zh-chs": "管理员", "zh-cht": "管理員", "xloc": [ - "default.handlebars->41->2401" + "default.handlebars->45->2416" ] }, { @@ -7340,7 +7352,7 @@ "zh-chs": "南非文", "zh-cht": "南非文", "xloc": [ - "default.handlebars->41->1536" + "default.handlebars->45->1551" ] }, { @@ -7369,11 +7381,11 @@ "default-mobile.handlebars->11->256", "default-mobile.handlebars->11->313", "default-mobile.handlebars->container->page_content->column_l->p10->p10console->consoleTable->1->4->1->1->1->0->p15outputselecttd->p15outputselect->p15outputselect1", - "default.handlebars->41->2129", - "default.handlebars->41->2142", - "default.handlebars->41->2928", - "default.handlebars->41->376", - "default.handlebars->41->628", + "default.handlebars->45->2144", + "default.handlebars->45->2157", + "default.handlebars->45->2943", + "default.handlebars->45->377", + "default.handlebars->45->631", "default.handlebars->container->column_l->p15->consoleTable->1->6->1->1->1->0->p15outputselecttd->p15outputselect->p15outputselect1", "default.handlebars->container->dialog->dialogBody->dialog7->1->td7meshkvm" ] @@ -7400,8 +7412,8 @@ "zh-chs": "代理+英特尔AMT", "zh-cht": "代理+Intel® AMT", "xloc": [ - "default.handlebars->41->2131", - "default.handlebars->41->2144" + "default.handlebars->45->2146", + "default.handlebars->45->2159" ] }, { @@ -7453,7 +7465,7 @@ "zh-cht": "代理控制台", "xloc": [ "default-mobile.handlebars->11->682", - "default.handlebars->41->2072" + "default.handlebars->45->2087" ] }, { @@ -7478,7 +7490,7 @@ "zh-chs": "代理错误计数器", "zh-cht": "代理錯誤計數器", "xloc": [ - "default.handlebars->41->2897" + "default.handlebars->45->2912" ] }, { @@ -7502,7 +7514,7 @@ "tr": "Agent IP adresi", "zh-chs": "代理IP地址", "xloc": [ - "default.handlebars->41->326" + "default.handlebars->45->327" ] }, { @@ -7553,7 +7565,7 @@ "zh-cht": "代理訊息", "xloc": [ "default-mobile.handlebars->11->229", - "default.handlebars->41->425" + "default.handlebars->45->428" ] }, { @@ -7645,8 +7657,8 @@ "ru": "Общий доступ из Агента", "tr": "Agent Kendisinin-Paylaşımı", "xloc": [ - "default.handlebars->41->1940", - "default.handlebars->41->980" + "default.handlebars->45->1955", + "default.handlebars->45->994" ] }, { @@ -7671,7 +7683,7 @@ "zh-chs": "代理时段", "zh-cht": "代理時段", "xloc": [ - "default.handlebars->41->2913" + "default.handlebars->45->2928" ] }, { @@ -7718,7 +7730,7 @@ "zh-cht": "代理標籤", "xloc": [ "default-mobile.handlebars->11->310", - "default.handlebars->41->826" + "default.handlebars->45->834" ] }, { @@ -7742,8 +7754,8 @@ "tr": "Agent Türü", "zh-chs": "代理类型", "xloc": [ - "default.handlebars->41->320", - "default.handlebars->41->346" + "default.handlebars->45->321", + "default.handlebars->45->347" ] }, { @@ -7768,7 +7780,7 @@ "zh-chs": "代理类型", "zh-cht": "代理類型", "xloc": [ - "default.handlebars->41->2140", + "default.handlebars->45->2155", "default.handlebars->container->column_l->p21->p21main->1->1->meshOsChartDiv->1" ] }, @@ -7793,8 +7805,8 @@ "tr": "Agent Sürümü", "zh-chs": "代理版本", "xloc": [ - "default.handlebars->41->321", - "default.handlebars->41->347" + "default.handlebars->45->322", + "default.handlebars->45->348" ] }, { @@ -7819,7 +7831,7 @@ "zh-chs": "代理关闭了与服务器压缩的{0}%代理会话。已发送:{1},已压缩:{2}", "zh-cht": "代理關閉了與{0}%代理到服務器壓縮的會話。已發送:{1},已壓縮:{2}", "xloc": [ - "default.handlebars->41->2250" + "default.handlebars->45->2265" ] }, { @@ -7844,9 +7856,9 @@ "zh-chs": "代理已连接", "zh-cht": "代理已連接", "xloc": [ - "default.handlebars->41->242", - "default.handlebars->41->944", - "default.handlebars->41->945" + "default.handlebars->45->243", + "default.handlebars->45->954", + "default.handlebars->45->955" ] }, { @@ -7866,7 +7878,7 @@ "ru": "Агент подключен с ограниченными привилегиями", "tr": "Agent kısıtlı yetkiler ile bağlandı", "xloc": [ - "default.handlebars->41->243" + "default.handlebars->45->244" ] }, { @@ -7891,7 +7903,7 @@ "zh-chs": "代理已断开连接", "zh-cht": "代理已斷開連接", "xloc": [ - "default.handlebars->41->247" + "default.handlebars->45->248" ] }, { @@ -7911,7 +7923,7 @@ "ru": "Проверка хэша агента пропущена, это небезопасно.", "tr": "Agent doğrulaması atlandı, bu güvenli değil.", "xloc": [ - "default.handlebars->41->91" + "default.handlebars->45->91" ] }, { @@ -8000,7 +8012,7 @@ "zh-cht": "代理離線", "xloc": [ "default-mobile.handlebars->11->603", - "default.handlebars->41->1486" + "default.handlebars->45->1501" ] }, { @@ -8026,7 +8038,7 @@ "zh-cht": "代理在線", "xloc": [ "default-mobile.handlebars->11->602", - "default.handlebars->41->1485" + "default.handlebars->45->1500" ] }, { @@ -8114,7 +8126,7 @@ "zh-chs": "代理在特权降低的远程设备上运行。", "zh-cht": "代理在特權降低的遠程設備上運行。", "xloc": [ - "default.handlebars->41->938" + "default.handlebars->45->948" ] }, { @@ -8223,9 +8235,9 @@ "zh-chs": "代理", "zh-cht": "代理", "xloc": [ - "default.handlebars->41->2102", - "default.handlebars->41->2941", - "default.handlebars->41->521" + "default.handlebars->45->2117", + "default.handlebars->45->2956", + "default.handlebars->45->524" ] }, { @@ -8250,7 +8262,7 @@ "zh-chs": "阿尔巴尼亚文", "zh-cht": "阿爾巴尼亞文", "xloc": [ - "default.handlebars->41->1537" + "default.handlebars->45->1552" ] }, { @@ -8278,7 +8290,7 @@ "default-mobile.handlebars->11->148", "default-mobile.handlebars->11->476", "default-mobile.handlebars->11->478", - "default.handlebars->41->2784", + "default.handlebars->45->2799", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar->DevFilterSelect->1" ] }, @@ -8304,7 +8316,7 @@ "zh-chs": "全部可用", "zh-cht": "全部可用", "xloc": [ - "default.handlebars->41->2363" + "default.handlebars->45->2378" ] }, { @@ -8315,8 +8327,8 @@ "pt-br": "Todos agentes disponíveis", "ru": "Все доступные агенты", "xloc": [ - "default.handlebars->41->2103", - "default.handlebars->41->522" + "default.handlebars->45->2118", + "default.handlebars->45->525" ] }, { @@ -8341,7 +8353,7 @@ "zh-chs": "所有显示", "zh-cht": "所有顯示", "xloc": [ - "default.handlebars->41->1298" + "default.handlebars->45->1313" ] }, { @@ -8366,7 +8378,7 @@ "zh-chs": "所有事件", "zh-cht": "所有事件", "xloc": [ - "default.handlebars->41->2361" + "default.handlebars->45->2376" ] }, { @@ -8391,9 +8403,9 @@ "zh-chs": "全部聚焦", "zh-cht": "全部聚焦", "xloc": [ - "default.handlebars->41->1230", - "default.handlebars->41->1232", - "default.handlebars->41->1233" + "default.handlebars->45->1245", + "default.handlebars->45->1247", + "default.handlebars->45->1248" ] }, { @@ -8442,8 +8454,8 @@ "zh-chs": "允许用户管理此设备组和该组中的设备。", "zh-cht": "允許用戶管理此裝置群和該群中的裝置。", "xloc": [ - "default.handlebars->41->2017", - "default.handlebars->41->2573" + "default.handlebars->45->2032", + "default.handlebars->45->2588" ] }, { @@ -8468,7 +8480,7 @@ "zh-chs": "允许用户管理此设备。", "zh-cht": "允許用戶管理此裝置。", "xloc": [ - "default.handlebars->41->2018" + "default.handlebars->45->2033" ] }, { @@ -8492,7 +8504,7 @@ "tr": "İzin verilmiş", "zh-chs": "允许", "xloc": [ - "default.handlebars->41->270" + "default.handlebars->45->271" ] }, { @@ -8539,7 +8551,7 @@ "zh-cht": "Alpine Linux x86 64 Bit (MUSL)", "xloc": [ "default-mobile.handlebars->11->39", - "default.handlebars->41->46" + "default.handlebars->45->46" ] }, { @@ -8565,8 +8577,8 @@ "xloc": [ "default-mobile.handlebars->11->431", "default-mobile.handlebars->11->435", - "default.handlebars->41->1253", - "default.handlebars->41->1257" + "default.handlebars->45->1268", + "default.handlebars->45->1272" ] }, { @@ -8574,8 +8586,9 @@ "nl": "Alt Shell", "pl": "Alternatywna Powłoka", "ru": "Альтернативная оболочка", + "fr": "Shell alternatif", "xloc": [ - "default.handlebars->41->1220" + "default.handlebars->45->1235" ] }, { @@ -8652,7 +8665,7 @@ "zh-chs": "备用(F10 = ESC + 0)", "zh-cht": "備用(F10 = ESC + 0)", "xloc": [ - "default.handlebars->41->1332", + "default.handlebars->45->1347", "sharing.handlebars->11->37" ] }, @@ -8679,6 +8692,8 @@ "zh-cht": "備用端口", "xloc": [ "default.handlebars->altPortContextMenu->1", + "default.handlebars->httpPortContextMenu->1", + "default.handlebars->httpsPortContextMenu->1", "default.handlebars->rfbPortContextMenu->1", "default.handlebars->sshPortContextMenu->1" ] @@ -8686,7 +8701,7 @@ { "cs": "Alternativní port", "da": "Alternativ port", - "de": "Alternativer Hafen", + "de": "Alternativer Port", "en": "Alternative Port", "es": "Puerto Alternativo", "fi": "Vaihtoehtoinen portti", @@ -8726,10 +8741,10 @@ "zh-chs": "一直通知", "zh-cht": "一直通知", "xloc": [ - "default.handlebars->41->1883", - "default.handlebars->41->2532", - "default.handlebars->41->2634", - "default.handlebars->41->856" + "default.handlebars->45->1898", + "default.handlebars->45->2547", + "default.handlebars->45->2649", + "default.handlebars->45->864" ] }, { @@ -8754,10 +8769,10 @@ "zh-chs": "一直提示", "zh-cht": "一直提示", "xloc": [ - "default.handlebars->41->1884", - "default.handlebars->41->2533", - "default.handlebars->41->2635", - "default.handlebars->41->857" + "default.handlebars->45->1899", + "default.handlebars->45->2548", + "default.handlebars->45->2650", + "default.handlebars->45->865" ] }, { @@ -8856,8 +8871,8 @@ "agentinvite.handlebars->container->column_l->5->1->tandrotab", "agentinvite.handlebars->container->column_l->5->androtab->1", "default-mobile.handlebars->11->20", - "default.handlebars->41->22", - "default.handlebars->41->27" + "default.handlebars->45->22", + "default.handlebars->45->27" ] }, { @@ -8978,7 +8993,7 @@ "zh-cht": "安卓x86", "xloc": [ "default-mobile.handlebars->11->18", - "default.handlebars->41->25" + "default.handlebars->45->25" ] }, { @@ -9002,8 +9017,8 @@ "tr": "Anti-virüs etkin değil", "zh-chs": "杀毒软件未激活", "xloc": [ - "default.handlebars->41->2133", - "default.handlebars->41->2147" + "default.handlebars->45->2148", + "default.handlebars->45->2162" ] }, { @@ -9029,7 +9044,7 @@ "zh-cht": "防毒軟體", "xloc": [ "default-mobile.handlebars->11->532", - "default.handlebars->41->845" + "default.handlebars->45->853" ] }, { @@ -9054,7 +9069,7 @@ "zh-chs": "任何可支持的", "zh-cht": "任何可支持的", "xloc": [ - "default.handlebars->41->495" + "default.handlebars->45->498" ] }, { @@ -9062,8 +9077,9 @@ "nl": "Apple", "pl": "Apple", "ru": "Apple", + "fr": "Apple", "xloc": [ - "default.handlebars->41->57" + "default.handlebars->45->57" ] }, { @@ -9089,7 +9105,7 @@ "zh-cht": "蘋果矽", "xloc": [ "default-mobile.handlebars->11->35", - "default.handlebars->41->42" + "default.handlebars->45->42" ] }, { @@ -9114,7 +9130,7 @@ "zh-chs": "苹果macOS", "zh-cht": "蘋果macOS", "xloc": [ - "default.handlebars->41->536" + "default.handlebars->45->539" ] }, { @@ -9139,7 +9155,7 @@ "zh-chs": "仅限Apple macOS", "zh-cht": "僅限Apple macOS", "xloc": [ - "default.handlebars->41->497" + "default.handlebars->45->500" ] }, { @@ -9272,7 +9288,7 @@ "tr": "Uygulama, Her zaman bağlı", "zh-chs": "应用程序,始终连接", "xloc": [ - "default.handlebars->41->549" + "default.handlebars->45->552" ] }, { @@ -9296,7 +9312,7 @@ "tr": "Uygulama, Kullanıcı isteği üzerine bağlanın", "zh-chs": "应用程序,根据用户请求连接", "xloc": [ - "default.handlebars->41->548" + "default.handlebars->45->551" ] }, { @@ -9321,7 +9337,7 @@ "zh-chs": "阿拉伯文(阿尔及利亚)", "zh-cht": "阿拉伯文(阿爾及利亞)", "xloc": [ - "default.handlebars->41->1539" + "default.handlebars->45->1554" ] }, { @@ -9346,7 +9362,7 @@ "zh-chs": "阿拉伯文(巴林)", "zh-cht": "阿拉伯文(巴林)", "xloc": [ - "default.handlebars->41->1540" + "default.handlebars->45->1555" ] }, { @@ -9371,7 +9387,7 @@ "zh-chs": "阿拉伯文(埃及)", "zh-cht": "阿拉伯文(埃及)", "xloc": [ - "default.handlebars->41->1541" + "default.handlebars->45->1556" ] }, { @@ -9396,7 +9412,7 @@ "zh-chs": "阿拉伯文(伊拉克)", "zh-cht": "阿拉伯文(伊拉克)", "xloc": [ - "default.handlebars->41->1542" + "default.handlebars->45->1557" ] }, { @@ -9421,7 +9437,7 @@ "zh-chs": "阿拉伯文(约旦)", "zh-cht": "阿拉伯文(約旦)", "xloc": [ - "default.handlebars->41->1543" + "default.handlebars->45->1558" ] }, { @@ -9446,7 +9462,7 @@ "zh-chs": "阿拉伯文(科威特)", "zh-cht": "阿拉伯文(科威特)", "xloc": [ - "default.handlebars->41->1544" + "default.handlebars->45->1559" ] }, { @@ -9471,7 +9487,7 @@ "zh-chs": "阿拉伯文(黎巴嫩)", "zh-cht": "阿拉伯文(黎巴嫩)", "xloc": [ - "default.handlebars->41->1545" + "default.handlebars->45->1560" ] }, { @@ -9496,7 +9512,7 @@ "zh-chs": "阿拉伯文(利比亚)", "zh-cht": "阿拉伯文(利比亞)", "xloc": [ - "default.handlebars->41->1546" + "default.handlebars->45->1561" ] }, { @@ -9521,7 +9537,7 @@ "zh-chs": "阿拉伯文(摩洛哥)", "zh-cht": "阿拉伯文(摩洛哥)", "xloc": [ - "default.handlebars->41->1547" + "default.handlebars->45->1562" ] }, { @@ -9546,7 +9562,7 @@ "zh-chs": "阿拉伯文(阿曼)", "zh-cht": "阿拉伯文(阿曼)", "xloc": [ - "default.handlebars->41->1548" + "default.handlebars->45->1563" ] }, { @@ -9571,7 +9587,7 @@ "zh-chs": "阿拉伯文(卡塔尔)", "zh-cht": "阿拉伯文(卡塔爾)", "xloc": [ - "default.handlebars->41->1549" + "default.handlebars->45->1564" ] }, { @@ -9596,7 +9612,7 @@ "zh-chs": "阿拉伯文(沙特阿拉伯)", "zh-cht": "阿拉伯文(沙特阿拉伯)", "xloc": [ - "default.handlebars->41->1550" + "default.handlebars->45->1565" ] }, { @@ -9621,7 +9637,7 @@ "zh-chs": "阿拉伯文(标准)", "zh-cht": "阿拉伯文(標準)", "xloc": [ - "default.handlebars->41->1538" + "default.handlebars->45->1553" ] }, { @@ -9646,7 +9662,7 @@ "zh-chs": "阿拉伯文(叙利亚)", "zh-cht": "阿拉伯文(敘利亞)", "xloc": [ - "default.handlebars->41->1551" + "default.handlebars->45->1566" ] }, { @@ -9671,7 +9687,7 @@ "zh-chs": "阿拉伯文(突尼斯)", "zh-cht": "阿拉伯文(突尼斯)", "xloc": [ - "default.handlebars->41->1552" + "default.handlebars->45->1567" ] }, { @@ -9696,7 +9712,7 @@ "zh-chs": "阿拉伯文(阿联酋)", "zh-cht": "阿拉伯文(阿聯酋)", "xloc": [ - "default.handlebars->41->1553" + "default.handlebars->45->1568" ] }, { @@ -9721,7 +9737,7 @@ "zh-chs": "阿拉伯文(也门)", "zh-cht": "阿拉伯文(也門)", "xloc": [ - "default.handlebars->41->1554" + "default.handlebars->45->1569" ] }, { @@ -9746,7 +9762,7 @@ "zh-chs": "阿拉贡文", "zh-cht": "阿拉貢文", "xloc": [ - "default.handlebars->41->1555" + "default.handlebars->45->1570" ] }, { @@ -9774,9 +9790,9 @@ "default-mobile.handlebars->11->511", "default-mobile.handlebars->11->513", "default-mobile.handlebars->11->515", - "default.handlebars->41->1400", - "default.handlebars->41->1402", - "default.handlebars->41->1404" + "default.handlebars->45->1415", + "default.handlebars->45->1417", + "default.handlebars->45->1419" ] }, { @@ -9801,7 +9817,7 @@ "zh-chs": "您确定要连接到{0}设备吗?", "zh-cht": "你確定要連接到{0}裝置嗎?", "xloc": [ - "default.handlebars->41->428" + "default.handlebars->45->431" ] }, { @@ -9827,7 +9843,7 @@ "zh-cht": "你確定要刪除群{0}嗎?刪除裝置群還將刪除該群中有關裝置的所有訊息。", "xloc": [ "default-mobile.handlebars->11->643", - "default.handlebars->41->1984" + "default.handlebars->45->1999" ] }, { @@ -9852,7 +9868,7 @@ "zh-chs": "您确定要删除节点{0}吗?", "zh-cht": "你確定要刪除節點{0}嗎?", "xloc": [ - "default.handlebars->41->1149" + "default.handlebars->45->1164" ] }, { @@ -9877,7 +9893,7 @@ "zh-chs": "您确定要卸载所选代理吗?", "zh-cht": "你確定要卸載所選代理嗎?", "xloc": [ - "default.handlebars->41->1138" + "default.handlebars->45->1153" ] }, { @@ -9902,7 +9918,7 @@ "zh-chs": "您确定要卸载所选的{0}代理吗?", "zh-cht": "你確定要卸載所選的{0}代理嗎?", "xloc": [ - "default.handlebars->41->1137" + "default.handlebars->45->1152" ] }, { @@ -9927,7 +9943,7 @@ "zh-chs": "您确定要{0}插件吗:{1}", "zh-cht": "你確定要{0}外掛嗎:{1}", "xloc": [ - "default.handlebars->41->2992" + "default.handlebars->45->3007" ] }, { @@ -9952,7 +9968,7 @@ "zh-chs": "Armada370 - ARM32/HF (libc/2.26)", "xloc": [ "default-mobile.handlebars->11->41", - "default.handlebars->41->48" + "default.handlebars->45->48" ] }, { @@ -9977,19 +9993,25 @@ "zh-chs": "亚美尼亚文", "zh-cht": "亞美尼亞文", "xloc": [ - "default.handlebars->41->1556" + "default.handlebars->45->1571" ] }, { "en": "Ask Admin PowerShell", + "nl": "Vraag naar de PowerShell in beheersdersmodus", + "pl": "PowerShell z Zapytaniem Administratora", "ru": "PowerShell от Админа, cпросить согласия", + "fr": "Demander PowerShell en mode administrateur", "xloc": [ "default.handlebars->termShellContextMenu->11" ] }, { "en": "Ask Admin Shell", + "nl": "Vraag naar de shell in beheersdersmodus", + "pl": "Terminal z Zapytaniem Administratora", "ru": "Консоль от Админа, cпросить согласия", + "fr": "Demander le shell en mode administrateur", "xloc": [ "default.handlebars->termShellContextMenu->9" ] @@ -10047,14 +10069,20 @@ }, { "en": "Ask User PowerShell", + "nl": "Vraag naar de PowerShell in gebruikersmodus", + "pl": "PowerShell z Zapytaniem Użytkownika", "ru": "PowerShell от Пользователя, cпросить согласия", + "fr": "Demander PowerShell en mode utilisateur ", "xloc": [ "default.handlebars->termShellContextMenu->15" ] }, { "en": "Ask User Shell", + "nl": "Vraag naar de shell in gebruikersmodus", + "pl": "Terminal z Zapytaniem Użytkownika", "ru": "Консоль от Пользователя, cпросить согласия", + "fr": "Demander le shell en mode utilisateur", "xloc": [ "default.handlebars->termShellContextMenu->13" ] @@ -10081,7 +10109,7 @@ "zh-chs": "阿萨姆文", "zh-cht": "阿薩姆文", "xloc": [ - "default.handlebars->41->1557" + "default.handlebars->45->1572" ] }, { @@ -10131,7 +10159,7 @@ "zh-chs": "助手 (Windows)", "xloc": [ "default-mobile.handlebars->11->40", - "default.handlebars->41->47" + "default.handlebars->45->47" ] }, { @@ -10176,8 +10204,8 @@ "tr": "Windows için Asistan (.exe)", "zh-chs": "Windows 助手 (.exe)", "xloc": [ - "default.handlebars->41->575", - "default.handlebars->41->579" + "default.handlebars->45->578", + "default.handlebars->45->582" ] }, { @@ -10226,7 +10254,7 @@ "zh-chs": "阿斯图里亚斯文", "zh-cht": "阿斯圖里亞斯文", "xloc": [ - "default.handlebars->41->1558" + "default.handlebars->45->1573" ] }, { @@ -10251,7 +10279,7 @@ "zh-chs": "尝试激活英特尔(R)AMT ACM模式", "zh-cht": "嘗試激活英特爾(R)AMT ACM模式", "xloc": [ - "default.handlebars->41->2219" + "default.handlebars->45->2234" ] }, { @@ -10299,9 +10327,9 @@ "default-mobile.handlebars->11->447", "default-mobile.handlebars->11->451", "default-mobile.handlebars->11->463", - "default.handlebars->41->1307", - "default.handlebars->41->1311", - "default.handlebars->41->1323", + "default.handlebars->45->1322", + "default.handlebars->45->1326", + "default.handlebars->45->1338", "ssh.handlebars->3->21", "ssh.handlebars->3->22", "ssh.handlebars->3->5", @@ -10330,7 +10358,7 @@ "zh-chs": "认证软件", "zh-cht": "認證軟體", "xloc": [ - "default.handlebars->41->2638" + "default.handlebars->45->2653" ] }, { @@ -10354,9 +10382,9 @@ "tr": "Kimlik Doğrulama Cihazı", "zh-chs": "认证设备", "xloc": [ - "default.handlebars->41->1519", - "default.handlebars->41->1521", - "default.handlebars->41->1525" + "default.handlebars->45->1534", + "default.handlebars->45->1536", + "default.handlebars->45->1540" ] }, { @@ -10382,8 +10410,8 @@ "xloc": [ "default-mobile.handlebars->11->464", "default-mobile.handlebars->11->470", - "default.handlebars->41->1325", - "default.handlebars->41->1340" + "default.handlebars->45->1340", + "default.handlebars->45->1355" ] }, { @@ -10412,10 +10440,10 @@ "default-mobile.handlebars->11->104", "default-mobile.handlebars->11->68", "default-mobile.handlebars->11->71", - "default.handlebars->41->1515", - "default.handlebars->41->1517", - "default.handlebars->41->204", - "default.handlebars->41->209" + "default.handlebars->45->1530", + "default.handlebars->45->1532", + "default.handlebars->45->205", + "default.handlebars->45->210" ] }, { @@ -10440,7 +10468,7 @@ "zh-chs": "认证软件激活成功。", "zh-cht": "認證軟體啟動成功。", "xloc": [ - "default.handlebars->41->205" + "default.handlebars->45->206" ] }, { @@ -10465,7 +10493,7 @@ "zh-chs": "认证软件已删除。", "zh-cht": "認證軟體已刪除。", "xloc": [ - "default.handlebars->41->210" + "default.handlebars->45->211" ] }, { @@ -10535,8 +10563,8 @@ "zh-chs": "自动删除", "zh-cht": "自動刪除", "xloc": [ - "default.handlebars->41->1868", - "default.handlebars->41->2354" + "default.handlebars->45->1883", + "default.handlebars->45->2369" ] }, { @@ -10590,7 +10618,7 @@ "zh-chs": "自动下载代理程序核心转储文件:“{0}”", "zh-cht": "自動下載代理程序核心轉儲文件:“{0}”", "xloc": [ - "default.handlebars->41->2300" + "default.handlebars->45->2315" ] }, { @@ -10685,7 +10713,7 @@ "tr": "Etkin olmayan cihazları otomatik olarak kaldırın", "zh-chs": "自动移除非活动设备", "xloc": [ - "default.handlebars->41->2012" + "default.handlebars->45->2027" ] }, { @@ -10710,7 +10738,7 @@ "zh-chs": "可用內存", "zh-cht": "可用內存", "xloc": [ - "default.handlebars->41->2922" + "default.handlebars->45->2937" ] }, { @@ -10735,7 +10763,7 @@ "zh-chs": "阿塞拜疆文", "zh-cht": "阿塞拜疆文", "xloc": [ - "default.handlebars->41->1559" + "default.handlebars->45->1574" ] }, { @@ -10762,9 +10790,9 @@ "default-mobile.handlebars->11->519", "default-mobile.handlebars->11->523", "default-mobile.handlebars->11->527", - "default.handlebars->41->832", - "default.handlebars->41->836", - "default.handlebars->41->840" + "default.handlebars->45->840", + "default.handlebars->45->844", + "default.handlebars->45->848" ] }, { @@ -10790,7 +10818,7 @@ "zh-cht": "的BIOS", "xloc": [ "default-mobile.handlebars->11->581", - "default.handlebars->41->1463" + "default.handlebars->45->1478" ] }, { @@ -10901,7 +10929,7 @@ "zh-chs": "退格", "xloc": [ "default-mobile.handlebars->11->414", - "default.handlebars->41->1236" + "default.handlebars->45->1251" ] }, { @@ -10926,7 +10954,7 @@ "zh-chs": "背景与互动", "zh-cht": "背景與互動", "xloc": [ - "default.handlebars->41->544" + "default.handlebars->45->547" ] }, { @@ -10951,10 +10979,10 @@ "zh-chs": "背景与互动", "zh-cht": "背景與互動", "xloc": [ - "default.handlebars->41->2109", - "default.handlebars->41->2116", - "default.handlebars->41->508", - "default.handlebars->41->528" + "default.handlebars->45->2124", + "default.handlebars->45->2131", + "default.handlebars->45->511", + "default.handlebars->45->531" ] }, { @@ -10979,11 +11007,11 @@ "zh-chs": "仅背景", "zh-cht": "僅背景", "xloc": [ - "default.handlebars->41->2110", - "default.handlebars->41->2117", - "default.handlebars->41->509", - "default.handlebars->41->529", - "default.handlebars->41->545" + "default.handlebars->45->2125", + "default.handlebars->45->2132", + "default.handlebars->45->512", + "default.handlebars->45->532", + "default.handlebars->45->548" ] }, { @@ -11034,8 +11062,8 @@ "zh-chs": "备用码", "zh-cht": "備用碼", "xloc": [ - "default.handlebars->41->2641", - "default.handlebars->41->2832" + "default.handlebars->45->2656", + "default.handlebars->45->2847" ] }, { @@ -11043,9 +11071,10 @@ "nl": "Backup codes zijn vergrendeld", "pl": "Kody zapasowe są zablokowane", "ru": "Резервные коды заблокированы", + "fr": "Les codes de récupérations sont verrouillés", "xloc": [ "default-mobile.handlebars->11->61", - "default.handlebars->41->195" + "default.handlebars->45->196" ] }, { @@ -11065,7 +11094,7 @@ "ru": "Путь резервного копирования не может в папке meshcentral-data, параметры резервного копирования игнорируются.", "tr": "Yedekleme yolu meshcentral-data klasörü içinde ayarlanamaz, yedekleme ayarları yok sayılır.", "xloc": [ - "default.handlebars->41->103" + "default.handlebars->45->103" ] }, { @@ -11090,7 +11119,7 @@ "zh-chs": "错误的签名", "zh-cht": "錯誤的簽名", "xloc": [ - "default.handlebars->41->2904" + "default.handlebars->45->2919" ] }, { @@ -11115,7 +11144,7 @@ "zh-chs": "错误的网络证书", "zh-cht": "錯誤的網絡憑證", "xloc": [ - "default.handlebars->41->2903" + "default.handlebars->45->2918" ] }, { @@ -11140,7 +11169,7 @@ "zh-chs": "巴斯克", "zh-cht": "巴斯克", "xloc": [ - "default.handlebars->41->1560" + "default.handlebars->45->1575" ] }, { @@ -11165,7 +11194,7 @@ "zh-chs": "批处理文件上传", "zh-cht": "批處理文件上傳", "xloc": [ - "default.handlebars->41->693" + "default.handlebars->45->696" ] }, { @@ -11215,7 +11244,7 @@ "zh-chs": "将{0}个文件批量上传到文件夹{1}", "zh-cht": "將{0}個文件批量上傳到文件夾{1}", "xloc": [ - "default.handlebars->41->2299" + "default.handlebars->45->2314" ] }, { @@ -11240,7 +11269,7 @@ "zh-chs": "白俄罗斯文", "zh-cht": "白俄羅斯文", "xloc": [ - "default.handlebars->41->1562" + "default.handlebars->45->1577" ] }, { @@ -11265,7 +11294,7 @@ "zh-chs": "孟加拉", "zh-cht": "孟加拉", "xloc": [ - "default.handlebars->41->1563" + "default.handlebars->45->1578" ] }, { @@ -11299,7 +11328,7 @@ { "cs": "Vázat místní port na všechna síťová rozhraní", "da": "Bind lokal port til alle netværksinterfaces", - "de": "Binden Sie den lokalen Port an alle Netzwerkschnittstellen", + "de": "Lokalen Port an alle Netzwerkschnittstellen binden", "en": "Bind local port to all network interfaces", "es": "Vincular el puerto local a todas las interfaces de red", "fi": "Sido paikallinen portti kaikkiin verkkoliitäntöihin", @@ -11339,7 +11368,7 @@ "zh-chs": "引导加载程序", "xloc": [ "default-mobile.handlebars->11->545", - "default.handlebars->41->1417" + "default.handlebars->45->1432" ] }, { @@ -11364,7 +11393,7 @@ "zh-chs": "波斯尼亚文", "zh-cht": "波斯尼亞文", "xloc": [ - "default.handlebars->41->1564" + "default.handlebars->45->1579" ] }, { @@ -11389,7 +11418,7 @@ "zh-chs": "布列塔尼", "zh-cht": "布列塔尼", "xloc": [ - "default.handlebars->41->1565" + "default.handlebars->45->1580" ] }, { @@ -11414,7 +11443,7 @@ "zh-chs": "广播", "zh-cht": "廣播", "xloc": [ - "default.handlebars->41->2539", + "default.handlebars->45->2554", "default.handlebars->container->column_l->p4->3->1->0->3->1" ] }, @@ -11440,7 +11469,7 @@ "zh-chs": "广播消息", "zh-cht": "廣播消息", "xloc": [ - "default.handlebars->41->2456" + "default.handlebars->45->2471" ] }, { @@ -11465,7 +11494,7 @@ "zh-chs": "向所有连接的用户广播消息。", "zh-cht": "向所有連接的用戶廣播消息。", "xloc": [ - "default.handlebars->41->2451" + "default.handlebars->45->2466" ] }, { @@ -11476,7 +11505,7 @@ "pt-br": "Navegador", "ru": "Браузер", "xloc": [ - "default.handlebars->41->2806" + "default.handlebars->45->2821" ] }, { @@ -11484,6 +11513,7 @@ "nl": "Browser grootte", "pl": "Jak Okna Przeglądarki", "ru": "Размер браузера", + "fr": "Taille du navigateur", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize->3" ] @@ -11510,7 +11540,7 @@ "zh-chs": "浏览器默认", "xloc": [ "default-mobile.handlebars->11->90", - "default.handlebars->41->62" + "default.handlebars->45->62" ] }, { @@ -11535,7 +11565,7 @@ "zh-chs": "保加利亚文", "zh-cht": "保加利亞文", "xloc": [ - "default.handlebars->41->1561" + "default.handlebars->45->1576" ] }, { @@ -11560,7 +11590,7 @@ "zh-chs": "缅甸文", "zh-cht": "緬甸文", "xloc": [ - "default.handlebars->41->1566" + "default.handlebars->45->1581" ] }, { @@ -11584,7 +11614,7 @@ "tr": "Varsayılan olarak, etkin olmayan cihazlar 1 gün sonra kaldırılacaktır.", "zh-chs": "默认情况下,不活动的设备将在 1 天后移除。", "xloc": [ - "default.handlebars->41->2014" + "default.handlebars->45->2029" ] }, { @@ -11608,7 +11638,7 @@ "tr": "Varsayılan olarak, etkin olmayan cihazlar {0} gün sonra kaldırılacaktır.", "zh-chs": "默认情况下,非活动设备将在 {0} 天后移除。", "xloc": [ - "default.handlebars->41->2015" + "default.handlebars->45->2030" ] }, { @@ -11628,7 +11658,7 @@ "ru": "Входящих байт", "tr": "Bayt Girişi", "xloc": [ - "default.handlebars->41->2802" + "default.handlebars->45->2817" ] }, { @@ -11648,7 +11678,7 @@ "ru": "Исходящих байт", "tr": "Bayt Bitti", "xloc": [ - "default.handlebars->41->2803" + "default.handlebars->45->2818" ] }, { @@ -11684,7 +11714,7 @@ "zh-cht": "CCM", "xloc": [ "default-mobile.handlebars->11->296", - "default.handlebars->41->808" + "default.handlebars->45->816" ] }, { @@ -11709,7 +11739,7 @@ "zh-chs": "CCM模式", "zh-cht": "CCM模式", "xloc": [ - "default.handlebars->41->1967" + "default.handlebars->45->1982" ] }, { @@ -11735,9 +11765,9 @@ "zh-cht": "CIRA", "xloc": [ "default-mobile.handlebars->11->257", - "default.handlebars->41->2929", - "default.handlebars->41->378", - "default.handlebars->41->630" + "default.handlebars->45->2944", + "default.handlebars->45->379", + "default.handlebars->45->633" ] }, { @@ -11762,7 +11792,7 @@ "zh-chs": "CIRA服务器", "zh-cht": "CIRA伺服器", "xloc": [ - "default.handlebars->41->2976" + "default.handlebars->45->2991" ] }, { @@ -11787,7 +11817,7 @@ "zh-chs": "CIRA服务器命令", "zh-cht": "CIRA伺服器指令", "xloc": [ - "default.handlebars->41->2977" + "default.handlebars->45->2992" ] }, { @@ -11807,7 +11837,7 @@ "ru": "Локальные полные доменные имена CIRA игнорируются, когда сервер находится в режиме LAN-only или WAN-only.", "tr": "Sunucu yalnızca LAN veya yalnızca WAN modundayken CIRA yerel FQDN'leri yoksayılır.", "xloc": [ - "default.handlebars->41->89" + "default.handlebars->45->89" ] }, { @@ -11832,7 +11862,7 @@ "zh-chs": "CIRA设置", "zh-cht": "CIRA設置", "xloc": [ - "default.handlebars->41->1975" + "default.handlebars->45->1990" ] }, { @@ -11858,8 +11888,8 @@ "zh-cht": "CPU", "xloc": [ "default-mobile.handlebars->11->587", - "default.handlebars->41->1469", - "default.handlebars->41->2953", + "default.handlebars->45->1484", + "default.handlebars->45->2968", "default.handlebars->container->column_l->p40->3->1->p40type->5" ] }, @@ -11885,7 +11915,7 @@ "zh-chs": "CPU负载", "zh-cht": "CPU負載", "xloc": [ - "default.handlebars->41->2918" + "default.handlebars->45->2933" ] }, { @@ -11910,7 +11940,7 @@ "zh-chs": "最近15分钟的CPU负载", "zh-cht": "最近15分鐘的CPU負載", "xloc": [ - "default.handlebars->41->2921" + "default.handlebars->45->2936" ] }, { @@ -11935,7 +11965,7 @@ "zh-chs": "最近5分钟的CPU负载", "zh-cht": "最近5分鐘的CPU負載", "xloc": [ - "default.handlebars->41->2920" + "default.handlebars->45->2935" ] }, { @@ -11960,7 +11990,7 @@ "zh-chs": "最近一分钟的CPU负载", "zh-cht": "最近一分鐘的CPU負載", "xloc": [ - "default.handlebars->41->2919" + "default.handlebars->45->2934" ] }, { @@ -11985,8 +12015,8 @@ "zh-chs": "CR+LF", "zh-cht": "CR+LF", "xloc": [ - "default.handlebars->41->1303", - "default.handlebars->41->1334", + "default.handlebars->45->1318", + "default.handlebars->45->1349", "default.handlebars->container->column_l->p12->termTable->1->1->4->1->1->terminalSettingsButtons", "sharing.handlebars->11->25", "sharing.handlebars->11->39", @@ -12015,7 +12045,7 @@ "zh-chs": "CSV", "zh-cht": "CSV", "xloc": [ - "default.handlebars->41->2371" + "default.handlebars->45->2386" ] }, { @@ -12040,9 +12070,9 @@ "zh-chs": "CSV格式", "zh-cht": "CSV格式", "xloc": [ - "default.handlebars->41->2375", - "default.handlebars->41->2443", - "default.handlebars->41->701" + "default.handlebars->45->2390", + "default.handlebars->45->2458", + "default.handlebars->45->705" ] }, { @@ -12089,7 +12119,7 @@ "zh-chs": "呼叫错误", "zh-cht": "呼叫錯誤", "xloc": [ - "default.handlebars->41->2993" + "default.handlebars->45->3008" ] }, { @@ -12109,7 +12139,7 @@ "ru": "Локальных полных доменных имен CIRA не может быть более 4. Игнорируем значение.", "tr": "4'ten fazla CIRA yerel FQDN'si olamaz. Değeri görmezden gelmek.", "xloc": [ - "default.handlebars->41->90" + "default.handlebars->45->90" ] }, { @@ -12137,9 +12167,9 @@ "agent-translations.json", "default-mobile.handlebars->11->113", "default-mobile.handlebars->dialog->idx_dlgButtonBar", - "default.handlebars->41->1838", - "default.handlebars->41->2982", - "default.handlebars->41->481", + "default.handlebars->45->1853", + "default.handlebars->45->2997", + "default.handlebars->45->484", "default.handlebars->container->dialog->idx_dlgButtonBar", "login-mobile.handlebars->dialog->idx_dlgButtonBar", "login.handlebars->dialog->idx_dlgButtonBar", @@ -12226,9 +12256,9 @@ "default-mobile.handlebars->11->592", "default-mobile.handlebars->11->597", "default-mobile.handlebars->11->599", - "default.handlebars->41->1474", - "default.handlebars->41->1479", - "default.handlebars->41->1481" + "default.handlebars->45->1489", + "default.handlebars->45->1494", + "default.handlebars->45->1496" ] }, { @@ -12254,7 +12284,7 @@ "zh-cht": "容量/速度", "xloc": [ "default-mobile.handlebars->11->590", - "default.handlebars->41->1472" + "default.handlebars->45->1487" ] }, { @@ -12279,7 +12309,7 @@ "zh-chs": "加泰罗尼亚文", "zh-cht": "加泰羅尼亞文", "xloc": [ - "default.handlebars->41->1567" + "default.handlebars->45->1582" ] }, { @@ -12304,7 +12334,7 @@ "zh-chs": "在这里为中心显示地图", "zh-cht": "在這裡為中心顯示地圖", "xloc": [ - "default.handlebars->41->761" + "default.handlebars->45->769" ] }, { @@ -12350,8 +12380,8 @@ "zh-chs": "证书将在 {0} 天后到期", "xloc": [ "default-mobile.handlebars->11->59", - "default.handlebars->41->107", - "default.handlebars->41->108" + "default.handlebars->45->108", + "default.handlebars->45->109" ] }, { @@ -12376,7 +12406,7 @@ "zh-chs": "查莫罗", "zh-cht": "查莫羅", "xloc": [ - "default.handlebars->41->1568" + "default.handlebars->45->1583" ] }, { @@ -12428,7 +12458,7 @@ "zh-chs": "更改{0}的电邮", "zh-cht": "更改{0}的電郵", "xloc": [ - "default.handlebars->41->2686" + "default.handlebars->45->2701" ] }, { @@ -12453,9 +12483,9 @@ "zh-chs": "更改组", "zh-cht": "更改群", "xloc": [ - "default.handlebars->41->1146", - "default.handlebars->41->1147", - "default.handlebars->41->912" + "default.handlebars->45->1161", + "default.handlebars->45->1162", + "default.handlebars->45->920" ] }, { @@ -12481,8 +12511,8 @@ "zh-cht": "更改密碼", "xloc": [ "default-mobile.handlebars->11->121", - "default.handlebars->41->1784", - "default.handlebars->41->2659" + "default.handlebars->45->1799", + "default.handlebars->45->2674" ] }, { @@ -12507,7 +12537,7 @@ "zh-chs": "更改{0}的密码", "zh-cht": "更改{0}的密碼", "xloc": [ - "default.handlebars->41->2695" + "default.handlebars->45->2710" ] }, { @@ -12532,7 +12562,7 @@ "zh-chs": "更改{0}的真实名称", "zh-cht": "更改{0}的真實名稱", "xloc": [ - "default.handlebars->41->2681" + "default.handlebars->45->2696" ] }, { @@ -12679,7 +12709,7 @@ "zh-chs": "更改该用户的密码", "zh-cht": "更改該用戶的密碼", "xloc": [ - "default.handlebars->41->2658" + "default.handlebars->45->2673" ] }, { @@ -12729,7 +12759,7 @@ "zh-chs": "在此处更改您的帐户电邮地址。", "zh-cht": "在此處更改你的帳戶電郵地址。", "xloc": [ - "default.handlebars->41->1771" + "default.handlebars->45->1786" ] }, { @@ -12754,7 +12784,7 @@ "zh-chs": "在下面的框中两次输入旧密码和新密码,以更改帐户密码。", "zh-cht": "在下面的框中兩次輸入舊密碼和新密碼,以更改帳戶密碼。", "xloc": [ - "default.handlebars->41->1777" + "default.handlebars->45->1792" ] }, { @@ -12779,7 +12809,7 @@ "zh-chs": "更改帐户凭据", "zh-cht": "帳戶憑證已更改", "xloc": [ - "default.handlebars->41->2271" + "default.handlebars->45->2286" ] }, { @@ -12799,7 +12829,7 @@ "ru": "Изменено отображаемое имя учетной записи на {0}.", "tr": "Hesap görünen adı {0} olarak değiştirildi.", "xloc": [ - "default.handlebars->41->2323" + "default.handlebars->45->2338" ] }, { @@ -12824,8 +12854,8 @@ "zh-chs": "{1}组中的设备{0}已更改:{2}", "zh-cht": "{1}組中的設備{0}已更改:{2}", "xloc": [ - "default.handlebars->41->2255", - "default.handlebars->41->2336" + "default.handlebars->45->2270", + "default.handlebars->45->2351" ] }, { @@ -12850,7 +12880,7 @@ "zh-chs": "语言从{1}更改为{2}", "zh-cht": "語言從{1}更改為{2}", "xloc": [ - "default.handlebars->41->2199" + "default.handlebars->45->2214" ] }, { @@ -12875,8 +12905,8 @@ "zh-chs": "已更改{0}的用户设备权限", "zh-cht": "已更改{0}的用戶設備權限", "xloc": [ - "default.handlebars->41->2257", - "default.handlebars->41->2278" + "default.handlebars->45->2272", + "default.handlebars->45->2293" ] }, { @@ -12922,7 +12952,7 @@ "zh-chs": "更改语言将需要刷新页面。", "zh-cht": "更改語言將需要刷新頁面。", "xloc": [ - "default.handlebars->41->1735" + "default.handlebars->45->1750" ] }, { @@ -12947,12 +12977,12 @@ "zh-chs": "聊天", "zh-cht": "聊天", "xloc": [ - "default.handlebars->41->1007", - "default.handlebars->41->1029", - "default.handlebars->41->2392", - "default.handlebars->41->2654", - "default.handlebars->41->2655", - "default.handlebars->41->901" + "default.handlebars->45->1021", + "default.handlebars->45->1043", + "default.handlebars->45->2407", + "default.handlebars->45->2669", + "default.handlebars->45->2670", + "default.handlebars->45->909" ] }, { @@ -12979,8 +13009,8 @@ "xloc": [ "default-mobile.handlebars->11->672", "default-mobile.handlebars->11->692", - "default.handlebars->41->2046", - "default.handlebars->41->2083" + "default.handlebars->45->2061", + "default.handlebars->45->2098" ] }, { @@ -13005,7 +13035,7 @@ "zh-chs": "聊天请求,点击这里接受。", "xloc": [ "default-mobile.handlebars->11->724", - "default.handlebars->41->2872" + "default.handlebars->45->2887" ] }, { @@ -13055,7 +13085,7 @@ "zh-chs": "车臣", "zh-cht": "車臣", "xloc": [ - "default.handlebars->41->1569" + "default.handlebars->45->1584" ] }, { @@ -13080,7 +13110,7 @@ "zh-chs": "检查并单击确定以清除错误日志。", "zh-cht": "檢查並單擊確定以清除錯誤日誌。", "xloc": [ - "default.handlebars->41->192" + "default.handlebars->45->193" ] }, { @@ -13105,7 +13135,7 @@ "zh-chs": "检查并单击确定以开始服务器自我更新。", "zh-cht": "檢查並單擊確定以開始伺服器自我更新。", "xloc": [ - "default.handlebars->41->187" + "default.handlebars->45->188" ] }, { @@ -13155,7 +13185,7 @@ "zh-chs": "检查您的手机并输入验证码。", "zh-cht": "檢查你的電話並輸入驗證碼。", "xloc": [ - "default.handlebars->41->238" + "default.handlebars->45->239" ] }, { @@ -13180,8 +13210,8 @@ "zh-chs": "检查...", "zh-cht": "檢查...", "xloc": [ - "default.handlebars->41->1535", - "default.handlebars->41->2987" + "default.handlebars->45->1550", + "default.handlebars->45->3002" ] }, { @@ -13206,7 +13236,7 @@ "zh-chs": "中文", "zh-cht": "中文", "xloc": [ - "default.handlebars->41->1570" + "default.handlebars->45->1585" ] }, { @@ -13231,7 +13261,7 @@ "zh-chs": "中文(香港)", "zh-cht": "中文(香港)", "xloc": [ - "default.handlebars->41->1571" + "default.handlebars->45->1586" ] }, { @@ -13256,7 +13286,7 @@ "zh-chs": "中文(中国)", "zh-cht": "中文(中國)", "xloc": [ - "default.handlebars->41->1572" + "default.handlebars->45->1587" ] }, { @@ -13281,7 +13311,7 @@ "zh-chs": "简体中文", "zh-cht": "簡體中文", "xloc": [ - "default.handlebars->41->1732" + "default.handlebars->45->1747" ] }, { @@ -13306,7 +13336,7 @@ "zh-chs": "中文(新加坡)", "zh-cht": "中文(新加坡)", "xloc": [ - "default.handlebars->41->1573" + "default.handlebars->45->1588" ] }, { @@ -13331,7 +13361,7 @@ "zh-chs": "中文(台湾)", "zh-cht": "中文(台灣)", "xloc": [ - "default.handlebars->41->1574" + "default.handlebars->45->1589" ] }, { @@ -13356,7 +13386,7 @@ "zh-chs": "繁体中文", "zh-cht": "繁體中文", "xloc": [ - "default.handlebars->41->1733" + "default.handlebars->45->1748" ] }, { @@ -13382,7 +13412,7 @@ "zh-cht": "ChromeOS", "xloc": [ "default-mobile.handlebars->11->23", - "default.handlebars->41->30" + "default.handlebars->45->30" ] }, { @@ -13407,7 +13437,7 @@ "zh-chs": "楚瓦什", "zh-cht": "楚瓦什", "xloc": [ - "default.handlebars->41->1575" + "default.handlebars->45->1590" ] }, { @@ -13461,11 +13491,11 @@ "default-mobile.handlebars->11->501", "default-mobile.handlebars->11->78", "default-mobile.handlebars->container->page_content->column_l->p10->p10console->consoleTable->1->4->1->1->1->0->5", - "default.handlebars->41->1374", - "default.handlebars->41->1376", - "default.handlebars->41->1378", - "default.handlebars->41->1380", - "default.handlebars->41->2193", + "default.handlebars->45->1389", + "default.handlebars->45->1391", + "default.handlebars->45->1393", + "default.handlebars->45->1395", + "default.handlebars->45->2208", "default.handlebars->container->column_l->p15->consoleTable->1->6->1->1->1->0->7", "default.handlebars->container->column_l->p41->3->1", "messenger.handlebars->xbottom->1->1->0->5", @@ -13497,7 +13527,7 @@ "zh-chs": "清除 RDP 凭据?", "xloc": [ "default-mobile.handlebars->11->399", - "default.handlebars->41->1190" + "default.handlebars->45->1205" ] }, { @@ -13522,7 +13552,7 @@ "zh-chs": "清除 SSH 凭据?", "xloc": [ "default-mobile.handlebars->11->397", - "default.handlebars->41->1188" + "default.handlebars->45->1203" ] }, { @@ -13547,7 +13577,7 @@ "zh-chs": "清除保安编码", "zh-cht": "清除保安編碼", "xloc": [ - "default.handlebars->41->218" + "default.handlebars->45->219" ] }, { @@ -13571,8 +13601,8 @@ "tr": "Temsilci çekirdeğini temizle", "zh-chs": "清除代理核心", "xloc": [ - "default.handlebars->41->654", - "default.handlebars->41->697" + "default.handlebars->45->657", + "default.handlebars->45->700" ] }, { @@ -13596,7 +13626,7 @@ "tr": "Seçilen cihazlarda temsilci çekirdeği temizlensin mi?", "zh-chs": "清除选定设备上的代理核心?", "xloc": [ - "default.handlebars->41->696" + "default.handlebars->45->699" ] }, { @@ -13622,7 +13652,7 @@ "zh-cht": "全部清除", "xloc": [ "default-mobile.handlebars->11->707", - "default.handlebars->41->2855" + "default.handlebars->45->2870" ] }, { @@ -13648,7 +13678,7 @@ "zh-cht": "清除搜索過濾器", "xloc": [ "default-mobile.handlebars->11->193", - "default.handlebars->41->338" + "default.handlebars->45->339" ] }, { @@ -13674,7 +13704,7 @@ "zh-cht": "清除核心", "xloc": [ "default-mobile.handlebars->11->613", - "default.handlebars->41->1496" + "default.handlebars->45->1511" ] }, { @@ -13699,7 +13729,7 @@ "zh-chs": "从应用程序中清除机密,然后重试。您只有几分钟的时间来输入正确的代码。", "zh-cht": "從應用程序中清除秘密,然後重試。你只有幾分鐘的時間來輸入正確的代碼。", "xloc": [ - "default.handlebars->41->208" + "default.handlebars->45->209" ] }, { @@ -13725,7 +13755,7 @@ "zh-cht": "清除此通知", "xloc": [ "default-mobile.handlebars->11->706", - "default.handlebars->41->2854" + "default.handlebars->45->2869" ] }, { @@ -13811,8 +13841,8 @@ "zh-chs": "单击此处编辑设备组名称", "zh-cht": "單擊此處編輯裝置群名稱", "xloc": [ - "default.handlebars->41->1849", - "default.handlebars->41->2138" + "default.handlebars->45->1864", + "default.handlebars->45->2153" ] }, { @@ -13837,7 +13867,7 @@ "zh-chs": "单击此处编辑服务器端设备名称", "zh-cht": "單擊此處編輯伺服器端裝置名稱", "xloc": [ - "default.handlebars->41->777" + "default.handlebars->45->785" ] }, { @@ -13862,7 +13892,7 @@ "zh-chs": "单击此处编辑用户组名称", "zh-cht": "單擊此處編輯用戶群名稱", "xloc": [ - "default.handlebars->41->2513" + "default.handlebars->45->2528" ] }, { @@ -13985,7 +14015,7 @@ "zh-cht": "單擊確定將驗證電郵發送到:", "xloc": [ "default-mobile.handlebars->11->106", - "default.handlebars->41->1768" + "default.handlebars->45->1783" ] }, { @@ -14078,8 +14108,8 @@ "zh-chs": "客户端控制模式(CCM)", "zh-cht": "客戶端控制模式(CCM)", "xloc": [ - "default-mobile.handlebars->11->568", - "default.handlebars->41->1450" + "default-mobile.handlebars->11->567", + "default.handlebars->45->1464" ] }, { @@ -14104,7 +14134,7 @@ "zh-chs": "客户编号", "zh-cht": "客戶編號", "xloc": [ - "default.handlebars->41->1831" + "default.handlebars->45->1846" ] }, { @@ -14129,7 +14159,7 @@ "zh-chs": "客户端启动的远程访问", "zh-cht": "客戶端啟動的遠程訪問", "xloc": [ - "default.handlebars->41->1974" + "default.handlebars->45->1989" ] }, { @@ -14154,7 +14184,7 @@ "zh-chs": "客户机密", "zh-cht": "客戶機密", "xloc": [ - "default.handlebars->41->1832" + "default.handlebars->45->1847" ] }, { @@ -14207,11 +14237,11 @@ "xloc": [ "agent-translations.json", "default-mobile.handlebars->11->76", - "default.handlebars->41->1291", - "default.handlebars->41->1350", - "default.handlebars->41->216", - "default.handlebars->41->224", - "default.handlebars->41->2981", + "default.handlebars->45->1306", + "default.handlebars->45->1365", + "default.handlebars->45->217", + "default.handlebars->45->225", + "default.handlebars->45->2996", "sharing.handlebars->11->52" ] }, @@ -14223,7 +14253,7 @@ "pt-br": "Sessão \\\"{0}\\\" multiplex de área de trabalho fechada, {1} segundo(s)", "ru": "Завершился сеанс мультиплексирования рабочего стола \\\"{0}\\\", {1} сек.", "xloc": [ - "default.handlebars->41->2343" + "default.handlebars->45->2358" ] }, { @@ -14248,7 +14278,7 @@ "zh-chs": "封闭式桌面多路复用会话,{0}秒", "zh-cht": "封閉式桌面多路復用會話,{0}秒", "xloc": [ - "default.handlebars->41->2204" + "default.handlebars->45->2219" ] }, { @@ -14273,7 +14303,7 @@ "zh-chs": "码", "zh-cht": "碼", "xloc": [ - "default.handlebars->41->302" + "default.handlebars->45->303" ] }, { @@ -14373,7 +14403,7 @@ "zh-chs": "命令", "zh-cht": "命令", "xloc": [ - "default.handlebars->41->594" + "default.handlebars->45->597" ] }, { @@ -14397,7 +14427,7 @@ "tr": "Komut satırı", "zh-chs": "命令行", "xloc": [ - "default.handlebars->41->114" + "default.handlebars->45->115" ] }, { @@ -14423,9 +14453,9 @@ "zh-cht": "指令", "xloc": [ "default-mobile.handlebars->11->694", - "default.handlebars->41->1009", - "default.handlebars->41->1031", - "default.handlebars->41->2085" + "default.handlebars->45->1023", + "default.handlebars->45->1045", + "default.handlebars->45->2100" ] }, { @@ -14450,8 +14480,8 @@ "zh-chs": "通用设备组", "zh-cht": "通用裝置群", "xloc": [ - "default.handlebars->41->2547", - "default.handlebars->41->2700" + "default.handlebars->45->2562", + "default.handlebars->45->2715" ] }, { @@ -14476,8 +14506,8 @@ "zh-chs": "通用设备", "zh-cht": "通用裝置", "xloc": [ - "default.handlebars->41->2553", - "default.handlebars->41->2712" + "default.handlebars->45->2568", + "default.handlebars->45->2727" ] }, { @@ -14502,7 +14532,7 @@ "zh-chs": "编译时间", "xloc": [ "default-mobile.handlebars->11->541", - "default.handlebars->41->1413" + "default.handlebars->45->1428" ] }, { @@ -14548,7 +14578,7 @@ "zh-chs": "压缩档案...", "zh-cht": "壓縮檔案...", "xloc": [ - "default.handlebars->41->1345", + "default.handlebars->45->1360", "sharing.handlebars->11->47" ] }, @@ -14597,14 +14627,14 @@ "xloc": [ "default-mobile.handlebars->11->394", "default-mobile.handlebars->11->644", - "default.handlebars->41->1141", - "default.handlebars->41->1150", - "default.handlebars->41->1985", - "default.handlebars->41->2421", - "default.handlebars->41->2503", - "default.handlebars->41->2569", - "default.handlebars->41->2698", - "default.handlebars->41->665" + "default.handlebars->45->1156", + "default.handlebars->45->1165", + "default.handlebars->45->2000", + "default.handlebars->45->2436", + "default.handlebars->45->2518", + "default.handlebars->45->2584", + "default.handlebars->45->2713", + "default.handlebars->45->668" ] }, { @@ -14651,7 +14681,7 @@ "zh-cht": "確認將1個副本複製到此位置?", "xloc": [ "default-mobile.handlebars->11->490", - "default.handlebars->41->1369", + "default.handlebars->45->1384", "sharing.handlebars->11->70" ] }, @@ -14677,7 +14707,7 @@ "zh-chs": "确认{0}个条目的复制到此位置?", "zh-cht": "確認{0}個條目的複製到此位置?", "xloc": [ - "default.handlebars->41->1368", + "default.handlebars->45->1383", "sharing.handlebars->11->69" ] }, @@ -14728,7 +14758,7 @@ "zh-chs": "确认删除选定的帐户?", "zh-cht": "確認刪除所選帳戶?", "xloc": [ - "default.handlebars->41->2420" + "default.handlebars->45->2435" ] }, { @@ -14775,7 +14805,7 @@ "zh-chs": "确认删除选定的用户组?", "zh-cht": "確認刪除所選用戶群?", "xloc": [ - "default.handlebars->41->2502" + "default.handlebars->45->2517" ] }, { @@ -14800,7 +14830,7 @@ "zh-chs": "确认删除用户{0}?", "zh-cht": "確認刪除用戶{0}?", "xloc": [ - "default.handlebars->41->2697" + "default.handlebars->45->2712" ] }, { @@ -14825,7 +14855,7 @@ "zh-chs": "确认删除用户“ {0} ”的成员身份?", "zh-cht": "確認刪除用戶“ {0} ”的成員身份?", "xloc": [ - "default.handlebars->41->2572" + "default.handlebars->45->2587" ] }, { @@ -14850,7 +14880,7 @@ "zh-chs": "确认删除用户组“ {0} ”的成员身份?", "zh-cht": "確認刪除用戶群“ {0} ”的成員身份?", "xloc": [ - "default.handlebars->41->2729" + "default.handlebars->45->2744" ] }, { @@ -14876,7 +14906,7 @@ "zh-cht": "確認將1個條目移動到此位置?", "xloc": [ "default-mobile.handlebars->11->492", - "default.handlebars->41->1371", + "default.handlebars->45->1386", "sharing.handlebars->11->72" ] }, @@ -14902,7 +14932,7 @@ "zh-chs": "确认将{0}个条目移到此位置?", "zh-cht": "確認將{0}個條目移到該位置?", "xloc": [ - "default.handlebars->41->1370", + "default.handlebars->45->1385", "sharing.handlebars->11->71" ] }, @@ -14953,7 +14983,7 @@ "zh-chs": "确认覆盖?", "zh-cht": "確認覆蓋?", "xloc": [ - "default.handlebars->41->2187" + "default.handlebars->45->2202" ] }, { @@ -14978,8 +15008,8 @@ "zh-chs": "确认删除设备“ {0} ”的访问权限?", "zh-cht": "確認刪除裝置“ {0} ”的訪問權限?", "xloc": [ - "default.handlebars->41->2562", - "default.handlebars->41->2720" + "default.handlebars->45->2577", + "default.handlebars->45->2735" ] }, { @@ -15004,8 +15034,8 @@ "zh-chs": "确认删除设备组“ {0} ”的访问权限?", "zh-cht": "確認刪除裝置群“ {0} ”的訪問權限?", "xloc": [ - "default.handlebars->41->2564", - "default.handlebars->41->2733" + "default.handlebars->45->2579", + "default.handlebars->45->2748" ] }, { @@ -15030,7 +15060,7 @@ "zh-chs": "确认删除用户“ {0} ”的访问权限?", "zh-cht": "確認刪除用戶“ {0} ”的訪問權限?", "xloc": [ - "default.handlebars->41->2722" + "default.handlebars->45->2737" ] }, { @@ -15055,7 +15085,7 @@ "zh-chs": "确认删除用户组“ {0} ”的访问权限?", "zh-cht": "確認刪除用戶群“ {0} ”的訪問權限?", "xloc": [ - "default.handlebars->41->2725" + "default.handlebars->45->2740" ] }, { @@ -15080,8 +15110,8 @@ "zh-chs": "确认删除访问权限?", "zh-cht": "確認刪除訪問權限?", "xloc": [ - "default.handlebars->41->2723", - "default.handlebars->41->2726" + "default.handlebars->45->2738", + "default.handlebars->45->2741" ] }, { @@ -15107,7 +15137,7 @@ "zh-cht": "確認刪除身份驗證軟體兩步登入?", "xloc": [ "default-mobile.handlebars->11->105", - "default.handlebars->41->1518" + "default.handlebars->45->1533" ] }, { @@ -15154,7 +15184,7 @@ "zh-chs": "确认删除设备共享“{0}”?", "zh-cht": "確認刪除設備共享“{0}”?", "xloc": [ - "default.handlebars->41->2718" + "default.handlebars->45->2733" ] }, { @@ -15222,7 +15252,7 @@ "tr": "Push kimlik doğrulama cihazının kaldırılması onaylansın mı?", "zh-chs": "确认移除推送认证设备?", "xloc": [ - "default.handlebars->41->1520" + "default.handlebars->45->1535" ] }, { @@ -15247,7 +15277,7 @@ "zh-chs": "确认删除用户“ {0} ”的权限?", "zh-cht": "確認刪除用戶“ {0} ”的權限?", "xloc": [ - "default.handlebars->41->2096" + "default.handlebars->45->2111" ] }, { @@ -15272,7 +15302,7 @@ "zh-chs": "确认删除用户组“ {0} ”的权限?", "zh-cht": "確認刪除用戶群“ {0} ”的權限?", "xloc": [ - "default.handlebars->41->2098" + "default.handlebars->45->2113" ] }, { @@ -15296,7 +15326,7 @@ "tr": "Seçili cihazların kaldırılması onaylansın mı?", "zh-chs": "确认移除所选设备?", "xloc": [ - "default.handlebars->41->659" + "default.handlebars->45->662" ] }, { @@ -15320,7 +15350,7 @@ "tr": "Bu giriş belirtecinin kaldırılması onaylansın mı?", "zh-chs": "确认删除此登录令牌?", "xloc": [ - "default.handlebars->41->1824" + "default.handlebars->45->1839" ] }, { @@ -15391,7 +15421,7 @@ "tr": "Seçilen {0} cihazın kaldırılması onaylansın mı?", "zh-chs": "确认移除 {0} 个选定的设备?", "xloc": [ - "default.handlebars->41->660" + "default.handlebars->45->663" ] }, { @@ -15417,7 +15447,7 @@ "zh-cht": "將{1}入口{2}中的{0}限製到此位置?", "xloc": [ "default-mobile.handlebars->11->158", - "default.handlebars->41->2188" + "default.handlebars->45->2203" ] }, { @@ -15446,8 +15476,8 @@ "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", "default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea1->1->3->connectbutton2span", - "default.handlebars->41->1887", - "default.handlebars->41->860", + "default.handlebars->45->1902", + "default.handlebars->45->868", "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1span", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->connectbutton2span", "default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3", @@ -15482,7 +15512,7 @@ "zh-chs": "全部连接", "zh-cht": "全部連接", "xloc": [ - "default.handlebars->41->427", + "default.handlebars->45->430", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->kvmListToolbar" ] }, @@ -15529,7 +15559,7 @@ "zh-chs": "连接到服务器", "zh-cht": "連接到伺服器", "xloc": [ - "default.handlebars->41->1978" + "default.handlebars->45->1993" ] }, { @@ -15626,7 +15656,6 @@ "zh-chs": "使用英特尔®AMT硬件KVM连接", "zh-cht": "使用英特爾®AMT硬件KVM連接", "xloc": [ - "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1hspan", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->connectbutton2hspan" ] }, @@ -15635,6 +15664,7 @@ "nl": "Verbinding maken via MeshAgent extern bureaublad", "pl": "Połącz używając zdalnego pulpitu MeshAgent", "ru": "Подключиться к удаленному рабочему столу с помощью MeshAgent", + "fr": "Se connecter en utilisant le bureau à distance MeshAgent", "xloc": [ "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1span" ] @@ -15644,10 +15674,19 @@ "nl": "Verbinding maken via RDP", "pl": "Połącz używając RDP", "ru": "Подключиться используя RDP", + "fr": "Se connecter par RDP", "xloc": [ "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1rspan" ] }, + { + "en": "Connect using hardware KVM", + "nl": "Verbinding maken via hardware KVM", + "pl": "Połącz za pomocą sprzętowego KVM", + "xloc": [ + "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1hspan" + ] + }, { "cs": "Připojeno", "da": "Forbundet", @@ -15671,8 +15710,8 @@ "zh-cht": "已連接", "xloc": [ "default-mobile.handlebars->11->4", - "default.handlebars->41->11", - "default.handlebars->41->389", + "default.handlebars->45->11", + "default.handlebars->45->390", "sharing.handlebars->11->4", "ssh.handlebars->3->4", "xterm.handlebars->9->4" @@ -15700,7 +15739,7 @@ "zh-chs": "已连接的英特尔®AMT", "zh-cht": "已連接的Intel® AMT", "xloc": [ - "default.handlebars->41->2909" + "default.handlebars->45->2924" ] }, { @@ -15725,7 +15764,7 @@ "zh-chs": "已连接的用户", "zh-cht": "已连接的用户", "xloc": [ - "default.handlebars->41->2914" + "default.handlebars->45->2929" ] }, { @@ -15772,7 +15811,7 @@ "zh-cht": "現在已連接", "xloc": [ "default-mobile.handlebars->11->536", - "default.handlebars->41->1408" + "default.handlebars->45->1423" ] }, { @@ -15887,11 +15926,11 @@ "default-mobile.handlebars->11->2", "default-mobile.handlebars->11->48", "default-mobile.handlebars->11->508", - "default.handlebars->41->1394", - "default.handlebars->41->362", - "default.handlebars->41->365", - "default.handlebars->41->430", - "default.handlebars->41->9", + "default.handlebars->45->1409", + "default.handlebars->45->363", + "default.handlebars->45->366", + "default.handlebars->45->433", + "default.handlebars->45->9", "sharing.handlebars->11->2", "sharing.handlebars->11->93", "ssh.handlebars->3->2", @@ -15941,7 +15980,7 @@ "zh-chs": "连接数量", "zh-cht": "連接數量", "xloc": [ - "default.handlebars->41->2940" + "default.handlebars->45->2955" ] }, { @@ -15966,8 +16005,8 @@ "zh-chs": "连接错误", "xloc": [ "default-mobile.handlebars->11->471", - "default.handlebars->41->1324", - "default.handlebars->41->1341", + "default.handlebars->45->1339", + "default.handlebars->45->1356", "login2.handlebars->7->32" ] }, @@ -15993,7 +16032,7 @@ "zh-chs": "连接转发器", "zh-cht": "連接轉發器", "xloc": [ - "default.handlebars->41->2975" + "default.handlebars->45->2990" ] }, { @@ -16069,9 +16108,9 @@ "zh-cht": "連接性", "xloc": [ "default-mobile.handlebars->11->318", - "default.handlebars->41->2145", - "default.handlebars->41->352", - "default.handlebars->41->877", + "default.handlebars->45->2160", + "default.handlebars->45->353", + "default.handlebars->45->885", "default.handlebars->container->column_l->p21->p21main->1->1->meshConnChartDiv->1" ] }, @@ -16092,7 +16131,7 @@ "ru": "Согласие", "tr": "Onay", "xloc": [ - "default.handlebars->41->2353" + "default.handlebars->45->2368" ] }, { @@ -16118,8 +16157,8 @@ "zh-cht": "控制台", "xloc": [ "default-mobile.handlebars->11->356", - "default.handlebars->41->1002", - "default.handlebars->41->1024", + "default.handlebars->45->1016", + "default.handlebars->45->1038", "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevConsole", "default.handlebars->container->topbar->1->1->ServerSubMenuSpan->ServerSubMenu->1->0->ServerConsole", "default.handlebars->contextMenu->cxconsole" @@ -16147,7 +16186,7 @@ "zh-chs": "控制台 -", "zh-cht": "控制台 -", "xloc": [ - "default.handlebars->41->778" + "default.handlebars->45->786" ] }, { @@ -16172,8 +16211,8 @@ "zh-chs": "控制", "zh-cht": "控制", "xloc": [ - "default.handlebars->41->1001", - "default.handlebars->41->1023", + "default.handlebars->45->1015", + "default.handlebars->45->1037", "messenger.handlebars->remoteImage->3->2" ] }, @@ -16224,7 +16263,7 @@ "zh-chs": "Cookie编码器", "zh-cht": "Cookie編碼器", "xloc": [ - "default.handlebars->41->2959" + "default.handlebars->45->2974" ] }, { @@ -16251,7 +16290,7 @@ "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->3", "default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->3", - "default.handlebars->41->567", + "default.handlebars->45->570", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3", "sharing.handlebars->p13->p13toolbar->fileArea2->3" @@ -16279,9 +16318,9 @@ "zh-chs": "将MAC地址复制到剪贴板", "zh-cht": "將MAC地址複製到剪貼板", "xloc": [ - "default.handlebars->41->152", - "default.handlebars->41->160", - "default.handlebars->41->163" + "default.handlebars->45->153", + "default.handlebars->45->161", + "default.handlebars->45->164" ] }, { @@ -16305,8 +16344,8 @@ "tr": "URL'yi panoya kopyala", "zh-chs": "将 URL 复制到剪贴板", "xloc": [ - "default.handlebars->41->576", - "default.handlebars->41->580" + "default.handlebars->45->579", + "default.handlebars->45->583" ] }, { @@ -16331,7 +16370,7 @@ "zh-chs": "将Windows 32位代理URL复制到剪贴板", "zh-cht": "將Windows 32位代理URL複製到剪貼板", "xloc": [ - "default.handlebars->41->557" + "default.handlebars->45->560" ] }, { @@ -16356,7 +16395,7 @@ "zh-chs": "将Windows 64位代理URL复制到剪贴板", "zh-cht": "將Windows 64位代理URL複製到剪貼板", "xloc": [ - "default.handlebars->41->561" + "default.handlebars->45->564" ] }, { @@ -16381,18 +16420,18 @@ "zh-chs": "将地址复制到剪贴板", "zh-cht": "將地址複製到剪貼板", "xloc": [ - "default.handlebars->41->141", - "default.handlebars->41->143", - "default.handlebars->41->145", - "default.handlebars->41->154", - "default.handlebars->41->156", - "default.handlebars->41->158", - "default.handlebars->41->166", - "default.handlebars->41->168", - "default.handlebars->41->170", - "default.handlebars->41->172", - "default.handlebars->41->174", - "default.handlebars->41->176" + "default.handlebars->45->142", + "default.handlebars->45->144", + "default.handlebars->45->146", + "default.handlebars->45->155", + "default.handlebars->45->157", + "default.handlebars->45->159", + "default.handlebars->45->167", + "default.handlebars->45->169", + "default.handlebars->45->171", + "default.handlebars->45->173", + "default.handlebars->45->175", + "default.handlebars->45->177" ] }, { @@ -16417,8 +16456,8 @@ "zh-chs": "将代理URL复制到剪贴板", "zh-cht": "將代理URL複製到剪貼板", "xloc": [ - "default.handlebars->41->593", - "default.handlebars->41->595" + "default.handlebars->45->596", + "default.handlebars->45->598" ] }, { @@ -16443,12 +16482,12 @@ "zh-chs": "复制连结到剪贴板", "zh-cht": "複製連結到剪貼板", "xloc": [ - "default.handlebars->41->2156", - "default.handlebars->41->2175", - "default.handlebars->41->294", - "default.handlebars->41->316", - "default.handlebars->41->318", - "default.handlebars->41->531" + "default.handlebars->45->2171", + "default.handlebars->45->2190", + "default.handlebars->45->295", + "default.handlebars->45->317", + "default.handlebars->45->319", + "default.handlebars->45->534" ] }, { @@ -16473,7 +16512,7 @@ "zh-chs": "将macOS代理URL复制到剪贴板", "zh-cht": "將macOS代理URL複製到剪貼板", "xloc": [ - "default.handlebars->41->571" + "default.handlebars->45->574" ] }, { @@ -16498,7 +16537,7 @@ "zh-chs": "将名称复制到剪贴板", "zh-cht": "將名稱複製到剪貼板", "xloc": [ - "default.handlebars->41->150" + "default.handlebars->45->151" ] }, { @@ -16525,8 +16564,8 @@ "xloc": [ "agentinvite.handlebars->container->column_l->5->linuxtab", "agentinvite.handlebars->container->column_l->5->linuxtab", - "default.handlebars->41->566", - "default.handlebars->41->589" + "default.handlebars->45->569", + "default.handlebars->45->592" ] }, { @@ -16551,7 +16590,7 @@ "zh-chs": "将有效代码复制到剪贴板", "zh-cht": "將有效代碼複製到剪貼板", "xloc": [ - "default.handlebars->41->219" + "default.handlebars->45->220" ] }, { @@ -16576,7 +16615,7 @@ "zh-chs": "复制:“{0}”到“{1}”", "zh-cht": "複製:“{0}”到“{1}”", "xloc": [ - "default.handlebars->41->2247" + "default.handlebars->45->2262" ] }, { @@ -16757,7 +16796,7 @@ "zh-chs": "核心服务器", "zh-cht": "核心伺服器", "xloc": [ - "default.handlebars->41->2958" + "default.handlebars->45->2973" ] }, { @@ -16782,7 +16821,7 @@ "zh-chs": "科西嘉文", "zh-cht": "科西嘉文", "xloc": [ - "default.handlebars->41->1576" + "default.handlebars->45->1591" ] }, { @@ -16828,7 +16867,7 @@ "zh-chs": "创建帐号", "zh-cht": "創建帳號", "xloc": [ - "default.handlebars->41->2470", + "default.handlebars->45->2485", "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->createpanel->1->1->9->1->12->1->1", "login.handlebars->container->column_l->centralTable->1->0->logincell->createpanel->1->9->1->12->1->1", "login2.handlebars->centralTable->1->0->logincell->createpanel->createpanelform->9->1->12->1->1" @@ -16901,8 +16940,8 @@ "tr": "Giriş Simgesi Oluştur", "zh-chs": "创建登录令牌", "xloc": [ - "default.handlebars->41->1761", - "default.handlebars->41->319" + "default.handlebars->45->1776", + "default.handlebars->45->320" ] }, { @@ -16927,7 +16966,7 @@ "zh-chs": "创建用户组", "zh-cht": "創建用戶群", "xloc": [ - "default.handlebars->41->2510" + "default.handlebars->45->2525" ] }, { @@ -16952,7 +16991,7 @@ "zh-chs": "创建连结以与访客共享此设备", "zh-cht": "創建鏈結以與訪客共享此裝置", "xloc": [ - "default.handlebars->41->904" + "default.handlebars->45->912" ] }, { @@ -16977,7 +17016,7 @@ "zh-chs": "使用以下选项创建一个新的设备组。", "zh-cht": "使用以下選項創建一個新的裝置群。", "xloc": [ - "default.handlebars->41->1791" + "default.handlebars->45->1806" ] }, { @@ -17002,7 +17041,7 @@ "zh-chs": "创建一个新的设备组。", "zh-cht": "創建一個新的裝置群。", "xloc": [ - "default.handlebars->41->355" + "default.handlebars->45->356" ] }, { @@ -17026,7 +17065,7 @@ "tr": "Hesabınıza alternatif giriş olarak kullanılabilecek geçici bir kullanıcı adı ve şifre oluşturun. Bu, araçların veya diğer hizmetlerin hesabınıza erişmesine izin vermek için kullanışlıdır.", "zh-chs": "创建一个临时用户名和密码,可用作您帐户的替代登录名。这对于允许工具或其他服务访问您的帐户非常有用。", "xloc": [ - "default.handlebars->41->1741" + "default.handlebars->45->1756" ] }, { @@ -17051,7 +17090,7 @@ "zh-chs": "创建文件夹(如果不存在)?", "zh-cht": "創建文件夾(如果不存在)?", "xloc": [ - "default.handlebars->41->691" + "default.handlebars->45->694" ] }, { @@ -17076,7 +17115,7 @@ "zh-chs": "创建文件夹:“{0}”", "zh-cht": "創建文件夾:“{0}”", "xloc": [ - "default.handlebars->41->2240" + "default.handlebars->45->2255" ] }, { @@ -17125,7 +17164,7 @@ "zh-chs": "通过导入以下格式的JSON档案一次创建多个帐户:", "zh-cht": "通過導入以下格式的JSON檔案一次創建多個帳戶:", "xloc": [ - "default.handlebars->41->2434" + "default.handlebars->45->2449" ] }, { @@ -17141,7 +17180,7 @@ "ja": "一つ作る", "ko": "한 가지 만들기", "nl": "Creëer er een", - "pl": "Utwórz nowy", + "pl": "Utwórz nowe", "pt": "Crie um", "pt-br": "Crie um", "ru": "Создать", @@ -17177,7 +17216,7 @@ "zh-chs": "创建的设备组:{0}", "zh-cht": "創建的設備組:{0}", "xloc": [ - "default.handlebars->41->2251" + "default.handlebars->45->2266" ] }, { @@ -17202,7 +17241,7 @@ "zh-chs": "创建一个链接,该链接允许没有帐户的访客在有限的时间内远程控制此设备。", "zh-cht": "創建一個鏈接,該鏈接允許沒有帳戶的訪客在有限的時間內遠程控制此設備。", "xloc": [ - "default.handlebars->41->1047" + "default.handlebars->45->1062" ] }, { @@ -17271,7 +17310,7 @@ "zh-chs": "创建", "zh-cht": "創建", "xloc": [ - "default.handlebars->41->2614" + "default.handlebars->45->2629" ] }, { @@ -17296,7 +17335,7 @@ "zh-chs": "创建时间", "zh-cht": "創作時間", "xloc": [ - "default.handlebars->41->1867" + "default.handlebars->45->1882" ] }, { @@ -17329,7 +17368,7 @@ { "cs": "Tvůrce", "da": "Oprettet af", - "de": "Schöpfer", + "de": "Ersteller", "en": "Creator", "es": "Creado por", "fi": "Luoja", @@ -17348,8 +17387,8 @@ "zh-chs": "创建者", "zh-cht": "創作者", "xloc": [ - "default.handlebars->41->1865", - "default.handlebars->41->1866" + "default.handlebars->45->1880", + "default.handlebars->45->1881" ] }, { @@ -17375,9 +17414,9 @@ "zh-cht": "證書", "xloc": [ "default-mobile.handlebars->11->330", - "default.handlebars->41->1213", - "default.handlebars->41->1829", - "default.handlebars->41->889" + "default.handlebars->45->1228", + "default.handlebars->45->1844", + "default.handlebars->45->897" ] }, { @@ -17402,7 +17441,7 @@ "zh-chs": "克里语", "zh-cht": "克里語", "xloc": [ - "default.handlebars->41->1577" + "default.handlebars->45->1592" ] }, { @@ -17427,7 +17466,7 @@ "zh-chs": "克罗地亚文", "zh-cht": "克羅地亞文", "xloc": [ - "default.handlebars->41->1578" + "default.handlebars->45->1593" ] }, { @@ -17506,9 +17545,9 @@ "xloc": [ "default-mobile.handlebars->11->432", "default-mobile.handlebars->11->436", - "default.handlebars->41->1254", - "default.handlebars->41->1258", - "default.handlebars->41->60", + "default.handlebars->45->1269", + "default.handlebars->45->1273", + "default.handlebars->45->60", "sharing.handlebars->11->24" ] }, @@ -17657,7 +17696,7 @@ "zh-chs": "当前版本", "zh-cht": "當前版本", "xloc": [ - "default.handlebars->41->181" + "default.handlebars->45->182" ] }, { @@ -17682,7 +17721,7 @@ "zh-chs": "当前密码不正确。", "xloc": [ "default-mobile.handlebars->11->734", - "default.handlebars->41->2882" + "default.handlebars->45->2897" ] }, { @@ -17785,7 +17824,7 @@ "zh-chs": "捷克文", "zh-cht": "捷克文", "xloc": [ - "default.handlebars->41->1579" + "default.handlebars->45->1594" ] }, { @@ -17810,7 +17849,7 @@ "zh-chs": "DNS suffix", "zh-cht": "DNS suffix", "xloc": [ - "default.handlebars->41->149" + "default.handlebars->45->150" ] }, { @@ -17830,7 +17869,7 @@ "ru": "Ежедневно", "tr": "Günlük", "xloc": [ - "default.handlebars->41->279" + "default.handlebars->45->280" ] }, { @@ -17855,7 +17894,7 @@ "zh-chs": "丹麦文", "zh-cht": "丹麥文", "xloc": [ - "default.handlebars->41->1580" + "default.handlebars->45->1595" ] }, { @@ -17880,7 +17919,7 @@ "zh-chs": "黑暗模式", "xloc": [ "default-mobile.handlebars->11->92", - "default.handlebars->41->64" + "default.handlebars->45->64" ] }, { @@ -17905,7 +17944,7 @@ "zh-chs": "数据通道", "zh-cht": "數據通道", "xloc": [ - "default.handlebars->41->1211", + "default.handlebars->45->1226", "sharing.handlebars->11->11" ] }, @@ -17931,7 +17970,7 @@ "zh-chs": "日期和时间", "zh-cht": "日期和時間", "xloc": [ - "default.handlebars->41->1738" + "default.handlebars->45->1753" ] }, { @@ -17957,9 +17996,9 @@ "zh-cht": "天", "xloc": [ "default-mobile.handlebars->11->384", - "default.handlebars->41->1125", - "default.handlebars->41->2779", - "default.handlebars->41->2782" + "default.handlebars->45->1140", + "default.handlebars->45->2794", + "default.handlebars->45->2797" ] }, { @@ -17984,8 +18023,8 @@ "zh-chs": "停用", "zh-cht": "停用", "xloc": [ - "default.handlebars->41->1897", - "default.handlebars->41->1957" + "default.handlebars->45->1912", + "default.handlebars->45->1972" ] }, { @@ -18010,7 +18049,7 @@ "zh-chs": "如果设置停用CCM", "zh-cht": "如果設置停用CCM", "xloc": [ - "default.handlebars->41->1969" + "default.handlebars->45->1984" ] }, { @@ -18058,7 +18097,7 @@ "zh-cht": "沉睡", "xloc": [ "default-mobile.handlebars->11->241", - "default.handlebars->41->606" + "default.handlebars->45->609" ] }, { @@ -18083,10 +18122,10 @@ "zh-chs": "默认", "zh-cht": "默認", "xloc": [ - "default.handlebars->41->2457", - "default.handlebars->41->2506", - "default.handlebars->41->2517", - "default.handlebars->41->2590" + "default.handlebars->45->2472", + "default.handlebars->45->2521", + "default.handlebars->45->2532", + "default.handlebars->45->2605" ] }, { @@ -18111,7 +18150,7 @@ "zh-chs": "德尔", "xloc": [ "default-mobile.handlebars->11->420", - "default.handlebars->41->1242" + "default.handlebars->45->1257" ] }, { @@ -18141,9 +18180,9 @@ "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->1", "default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->1", "default-mobile.handlebars->dialog->idx_dlgButtonBar->5", - "default.handlebars->41->1360", - "default.handlebars->41->2182", - "default.handlebars->41->748", + "default.handlebars->45->1375", + "default.handlebars->45->2197", + "default.handlebars->45->756", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3", "default.handlebars->container->dialog->idx_dlgButtonBar->5", @@ -18179,7 +18218,7 @@ "zh-cht": "刪除帳戶", "xloc": [ "default-mobile.handlebars->11->115", - "default.handlebars->41->1776" + "default.handlebars->45->1791" ] }, { @@ -18204,7 +18243,7 @@ "zh-chs": "删除帐户", "zh-cht": "刪除帳戶", "xloc": [ - "default.handlebars->41->2422" + "default.handlebars->45->2437" ] }, { @@ -18230,7 +18269,7 @@ "zh-cht": "刪除裝置", "xloc": [ "default-mobile.handlebars->11->339", - "default.handlebars->41->914" + "default.handlebars->45->922" ] }, { @@ -18254,7 +18293,7 @@ "tr": "Cihazları Sil", "zh-chs": "删除设备", "xloc": [ - "default.handlebars->41->666" + "default.handlebars->45->669" ] }, { @@ -18281,8 +18320,8 @@ "xloc": [ "default-mobile.handlebars->11->642", "default-mobile.handlebars->11->645", - "default.handlebars->41->1945", - "default.handlebars->41->1986" + "default.handlebars->45->1960", + "default.handlebars->45->2001" ] }, { @@ -18308,7 +18347,7 @@ "zh-cht": "刪除節點", "xloc": [ "default-mobile.handlebars->11->392", - "default.handlebars->41->1151" + "default.handlebars->45->1166" ] }, { @@ -18355,7 +18394,7 @@ "zh-chs": "删除用户", "zh-cht": "刪除用戶", "xloc": [ - "default.handlebars->41->2657" + "default.handlebars->45->2672" ] }, { @@ -18380,8 +18419,8 @@ "zh-chs": "删除用户群组", "zh-cht": "刪除用戶群組", "xloc": [ - "default.handlebars->41->2558", - "default.handlebars->41->2570" + "default.handlebars->45->2573", + "default.handlebars->45->2585" ] }, { @@ -18406,7 +18445,7 @@ "zh-chs": "删除用户群组", "zh-cht": "刪除用戶群組", "xloc": [ - "default.handlebars->41->2504" + "default.handlebars->45->2519" ] }, { @@ -18431,7 +18470,7 @@ "zh-chs": "删除用户{0}", "zh-cht": "刪除用戶{0}", "xloc": [ - "default.handlebars->41->2696" + "default.handlebars->45->2711" ] }, { @@ -18457,7 +18496,7 @@ "zh-cht": "刪除帳戶", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->3->p3AccountActions->p2AccountActions->3->9->0", - "default.handlebars->41->2418", + "default.handlebars->45->2433", "default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->p2AccountPassActions->7" ] }, @@ -18483,7 +18522,7 @@ "zh-chs": "删除设备", "zh-cht": "刪除裝置", "xloc": [ - "default.handlebars->41->652" + "default.handlebars->45->655" ] }, { @@ -18508,7 +18547,7 @@ "zh-chs": "删除群组", "zh-cht": "刪除群組", "xloc": [ - "default.handlebars->41->2500" + "default.handlebars->45->2515" ] }, { @@ -18533,7 +18572,7 @@ "zh-chs": "删除项目?", "zh-cht": "刪除項目?", "xloc": [ - "default.handlebars->41->749" + "default.handlebars->45->757" ] }, { @@ -18558,7 +18597,7 @@ "zh-chs": "递归删除:“{0}”,{1}个元素已删除", "zh-cht": "遞歸刪除:“{0}”,{1}個元素已刪除", "xloc": [ - "default.handlebars->41->2242" + "default.handlebars->45->2257" ] }, { @@ -18585,8 +18624,8 @@ "xloc": [ "default-mobile.handlebars->11->155", "default-mobile.handlebars->11->484", - "default.handlebars->41->1362", - "default.handlebars->41->2184", + "default.handlebars->45->1377", + "default.handlebars->45->2199", "sharing.handlebars->11->63" ] }, @@ -18612,7 +18651,7 @@ "zh-chs": "删除用户群组{0}?", "zh-cht": "刪除用戶群組{0}?", "xloc": [ - "default.handlebars->41->2568" + "default.handlebars->45->2583" ] }, { @@ -18639,8 +18678,8 @@ "xloc": [ "default-mobile.handlebars->11->154", "default-mobile.handlebars->11->483", - "default.handlebars->41->1361", - "default.handlebars->41->2183", + "default.handlebars->45->1376", + "default.handlebars->45->2198", "sharing.handlebars->11->62" ] }, @@ -18691,7 +18730,7 @@ "zh-chs": "删除:“{0}”", "zh-cht": "刪除:“{0}”", "xloc": [ - "default.handlebars->41->2241" + "default.handlebars->45->2256" ] }, { @@ -18716,7 +18755,7 @@ "zh-chs": "删除:“{0}”,{1}个元素已删除", "zh-cht": "刪除:“{0}”,已刪除{1}個元素", "xloc": [ - "default.handlebars->41->2243" + "default.handlebars->45->2258" ] }, { @@ -18742,7 +18781,7 @@ "zh-cht": "被拒絕", "xloc": [ "default-mobile.handlebars->11->407", - "default.handlebars->41->1198", + "default.handlebars->45->1213", "sharing.handlebars->11->29", "sharing.handlebars->11->7" ] @@ -18887,20 +18926,20 @@ "default-mobile.handlebars->11->549", "default-mobile.handlebars->11->628", "default-mobile.handlebars->11->651", - "default.handlebars->41->1193", - "default.handlebars->41->1421", - "default.handlebars->41->1431", - "default.handlebars->41->148", - "default.handlebars->41->1801", - "default.handlebars->41->1858", - "default.handlebars->41->1992", - "default.handlebars->41->2351", - "default.handlebars->41->2509", - "default.handlebars->41->2519", - "default.handlebars->41->2520", - "default.handlebars->41->2566", - "default.handlebars->41->789", - "default.handlebars->41->790", + "default.handlebars->45->1208", + "default.handlebars->45->1436", + "default.handlebars->45->1446", + "default.handlebars->45->149", + "default.handlebars->45->1816", + "default.handlebars->45->1873", + "default.handlebars->45->2007", + "default.handlebars->45->2366", + "default.handlebars->45->2524", + "default.handlebars->45->2534", + "default.handlebars->45->2535", + "default.handlebars->45->2581", + "default.handlebars->45->797", + "default.handlebars->45->798", "default.handlebars->container->column_l->p42->p42tbl->1->0->3" ] }, @@ -18949,16 +18988,16 @@ "zh-cht": "桌面", "xloc": [ "default-mobile.handlebars->11->352", - "default.handlebars->41->1049", - "default.handlebars->41->1297", - "default.handlebars->41->1925", - "default.handlebars->41->1998", - "default.handlebars->41->2753", - "default.handlebars->41->2812", - "default.handlebars->41->2843", - "default.handlebars->41->2934", - "default.handlebars->41->754", - "default.handlebars->41->965", + "default.handlebars->45->1064", + "default.handlebars->45->1312", + "default.handlebars->45->1940", + "default.handlebars->45->2013", + "default.handlebars->45->2768", + "default.handlebars->45->2827", + "default.handlebars->45->2858", + "default.handlebars->45->2949", + "default.handlebars->45->762", + "default.handlebars->45->979", "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevDesktop", "default.handlebars->contextMenu->cxdesktop", "sharing.handlebars->11->23", @@ -18986,9 +19025,9 @@ "tr": "Masaüstü + Dosyalar", "zh-chs": "桌面 + 文件", "xloc": [ - "default.handlebars->41->1052", - "default.handlebars->41->1929", - "default.handlebars->41->969" + "default.handlebars->45->1067", + "default.handlebars->45->1944", + "default.handlebars->45->983" ] }, { @@ -19012,8 +19051,8 @@ "tr": "Masaüstü + Terminal", "zh-chs": "桌面 + 终端", "xloc": [ - "default.handlebars->41->1926", - "default.handlebars->41->966" + "default.handlebars->45->1941", + "default.handlebars->45->980" ] }, { @@ -19037,9 +19076,9 @@ "tr": "Masaüstü + Terminal + Dosyalar", "zh-chs": "桌面 + 终端 + 文件", "xloc": [ - "default.handlebars->41->1054", - "default.handlebars->41->1930", - "default.handlebars->41->970" + "default.handlebars->45->1069", + "default.handlebars->45->1945", + "default.handlebars->45->984" ] }, { @@ -19088,7 +19127,7 @@ "tr": "Masaüstü Multiplex", "zh-chs": "桌面复用", "xloc": [ - "default.handlebars->41->2939" + "default.handlebars->45->2954" ] }, { @@ -19113,10 +19152,10 @@ "zh-chs": "桌面通知", "zh-cht": "桌面通知", "xloc": [ - "default.handlebars->41->1878", - "default.handlebars->41->2527", - "default.handlebars->41->2629", - "default.handlebars->41->851" + "default.handlebars->45->1893", + "default.handlebars->45->2542", + "default.handlebars->45->2644", + "default.handlebars->45->859" ] }, { @@ -19141,10 +19180,10 @@ "zh-chs": "桌面提示", "zh-cht": "桌面提示", "xloc": [ - "default.handlebars->41->1877", - "default.handlebars->41->2526", - "default.handlebars->41->2628", - "default.handlebars->41->850" + "default.handlebars->45->1892", + "default.handlebars->45->2541", + "default.handlebars->45->2643", + "default.handlebars->45->858" ] }, { @@ -19169,10 +19208,10 @@ "zh-chs": "桌面提示+工具栏", "zh-cht": "桌面提示+工具欄", "xloc": [ - "default.handlebars->41->1875", - "default.handlebars->41->2524", - "default.handlebars->41->2626", - "default.handlebars->41->848" + "default.handlebars->45->1890", + "default.handlebars->45->2539", + "default.handlebars->45->2641", + "default.handlebars->45->856" ] }, { @@ -19196,7 +19235,7 @@ "tr": "Masaüstü Oturumu", "zh-chs": "桌面会话", "xloc": [ - "default.handlebars->41->2746" + "default.handlebars->45->2761" ] }, { @@ -19294,10 +19333,10 @@ "zh-chs": "桌面工具栏", "zh-cht": "桌面工具欄", "xloc": [ - "default.handlebars->41->1876", - "default.handlebars->41->2525", - "default.handlebars->41->2627", - "default.handlebars->41->849" + "default.handlebars->45->1891", + "default.handlebars->45->2540", + "default.handlebars->45->2642", + "default.handlebars->45->857" ] }, { @@ -19321,7 +19360,7 @@ "tr": "Yalnızca Masaüstü Görünümü", "zh-chs": "仅桌面视图", "xloc": [ - "default.handlebars->41->2602" + "default.handlebars->45->2617" ] }, { @@ -19345,7 +19384,7 @@ "tr": "Masaüstü, Yalnızca görüntüleme", "zh-chs": "桌面,仅查看", "xloc": [ - "default.handlebars->41->1055" + "default.handlebars->45->1070" ] }, { @@ -19370,7 +19409,7 @@ "zh-chs": "桌面时段", "zh-cht": "桌面時段", "xloc": [ - "default.handlebars->41->1296" + "default.handlebars->45->1311" ] }, { @@ -19447,7 +19486,7 @@ "zh-cht": "細節", "xloc": [ "default-mobile.handlebars->11->355", - "default.handlebars->41->2088", + "default.handlebars->45->2103", "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevInfo", "default.handlebars->contextMenu->cxdetails" ] @@ -19500,13 +19539,13 @@ "zh-cht": "裝置", "xloc": [ "default-mobile.handlebars->11->544", - "default.handlebars->41->1416", - "default.handlebars->41->1524", - "default.handlebars->41->2026", - "default.handlebars->41->266", - "default.handlebars->41->2715", - "default.handlebars->41->2778", - "default.handlebars->41->2796", + "default.handlebars->45->1431", + "default.handlebars->45->1539", + "default.handlebars->45->2041", + "default.handlebars->45->267", + "default.handlebars->45->2730", + "default.handlebars->45->2793", + "default.handlebars->45->2811", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSort->sortselect->5" ] }, @@ -19534,7 +19573,7 @@ "xloc": [ "default-mobile.handlebars->11->373", "default-mobile.handlebars->11->382", - "default.handlebars->41->1108" + "default.handlebars->45->1123" ] }, { @@ -19583,7 +19622,7 @@ "tr": "Cihaz Açıklaması", "zh-chs": "设备描述", "xloc": [ - "default.handlebars->41->322" + "default.handlebars->45->323" ] }, { @@ -19607,7 +19646,7 @@ "tr": "Cihaz Ayrıntıları", "zh-chs": "设备详情", "xloc": [ - "default.handlebars->41->2050" + "default.handlebars->45->2065" ] }, { @@ -19659,17 +19698,17 @@ "xloc": [ "agent-translations.json", "default-mobile.handlebars->11->712", - "default.handlebars->41->2021", - "default.handlebars->41->2024", - "default.handlebars->41->2025", - "default.handlebars->41->2368", - "default.handlebars->41->2550", - "default.handlebars->41->2556", - "default.handlebars->41->2703", - "default.handlebars->41->2762", - "default.handlebars->41->2785", - "default.handlebars->41->2799", - "default.handlebars->41->2860" + "default.handlebars->45->2036", + "default.handlebars->45->2039", + "default.handlebars->45->2040", + "default.handlebars->45->2383", + "default.handlebars->45->2565", + "default.handlebars->45->2571", + "default.handlebars->45->2718", + "default.handlebars->45->2777", + "default.handlebars->45->2800", + "default.handlebars->45->2814", + "default.handlebars->45->2875" ] }, { @@ -19695,7 +19734,7 @@ "zh-cht": "裝置群用戶", "xloc": [ "default-mobile.handlebars->11->701", - "default.handlebars->41->2094" + "default.handlebars->45->2109" ] }, { @@ -19721,11 +19760,11 @@ "zh-cht": "裝置群", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->3->3", - "default.handlebars->41->2384", - "default.handlebars->41->2494", - "default.handlebars->41->2537", - "default.handlebars->41->2623", - "default.handlebars->41->2912", + "default.handlebars->45->2399", + "default.handlebars->45->2509", + "default.handlebars->45->2552", + "default.handlebars->45->2638", + "default.handlebars->45->2927", "default.handlebars->container->column_l->p2->p2info->9" ] }, @@ -19751,7 +19790,7 @@ "zh-chs": "设备信息导出", "zh-cht": "裝置訊息輸出", "xloc": [ - "default.handlebars->41->708" + "default.handlebars->45->712" ] }, { @@ -19776,7 +19815,7 @@ "zh-chs": "设备位置", "zh-cht": "裝置位置", "xloc": [ - "default.handlebars->41->1152" + "default.handlebars->45->1167" ] }, { @@ -19801,7 +19840,7 @@ "zh-chs": "设备消息", "zh-cht": "裝置訊息", "xloc": [ - "default.handlebars->41->1039" + "default.handlebars->45->1053" ] }, { @@ -19827,10 +19866,10 @@ "zh-cht": "裝置名稱", "xloc": [ "default-mobile.handlebars->11->400", - "default.handlebars->41->1191", - "default.handlebars->41->2761", - "default.handlebars->41->446", - "default.handlebars->41->455", + "default.handlebars->45->1206", + "default.handlebars->45->2776", + "default.handlebars->45->449", + "default.handlebars->45->458", "player.handlebars->3->25" ] }, @@ -19856,8 +19895,8 @@ "zh-chs": "设备通知", "zh-cht": "裝置通知", "xloc": [ - "default.handlebars->41->1044", - "default.handlebars->41->687" + "default.handlebars->45->1059", + "default.handlebars->45->690" ] }, { @@ -19905,7 +19944,7 @@ "tr": "Cihaz İtme", "zh-chs": "设备推送", "xloc": [ - "default.handlebars->41->2642" + "default.handlebars->45->2657" ] }, { @@ -19973,8 +20012,8 @@ "zh-chs": "设备共享链接", "zh-cht": "設備共享鏈接", "xloc": [ - "default.handlebars->41->1922", - "default.handlebars->41->962" + "default.handlebars->45->1937", + "default.handlebars->45->976" ] }, { @@ -20047,9 +20086,9 @@ "default-mobile.handlebars->11->282", "default-mobile.handlebars->11->284", "default-mobile.handlebars->11->286", - "default.handlebars->41->793", - "default.handlebars->41->795", - "default.handlebars->41->797" + "default.handlebars->45->801", + "default.handlebars->45->803", + "default.handlebars->45->805" ] }, { @@ -20073,7 +20112,7 @@ "tr": "Cihaz Görünümü Sütunları", "zh-chs": "设备视图列", "xloc": [ - "default.handlebars->41->329" + "default.handlebars->45->330" ] }, { @@ -20098,11 +20137,11 @@ "zh-chs": "设备连接。", "zh-cht": "裝置連接。", "xloc": [ - "default.handlebars->41->1764", - "default.handlebars->41->2121", - "default.handlebars->41->2125", - "default.handlebars->41->986", - "default.handlebars->41->990" + "default.handlebars->45->1000", + "default.handlebars->45->1004", + "default.handlebars->45->1779", + "default.handlebars->45->2136", + "default.handlebars->45->2140" ] }, { @@ -20127,11 +20166,11 @@ "zh-chs": "设备断开连接。", "zh-cht": "裝置斷開連接。", "xloc": [ - "default.handlebars->41->1765", - "default.handlebars->41->2122", - "default.handlebars->41->2126", - "default.handlebars->41->987", - "default.handlebars->41->991" + "default.handlebars->45->1001", + "default.handlebars->45->1005", + "default.handlebars->45->1780", + "default.handlebars->45->2137", + "default.handlebars->45->2141" ] }, { @@ -20156,7 +20195,7 @@ "zh-chs": "创建的设备组:{0}", "zh-cht": "設備組已創建:{0}", "xloc": [ - "default.handlebars->41->2272" + "default.handlebars->45->2287" ] }, { @@ -20181,7 +20220,7 @@ "zh-chs": "设备组已删除:{0}", "zh-cht": "設備組已刪除:{0}", "xloc": [ - "default.handlebars->41->2273" + "default.handlebars->45->2288" ] }, { @@ -20206,7 +20245,7 @@ "zh-chs": "设备组成员身份已更改:{0}", "zh-cht": "設備組成員身份已更改:{0}", "xloc": [ - "default.handlebars->41->2274" + "default.handlebars->45->2289" ] }, { @@ -20232,7 +20271,7 @@ "zh-cht": "其他裝置群管理員可以查看和更改裝置群註釋。", "xloc": [ "default-mobile.handlebars->11->380", - "default.handlebars->41->1036" + "default.handlebars->45->1050" ] }, { @@ -20257,7 +20296,7 @@ "zh-chs": "设备组通知已更改", "zh-cht": "設備組通知已更改", "xloc": [ - "default.handlebars->41->2269" + "default.handlebars->45->2284" ] }, { @@ -20282,7 +20321,7 @@ "zh-chs": "未删除的设备组:{0}", "zh-cht": "未刪除的設備組:{0}", "xloc": [ - "default.handlebars->41->2252" + "default.handlebars->45->2267" ] }, { @@ -20302,7 +20341,7 @@ "ru": "Группа устройств {0} изменена: {1}", "tr": "{0} cihaz grubu değiştirildi: {1}", "xloc": [ - "default.handlebars->41->2338" + "default.handlebars->45->2353" ] }, { @@ -20311,7 +20350,7 @@ "pl": "Grupy urządzeń to urządzenie jest bramką dla", "ru": "Группы устройств, для которых это устройство является релеем", "xloc": [ - "default.handlebars->41->890" + "default.handlebars->45->898" ] }, { @@ -20338,8 +20377,8 @@ "xloc": [ "default-mobile.handlebars->11->199", "default-mobile.handlebars->11->269", - "default.handlebars->41->370", - "default.handlebars->41->775" + "default.handlebars->45->371", + "default.handlebars->45->783" ] }, { @@ -20360,7 +20399,7 @@ "tr": "Aygıt meşgul", "xloc": [ "default-mobile.handlebars->11->205", - "default.handlebars->41->401" + "default.handlebars->45->404" ] }, { @@ -20385,7 +20424,7 @@ "zh-chs": "检测到设备,但无法获得电源状态。", "zh-cht": "檢測到裝置,但無法獲得電源狀態。", "xloc": [ - "default.handlebars->41->611" + "default.handlebars->45->614" ] }, { @@ -20411,7 +20450,7 @@ "zh-cht": "裝置正在休眠(S4)", "xloc": [ "default-mobile.handlebars->11->250", - "default.handlebars->41->619" + "default.handlebars->45->622" ] }, { @@ -20437,7 +20476,7 @@ "zh-cht": "裝置處於深度睡眠狀態(S3)", "xloc": [ "default-mobile.handlebars->11->249", - "default.handlebars->41->618" + "default.handlebars->45->621" ] }, { @@ -20462,7 +20501,7 @@ "zh-chs": "设备处于深度睡眠状态(S3)。", "zh-cht": "裝置處於深度睡眠狀態(S3)。", "xloc": [ - "default.handlebars->41->605" + "default.handlebars->45->608" ] }, { @@ -20487,7 +20526,7 @@ "zh-chs": "设备处于休眠状态(S4)。", "zh-cht": "裝置處於休眠狀態(S4)。", "xloc": [ - "default.handlebars->41->607" + "default.handlebars->45->610" ] }, { @@ -20512,7 +20551,7 @@ "zh-chs": "设备处于关机状态(S5)。", "zh-cht": "裝置處於關機狀態(S5)。", "xloc": [ - "default.handlebars->41->609" + "default.handlebars->45->612" ] }, { @@ -20538,7 +20577,7 @@ "zh-cht": "裝置處於睡眠狀態(S1)", "xloc": [ "default-mobile.handlebars->11->247", - "default.handlebars->41->616" + "default.handlebars->45->619" ] }, { @@ -20563,7 +20602,7 @@ "zh-chs": "设备处于睡眠状态(S1)。", "zh-cht": "裝置處於睡眠狀態(S1)。", "xloc": [ - "default.handlebars->41->601" + "default.handlebars->45->604" ] }, { @@ -20589,7 +20628,7 @@ "zh-cht": "裝置處於睡眠狀態(S2)", "xloc": [ "default-mobile.handlebars->11->248", - "default.handlebars->41->617" + "default.handlebars->45->620" ] }, { @@ -20614,7 +20653,7 @@ "zh-chs": "设备处于睡眠状态(S2)。", "zh-cht": "裝置處於睡眠狀態(S2)。", "xloc": [ - "default.handlebars->41->603" + "default.handlebars->45->606" ] }, { @@ -20640,7 +20679,7 @@ "zh-cht": "裝置處於軟關機狀態(S5)", "xloc": [ "default-mobile.handlebars->11->251", - "default.handlebars->41->620" + "default.handlebars->45->623" ] }, { @@ -20667,8 +20706,8 @@ "xloc": [ "default-mobile.handlebars->11->198", "default-mobile.handlebars->11->268", - "default.handlebars->41->369", - "default.handlebars->41->774" + "default.handlebars->45->370", + "default.handlebars->45->782" ] }, { @@ -20694,7 +20733,7 @@ "zh-cht": "裝置已連接電源", "xloc": [ "default-mobile.handlebars->11->246", - "default.handlebars->41->615" + "default.handlebars->45->618" ] }, { @@ -20714,7 +20753,7 @@ "ru": "Устройство выключено.", "tr": "Cihaz kapalı.", "xloc": [ - "default.handlebars->41->613" + "default.handlebars->45->616" ] }, { @@ -20739,7 +20778,7 @@ "zh-chs": "设备已连接电源。", "zh-cht": "裝置已連接電源。", "xloc": [ - "default.handlebars->41->599" + "default.handlebars->45->602" ] }, { @@ -20765,7 +20804,7 @@ "zh-cht": "裝置存在,但無法確定電源狀態", "xloc": [ "default-mobile.handlebars->11->252", - "default.handlebars->41->621" + "default.handlebars->45->624" ] }, { @@ -20790,7 +20829,7 @@ "zh-chs": "设备名称", "zh-cht": "裝置名稱", "xloc": [ - "default.handlebars->41->766" + "default.handlebars->45->774" ] }, { @@ -20815,7 +20854,7 @@ "zh-chs": "设备通知", "zh-cht": "設備通知", "xloc": [ - "default.handlebars->41->649" + "default.handlebars->45->652" ] }, { @@ -20839,7 +20878,7 @@ "tr": "Cihaz, Intel(R) AMT ACM TLS etkinleştirmesini istedi, FQDN: {0}", "zh-chs": "设备请求 Intel(R) AMT ACM TLS 激活,FQDN:{0}", "xloc": [ - "default.handlebars->41->2307" + "default.handlebars->45->2322" ] }, { @@ -20864,7 +20903,7 @@ "zh-chs": "设备请求激活Intel(R)AMT ACM,FQDN:{0}", "zh-cht": "設備請求激活Intel(R)AMT ACM,FQDN:{0}", "xloc": [ - "default.handlebars->41->2254" + "default.handlebars->45->2269" ] }, { @@ -20911,9 +20950,9 @@ "zh-chs": "设备", "zh-cht": "裝置", "xloc": [ - "default.handlebars->41->1943", - "default.handlebars->41->2495", - "default.handlebars->41->2538" + "default.handlebars->45->1958", + "default.handlebars->45->2510", + "default.handlebars->45->2553" ] }, { @@ -20942,6 +20981,7 @@ "nl": "Cursorinstellingen uitschakelen", "pl": "Wyłącz Ustawienia Kursora", "ru": "Отключить настройки курсора", + "fr": "Désactiver les paramètres du curseur", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->11" ] @@ -20951,6 +20991,7 @@ "nl": "Cursorschaduw uitschakelen", "pl": "Wyłącz Cień Kursora", "ru": "Отключить тень курсора", + "fr": "Désactiver l'ombre du curseur", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->9" ] @@ -20960,6 +21001,7 @@ "nl": "Volledig venster slepen uitschakelen", "pl": "Wyłącz Przeciąganie Okna z Podglądem", "ru": "Отключить содежимое окна при перетаскивании", + "fr": "Désactiver le déplacement de la fenêtre entière", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->3" ] @@ -20969,6 +21011,7 @@ "nl": "Menu animaties uitschakelen", "pl": "Wyłącz Animację Menu", "ru": "Отключить анимации меню", + "fr": "Désactiver les animations du menu", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->5" ] @@ -20978,6 +21021,7 @@ "nl": "Thema's uitschakelen", "pl": "Wyłącz Temat Wizualny", "ru": "Отключить тему", + "fr": "Désactiver le thême", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->7" ] @@ -20987,6 +21031,7 @@ "nl": "Achtergrond uitschakelen", "pl": "Wyłącz Tapetę Pulpitu", "ru": "Отключить обои", + "fr": "Désactiver le fond d'écran", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->1" ] @@ -21014,8 +21059,8 @@ "zh-cht": "已禁用", "xloc": [ "default-mobile.handlebars->11->529", - "default.handlebars->41->121", - "default.handlebars->41->842" + "default.handlebars->45->122", + "default.handlebars->45->850" ] }, { @@ -21040,7 +21085,7 @@ "zh-chs": "禁用的电子邮件两因素身份验证", "zh-cht": "禁用的電子郵件兩因素身份驗證", "xloc": [ - "default.handlebars->41->2285" + "default.handlebars->45->2300" ] }, { @@ -21069,8 +21114,8 @@ "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", "default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea1->1->3->disconnectbutton2span", - "default.handlebars->41->1888", - "default.handlebars->41->861", + "default.handlebars->45->1903", + "default.handlebars->45->869", "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->disconnectbutton1span", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->disconnectbutton2span", "default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3", @@ -21171,12 +21216,12 @@ "default-mobile.handlebars->11->217", "default-mobile.handlebars->11->221", "default-mobile.handlebars->11->225", - "default.handlebars->41->398", - "default.handlebars->41->405", - "default.handlebars->41->409", - "default.handlebars->41->413", - "default.handlebars->41->417", - "default.handlebars->41->421" + "default.handlebars->45->401", + "default.handlebars->45->408", + "default.handlebars->45->412", + "default.handlebars->45->416", + "default.handlebars->45->420", + "default.handlebars->45->424" ] }, { @@ -21205,11 +21250,11 @@ "default-mobile.handlebars->container->page_content->column_l->p10->p10desktop->deskarea1->1->3->deskstatus", "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->0->1->3->p13Status", "default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea1->1->3->termstatus", - "default.handlebars->41->361", - "default.handlebars->41->364", - "default.handlebars->41->390", - "default.handlebars->41->429", - "default.handlebars->41->8", + "default.handlebars->45->362", + "default.handlebars->45->365", + "default.handlebars->45->391", + "default.handlebars->45->432", + "default.handlebars->45->8", "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->deskstatus", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->termstatus", "default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3->p13Status", @@ -21264,7 +21309,7 @@ "zh-chs": "解雇", "zh-cht": "解僱", "xloc": [ - "default.handlebars->41->394" + "default.handlebars->45->397" ] }, { @@ -21272,6 +21317,7 @@ "nl": "Scherm grootte", "pl": "Rozdzielczość Wyświetlacza", "ru": "Размер дисплея", + "fr": "Taille de l'affichage", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->1" ] @@ -21298,7 +21344,7 @@ "zh-chs": "在远程设备上显示一个消息框。", "zh-cht": "在遠程裝置上顯示一個訊息框。", "xloc": [ - "default.handlebars->41->1040" + "default.handlebars->45->1054" ] }, { @@ -21348,7 +21394,7 @@ "zh-chs": "在远程设备上显示短信", "zh-cht": "在遠程裝置上顯示短信", "xloc": [ - "default.handlebars->41->900" + "default.handlebars->45->908" ] }, { @@ -21394,7 +21440,7 @@ "zh-chs": "显示设备组名称", "zh-cht": "顯示裝置群名稱", "xloc": [ - "default.handlebars->41->1763" + "default.handlebars->45->1778" ] }, { @@ -21419,7 +21465,7 @@ "zh-chs": "显示名称", "zh-cht": "顯示名稱", "xloc": [ - "default.handlebars->41->1280" + "default.handlebars->45->1295" ] }, { @@ -21444,7 +21490,7 @@ "zh-chs": "显示公共连结", "zh-cht": "顯示公共鏈結", "xloc": [ - "default.handlebars->41->2155" + "default.handlebars->45->2170" ] }, { @@ -21468,7 +21514,7 @@ "tr": "{0} göster", "zh-chs": "显示{0}", "xloc": [ - "default.handlebars->41->1299" + "default.handlebars->45->1314" ] }, { @@ -21493,7 +21539,7 @@ "zh-chs": "显示消息框,标题= “{0}”,消息= “{1}”", "zh-cht": "顯示消息框,標題= “{0}”,消息= “{1}”", "xloc": [ - "default.handlebars->41->2214" + "default.handlebars->45->2229" ] }, { @@ -21518,7 +21564,7 @@ "zh-chs": "显示吐司消息,标题= “{0}”,消息= “{1}”", "zh-cht": "顯示吐司消息,標題= “{0}”,消息= “{1}”", "xloc": [ - "default.handlebars->41->2222" + "default.handlebars->45->2237" ] }, { @@ -21543,8 +21589,8 @@ "zh-chs": "什么都不做", "zh-cht": "什麼都不做", "xloc": [ - "default.handlebars->41->1972", - "default.handlebars->41->1976" + "default.handlebars->45->1987", + "default.handlebars->45->1991" ] }, { @@ -21569,12 +21615,12 @@ "zh-chs": "域", "zh-cht": "域", "xloc": [ - "default.handlebars->41->117", - "default.handlebars->41->1216", - "default.handlebars->41->2458", - "default.handlebars->41->2507", - "default.handlebars->41->2516", - "default.handlebars->41->2589", + "default.handlebars->45->118", + "default.handlebars->45->1231", + "default.handlebars->45->2473", + "default.handlebars->45->2522", + "default.handlebars->45->2531", + "default.handlebars->45->2604", "mstsc.handlebars->main->1->3->1->rowdomain->1->0", "mstsc.handlebars->main->1->3->1->rowdomain->3" ] @@ -21622,7 +21668,7 @@ "zh-chs": "请勿更改,如果设置请保留CCM", "zh-cht": "請勿更改,如果設置請保留CCM", "xloc": [ - "default.handlebars->41->1968" + "default.handlebars->45->1983" ] }, { @@ -21669,7 +21715,7 @@ "zh-chs": "不要连接到服务器", "zh-cht": "不要連接到伺服器", "xloc": [ - "default.handlebars->41->1977" + "default.handlebars->45->1992" ] }, { @@ -21786,7 +21832,7 @@ "zh-chs": "下", "xloc": [ "default-mobile.handlebars->11->428", - "default.handlebars->41->1250" + "default.handlebars->45->1265" ] }, { @@ -21889,7 +21935,7 @@ "zh-cht": "下載檔案", "xloc": [ "default-mobile.handlebars->11->503", - "default.handlebars->41->1381", + "default.handlebars->45->1396", "sharing.handlebars->11->82" ] }, @@ -21915,7 +21961,7 @@ "zh-chs": "下载MeshCentral Router,一个TCP端口映射工具。", "zh-cht": "下載MeshCentral Router,一個TCP端口映射工具。", "xloc": [ - "default.handlebars->41->359" + "default.handlebars->45->360" ] }, { @@ -21940,7 +21986,7 @@ "zh-chs": "下载MeshCmd", "zh-cht": "下載MeshCmd", "xloc": [ - "default.handlebars->41->1177" + "default.handlebars->45->1192" ] }, { @@ -21965,7 +22011,7 @@ "zh-chs": "下载MeshCmd,这是一个多功能的指令执行工具。", "zh-cht": "下載MeshCmd,這是一個多功能的指令執行工具。", "xloc": [ - "default.handlebars->41->357" + "default.handlebars->45->358" ] }, { @@ -22015,7 +22061,7 @@ "zh-chs": "下载报告", "zh-cht": "下載報告", "xloc": [ - "default.handlebars->41->2373", + "default.handlebars->45->2388", "default.handlebars->container->column_l->p3->3->1->0->3", "default.handlebars->container->column_l->p60->3->1->0->3->1->p60downloadReportDiv" ] @@ -22042,7 +22088,7 @@ "zh-chs": "下载带有指令档案的“ meshcmd”,以通过此服务器将网络讯息发送到该设备。紧记编辑meshaction.txt并添加您的帐户密码或进行任何必要的更改。", "zh-cht": "下載帶有指令檔案的“ meshcmd”,以通過此服務器將網絡讯息發送到該裝置。緊記編輯meshaction.txt並新增你的帳戶密碼或進行任何必要的更改。", "xloc": [ - "default.handlebars->41->1170" + "default.handlebars->45->1185" ] }, { @@ -22116,7 +22162,7 @@ "tr": "Cihaz listesini indir", "zh-chs": "下载设备列表", "xloc": [ - "default.handlebars->41->1941" + "default.handlebars->45->1956" ] }, { @@ -22141,7 +22187,7 @@ "zh-chs": "下载错误日志", "zh-cht": "下載錯誤日誌", "xloc": [ - "default.handlebars->41->191" + "default.handlebars->45->192" ] }, { @@ -22166,7 +22212,7 @@ "zh-chs": "下载电源事件", "zh-cht": "下載電源事件", "xloc": [ - "default.handlebars->41->1126" + "default.handlebars->45->1141" ] }, { @@ -22290,7 +22336,7 @@ "zh-chs": "使用以下一种档案格式下载设备列表。", "zh-cht": "使用以下一種檔案格式下載裝置列表。", "xloc": [ - "default.handlebars->41->700" + "default.handlebars->45->704" ] }, { @@ -22315,7 +22361,7 @@ "zh-chs": "使用以下一种档案格式下载事件列表。", "zh-cht": "使用以下一種檔案格式下載事件列表。", "xloc": [ - "default.handlebars->41->2374" + "default.handlebars->45->2389" ] }, { @@ -22340,7 +22386,7 @@ "zh-chs": "使用以下一种档案格式下载用户列表。", "zh-cht": "使用以下一種檔案格式下載用戶列表。", "xloc": [ - "default.handlebars->41->2442" + "default.handlebars->45->2457" ] }, { @@ -22441,7 +22487,7 @@ "zh-chs": "下载:“{0}”", "zh-cht": "下載:“{0}”", "xloc": [ - "default.handlebars->41->2245" + "default.handlebars->45->2260" ] }, { @@ -22465,7 +22511,7 @@ "tr": "İndirme: \\\"{0}\\\", Boyut: {1}", "zh-chs": "下载:\\\"{0}\\\",大小:{1}", "xloc": [ - "default.handlebars->41->2302" + "default.handlebars->45->2317" ] }, { @@ -22515,7 +22561,7 @@ "zh-chs": "代理重复", "zh-cht": "代理重複", "xloc": [ - "default.handlebars->41->2908" + "default.handlebars->45->2923" ] }, { @@ -22565,7 +22611,7 @@ "zh-chs": "复制用户组", "zh-cht": "複製用戶群", "xloc": [ - "default.handlebars->41->2511" + "default.handlebars->45->2526" ] }, { @@ -22612,11 +22658,11 @@ "zh-chs": "持续时间", "zh-cht": "持續時間", "xloc": [ - "default.handlebars->41->1083", - "default.handlebars->41->272", - "default.handlebars->41->274", - "default.handlebars->41->2741", - "default.handlebars->41->2767", + "default.handlebars->45->1098", + "default.handlebars->45->273", + "default.handlebars->45->275", + "default.handlebars->45->2756", + "default.handlebars->45->2782", "player.handlebars->3->18" ] }, @@ -22664,7 +22710,7 @@ "zh-chs": "荷兰文(比利时)", "zh-cht": "荷蘭文(比利時)", "xloc": [ - "default.handlebars->41->1582" + "default.handlebars->45->1597" ] }, { @@ -22689,7 +22735,7 @@ "zh-chs": "荷兰文(标准)", "zh-cht": "荷蘭文(標準)", "xloc": [ - "default.handlebars->41->1581" + "default.handlebars->45->1596" ] }, { @@ -22835,8 +22881,8 @@ "zh-chs": "错误:", "zh-cht": "錯誤:", "xloc": [ - "default.handlebars->41->235", - "default.handlebars->41->237" + "default.handlebars->45->236", + "default.handlebars->45->238" ] }, { @@ -22991,7 +23037,7 @@ "zh-chs": "错误:无法添加密钥。", "zh-cht": "錯誤:無法新增密鑰。", "xloc": [ - "default.handlebars->41->232" + "default.handlebars->45->233" ] }, { @@ -23073,9 +23119,9 @@ "default-mobile.handlebars->11->396", "default-mobile.handlebars->11->398", "default-mobile.handlebars->11->405", - "default.handlebars->41->1187", - "default.handlebars->41->1189", - "default.handlebars->41->1196" + "default.handlebars->45->1202", + "default.handlebars->45->1204", + "default.handlebars->45->1211" ] }, { @@ -23105,12 +23151,12 @@ "default-mobile.handlebars->11->652", "default-mobile.handlebars->11->658", "default-mobile.handlebars->11->678", - "default.handlebars->41->1987", - "default.handlebars->41->1990", - "default.handlebars->41->1993", - "default.handlebars->41->2030", - "default.handlebars->41->2056", - "default.handlebars->41->2068" + "default.handlebars->45->2002", + "default.handlebars->45->2005", + "default.handlebars->45->2008", + "default.handlebars->45->2045", + "default.handlebars->45->2071", + "default.handlebars->45->2083" ] }, { @@ -23135,7 +23181,7 @@ "zh-chs": "编辑设备组功能", "zh-cht": "編輯裝置群功能", "xloc": [ - "default.handlebars->41->2016" + "default.handlebars->45->2031" ] }, { @@ -23160,8 +23206,8 @@ "zh-chs": "编辑设备组权限", "zh-cht": "編輯裝置群權限", "xloc": [ - "default.handlebars->41->2053", - "default.handlebars->41->2065" + "default.handlebars->45->2068", + "default.handlebars->45->2080" ] }, { @@ -23186,7 +23232,7 @@ "zh-chs": "编辑设备组用户同意", "zh-cht": "編輯裝置群用戶同意", "xloc": [ - "default.handlebars->41->1994" + "default.handlebars->45->2009" ] }, { @@ -23212,7 +23258,7 @@ "zh-cht": "編輯裝置筆記", "xloc": [ "default-mobile.handlebars->11->670", - "default.handlebars->41->2044" + "default.handlebars->45->2059" ] }, { @@ -23237,8 +23283,8 @@ "zh-chs": "编辑设备权限", "zh-cht": "編輯裝置權限", "xloc": [ - "default.handlebars->41->2058", - "default.handlebars->41->2060" + "default.handlebars->45->2073", + "default.handlebars->45->2075" ] }, { @@ -23263,7 +23309,7 @@ "zh-chs": "编辑设备标签", "zh-cht": "編輯裝置標籤", "xloc": [ - "default.handlebars->41->682" + "default.handlebars->45->685" ] }, { @@ -23288,7 +23334,7 @@ "zh-chs": "编辑设备用户同意", "zh-cht": "編輯裝置用戶同意", "xloc": [ - "default.handlebars->41->1996" + "default.handlebars->45->2011" ] }, { @@ -23313,7 +23359,7 @@ "zh-chs": "编辑群组", "zh-cht": "編輯群組", "xloc": [ - "default.handlebars->41->1013" + "default.handlebars->45->1027" ] }, { @@ -23342,10 +23388,10 @@ "default-mobile.handlebars->11->305", "default-mobile.handlebars->11->306", "default-mobile.handlebars->11->391", - "default.handlebars->41->1133", - "default.handlebars->41->813", - "default.handlebars->41->818", - "default.handlebars->41->819" + "default.handlebars->45->1148", + "default.handlebars->45->821", + "default.handlebars->45->826", + "default.handlebars->45->827" ] }, { @@ -23371,7 +23417,7 @@ "zh-cht": "編輯筆記", "xloc": [ "default-mobile.handlebars->11->685", - "default.handlebars->41->2075" + "default.handlebars->45->2090" ] }, { @@ -23396,7 +23442,7 @@ "zh-chs": "编辑用户同意", "zh-cht": "編輯用戶同意", "xloc": [ - "default.handlebars->41->1995" + "default.handlebars->45->2010" ] }, { @@ -23421,7 +23467,7 @@ "zh-chs": "编辑用户设备组权限", "zh-cht": "編輯用戶裝置群權限", "xloc": [ - "default.handlebars->41->2066" + "default.handlebars->45->2081" ] }, { @@ -23446,7 +23492,7 @@ "zh-chs": "编辑用户设备权限", "zh-cht": "編輯用戶裝置權限", "xloc": [ - "default.handlebars->41->2061" + "default.handlebars->45->2076" ] }, { @@ -23470,7 +23516,7 @@ "tr": "Kullanıcı Özelliklerini Düzenle", "zh-chs": "编辑用户特征", "xloc": [ - "default.handlebars->41->2679" + "default.handlebars->45->2694" ] }, { @@ -23495,7 +23541,7 @@ "zh-chs": "编辑用户组", "zh-cht": "編輯用戶群", "xloc": [ - "default.handlebars->41->2567" + "default.handlebars->45->2582" ] }, { @@ -23520,7 +23566,7 @@ "zh-chs": "编辑用户组设备权限", "zh-cht": "編輯用戶群裝置權限", "xloc": [ - "default.handlebars->41->2063" + "default.handlebars->45->2078" ] }, { @@ -23540,7 +23586,7 @@ "ru": "Редактировать функции групп пользователей", "tr": "Kullanıcı Grubu Özelliklerini Düzenle", "xloc": [ - "default.handlebars->41->2560" + "default.handlebars->45->2575" ] }, { @@ -23565,7 +23611,7 @@ "zh-chs": "编辑用户组用户同意", "zh-cht": "編輯用戶組用戶同意", "xloc": [ - "default.handlebars->41->1997" + "default.handlebars->45->2012" ] }, { @@ -23616,7 +23662,7 @@ "zh-chs": "编辑标签", "zh-cht": "編輯標籤", "xloc": [ - "default.handlebars->41->650" + "default.handlebars->45->653" ] }, { @@ -23684,13 +23730,13 @@ "zh-cht": "電郵", "xloc": [ "default-mobile.handlebars->11->109", - "default.handlebars->41->2460", - "default.handlebars->41->2593", - "default.handlebars->41->2595", - "default.handlebars->41->2640", - "default.handlebars->41->2650", - "default.handlebars->41->2682", - "default.handlebars->41->491", + "default.handlebars->45->2475", + "default.handlebars->45->2608", + "default.handlebars->45->2610", + "default.handlebars->45->2655", + "default.handlebars->45->2665", + "default.handlebars->45->2697", + "default.handlebars->45->494", "login-mobile.handlebars->5->42", "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3", "login.handlebars->5->44", @@ -23727,7 +23773,7 @@ "zh-cht": "電郵地址變更", "xloc": [ "default-mobile.handlebars->11->110", - "default.handlebars->41->1772" + "default.handlebars->45->1787" ] }, { @@ -23753,7 +23799,7 @@ "zh-cht": "電郵認證", "xloc": [ "default-mobile.handlebars->11->99", - "default.handlebars->41->1512" + "default.handlebars->45->1527" ] }, { @@ -23800,8 +23846,8 @@ "ru": "Подлючение электронной почты", "tr": "E-posta Bağlantısı", "xloc": [ - "default.handlebars->41->1890", - "default.handlebars->41->863" + "default.handlebars->45->1905", + "default.handlebars->45->871" ] }, { @@ -23821,8 +23867,8 @@ "ru": "Отключение электронной почты", "tr": "E-posta Bağlantısını Kes", "xloc": [ - "default.handlebars->41->1891", - "default.handlebars->41->864" + "default.handlebars->45->1906", + "default.handlebars->45->872" ] }, { @@ -23842,8 +23888,8 @@ "ru": "Уведомления по электронной почте", "tr": "E-posta Bildirimleri", "xloc": [ - "default.handlebars->41->2124", - "default.handlebars->41->989" + "default.handlebars->45->1003", + "default.handlebars->45->2139" ] }, { @@ -23891,7 +23937,7 @@ "zh-cht": "電郵驗證", "xloc": [ "default-mobile.handlebars->11->108", - "default.handlebars->41->1770" + "default.handlebars->45->1785" ] }, { @@ -23900,9 +23946,10 @@ "pl": "Domena email \\\"{0}\\\" jest niedozwolona. Tylko ({1}) jest dopuszczona", "pt-br": "O domínio de e-mail \\\"{0}\\\" não é permitido. Somente ({1}) são permitidos", "ru": "Домен почты \\\"{0}\\\" не разрешен. Разрешены только ({1})", + "fr": "Les courriels de \\\"{0}\\\" ne sont pas autorisés. Seulement ceux de ({1}) sont permis", "xloc": [ "default-mobile.handlebars->11->743", - "default.handlebars->41->2891" + "default.handlebars->45->2906" ] }, { @@ -23927,7 +23974,7 @@ "zh-chs": "电邮邀请", "zh-cht": "電郵邀請", "xloc": [ - "default.handlebars->41->488" + "default.handlebars->45->491" ] }, { @@ -23952,7 +23999,7 @@ "zh-chs": "电邮未验证", "zh-cht": "電郵未驗證", "xloc": [ - "default.handlebars->41->2404" + "default.handlebars->45->2419" ] }, { @@ -23977,8 +24024,8 @@ "zh-chs": "电子邮件已验证", "zh-cht": "電子郵件已驗證", "xloc": [ - "default.handlebars->41->2405", - "default.handlebars->41->2587" + "default.handlebars->45->2420", + "default.handlebars->45->2602" ] }, { @@ -24003,7 +24050,7 @@ "zh-chs": "电邮已验证。", "zh-cht": "電郵已驗證。", "xloc": [ - "default.handlebars->41->2466" + "default.handlebars->45->2481" ] }, { @@ -24028,7 +24075,7 @@ "zh-chs": "电邮未验证", "zh-cht": "電郵未驗證", "xloc": [ - "default.handlebars->41->2588" + "default.handlebars->45->2603" ] }, { @@ -24075,7 +24122,7 @@ "zh-cht": "電郵已發送。", "xloc": [ "default-mobile.handlebars->11->727", - "default.handlebars->41->2875", + "default.handlebars->45->2890", "login-mobile.handlebars->5->2", "login.handlebars->5->2", "login2.handlebars->7->3" @@ -24151,7 +24198,7 @@ "zh-chs": "已通过电邮验证,并且需要重置密码。", "zh-cht": "已通過電郵驗證,並且需要重置密碼。", "xloc": [ - "default.handlebars->41->2467" + "default.handlebars->45->2482" ] }, { @@ -24197,7 +24244,7 @@ "tr": "E-posta/SMS/Push Trafiği", "zh-chs": "电子邮件/短信/推送流量", "xloc": [ - "default.handlebars->41->2967" + "default.handlebars->45->2982" ] }, { @@ -24236,6 +24283,7 @@ "nl": "Bureaubladsamenstelling inschakelen", "pl": "Włącz Kompozycje Pulpitu", "ru": "Включить композицию рабочего стола", + "fr": "Activer la composition du bureau", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->15" ] @@ -24245,6 +24293,7 @@ "nl": "Lettertype vloeiend maken inschakelen", "pl": "Włącz Rozmycie Czcionek", "ru": "Включить сглаживание шрифтов", + "fr": "Activer le lissage des polices de caractères", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->13" ] @@ -24271,7 +24320,7 @@ "zh-chs": "启用邀请代码", "zh-cht": "啟用邀請代碼", "xloc": [ - "default.handlebars->41->2100" + "default.handlebars->45->2115" ] }, { @@ -24322,7 +24371,7 @@ "zh-cht": "啟用電郵二因子鑑別。", "xloc": [ "default-mobile.handlebars->11->101", - "default.handlebars->41->1514" + "default.handlebars->45->1529" ] }, { @@ -24372,8 +24421,8 @@ "zh-chs": "已启用", "zh-cht": "已啟用", "xloc": [ - "default.handlebars->41->120", - "default.handlebars->41->2769" + "default.handlebars->45->121", + "default.handlebars->45->2784" ] }, { @@ -24398,7 +24447,7 @@ "zh-chs": "启用电子邮件两因素身份验证", "zh-cht": "啟用電子郵件兩因素身份驗證", "xloc": [ - "default.handlebars->41->2284" + "default.handlebars->45->2299" ] }, { @@ -24454,7 +24503,7 @@ "ru": "Кодировка: RAW", "tr": "kodlama: RAW", "xloc": [ - "default.handlebars->41->1388" + "default.handlebars->45->1403" ] }, { @@ -24474,7 +24523,7 @@ "ru": "Кодировка: UTF8", "tr": "Kodlama: UTF8", "xloc": [ - "default.handlebars->41->1389" + "default.handlebars->45->1404" ] }, { @@ -24499,7 +24548,7 @@ "zh-chs": "结尾", "xloc": [ "default-mobile.handlebars->11->422", - "default.handlebars->41->1244" + "default.handlebars->45->1259" ] }, { @@ -24524,7 +24573,7 @@ "zh-chs": "时间结束", "zh-cht": "時間結束", "xloc": [ - "default.handlebars->41->2766" + "default.handlebars->45->2781" ] }, { @@ -24549,7 +24598,7 @@ "zh-chs": "从{1}到{2},{3}秒结束了桌面会话“{0}”", "zh-cht": "從{1}到{2},{3}秒結束了桌面會話“{0}”", "xloc": [ - "default.handlebars->41->2207" + "default.handlebars->45->2222" ] }, { @@ -24574,7 +24623,7 @@ "zh-chs": "从{1}到{2},{3}秒结束了文件管理会话“{0}”", "zh-cht": "從{1}到{2},{3}秒結束了文件管理會話“{0}”", "xloc": [ - "default.handlebars->41->2208" + "default.handlebars->45->2223" ] }, { @@ -24598,7 +24647,7 @@ "tr": "Yerel geçiş oturumu \\\"{0}\\\", {1} - {2} protokolü, {3} saniye sona erdi", "zh-chs": "结束本地中继会话\\\"{0}\\\",协议 {1} 到 {2},{3} 秒", "xloc": [ - "default.handlebars->41->2317" + "default.handlebars->45->2332" ] }, { @@ -24622,7 +24671,7 @@ "tr": "{1} ile {2} arasında \\\"{0}\\\" mesajlaşma oturumu sona erdi, {3} saniye", "zh-chs": "从 {1} 到 {2},{3} 秒结束了 Messenger 会话 \\\"{0}\\\"", "xloc": [ - "default.handlebars->41->2308" + "default.handlebars->45->2323" ] }, { @@ -24647,7 +24696,7 @@ "zh-chs": "从{1}到{2},{3}秒结束了中继会话“{0}”", "zh-cht": "從{1}到{2},{3}秒結束了中繼會話“{0}”", "xloc": [ - "default.handlebars->41->2205" + "default.handlebars->45->2220" ] }, { @@ -24672,7 +24721,7 @@ "zh-chs": "从{1}到{2},{3}秒结束了终端会话“{0}”", "zh-cht": "從{1}到{2},{3}秒結束了終端會話“{0}”", "xloc": [ - "default.handlebars->41->2206" + "default.handlebars->45->2221" ] }, { @@ -24697,7 +24746,7 @@ "zh-chs": "英文", "zh-cht": "英文", "xloc": [ - "default.handlebars->41->1583" + "default.handlebars->45->1598" ] }, { @@ -24722,7 +24771,7 @@ "zh-chs": "英文(澳洲)", "zh-cht": "英文(澳洲)", "xloc": [ - "default.handlebars->41->1584" + "default.handlebars->45->1599" ] }, { @@ -24747,7 +24796,7 @@ "zh-chs": "英文(伯利茲)", "zh-cht": "英文(伯利茲)", "xloc": [ - "default.handlebars->41->1585" + "default.handlebars->45->1600" ] }, { @@ -24772,7 +24821,7 @@ "zh-chs": "英文(加拿大)", "zh-cht": "英文(加拿大)", "xloc": [ - "default.handlebars->41->1586" + "default.handlebars->45->1601" ] }, { @@ -24797,7 +24846,7 @@ "zh-chs": "英文(爱尔兰)", "zh-cht": "英文(愛爾蘭)", "xloc": [ - "default.handlebars->41->1587" + "default.handlebars->45->1602" ] }, { @@ -24822,7 +24871,7 @@ "zh-chs": "英文(牙买加)", "zh-cht": "英文(牙買加)", "xloc": [ - "default.handlebars->41->1588" + "default.handlebars->45->1603" ] }, { @@ -24847,7 +24896,7 @@ "zh-chs": "英文(纽西兰)", "zh-cht": "英文(紐西蘭)", "xloc": [ - "default.handlebars->41->1589" + "default.handlebars->45->1604" ] }, { @@ -24872,7 +24921,7 @@ "zh-chs": "英文(菲律宾)", "zh-cht": "英文(菲律賓)", "xloc": [ - "default.handlebars->41->1590" + "default.handlebars->45->1605" ] }, { @@ -24897,7 +24946,7 @@ "zh-chs": "英语(南非)", "zh-cht": "英語(南非)", "xloc": [ - "default.handlebars->41->1591" + "default.handlebars->45->1606" ] }, { @@ -24922,7 +24971,7 @@ "zh-chs": "英文(特立尼达和多巴哥)", "zh-cht": "英文(特立尼達和多巴哥)", "xloc": [ - "default.handlebars->41->1592" + "default.handlebars->45->1607" ] }, { @@ -24947,7 +24996,7 @@ "zh-chs": "英文(英国)", "zh-cht": "英文(英國)", "xloc": [ - "default.handlebars->41->1593" + "default.handlebars->45->1608" ] }, { @@ -24972,7 +25021,7 @@ "zh-chs": "美国英文", "zh-cht": "美國英語", "xloc": [ - "default.handlebars->41->1594" + "default.handlebars->45->1609" ] }, { @@ -24997,7 +25046,7 @@ "zh-chs": "英文(津巴布韦)", "zh-cht": "英文(津巴布韋)", "xloc": [ - "default.handlebars->41->1595" + "default.handlebars->45->1610" ] }, { @@ -25044,10 +25093,10 @@ "zh-cht": "輸入", "xloc": [ "default-mobile.handlebars->11->416", - "default.handlebars->41->1238", - "default.handlebars->41->1353", - "default.handlebars->41->1809", - "default.handlebars->41->1810", + "default.handlebars->45->1253", + "default.handlebars->45->1368", + "default.handlebars->45->1824", + "default.handlebars->45->1825", "sharing.handlebars->11->55" ] }, @@ -25073,7 +25122,7 @@ "zh-chs": "输入管理领域名称的逗号分隔列表。", "zh-cht": "輸入管理領域名稱的逗號分隔列表。", "xloc": [ - "default.handlebars->41->2471" + "default.handlebars->45->2486" ] }, { @@ -25098,7 +25147,7 @@ "zh-chs": "输入IP地址范围以扫描英特尔AMT设备。", "zh-cht": "輸入IP地址範圍以掃描Intel® AMT裝置。", "xloc": [ - "default.handlebars->41->476" + "default.handlebars->45->479" ] }, { @@ -25169,7 +25218,7 @@ "zh-chs": "输入文本,然后单击确定以远程键入它。在继续操作之前,请确保将远程光标放置在正确的位置。", "zh-cht": "輸入文本,然後單擊確定以遠程鍵入它。在繼續操作之前,請確保將遠程光標放置在正確的位置。", "xloc": [ - "default.handlebars->41->1268" + "default.handlebars->45->1283" ] }, { @@ -25263,7 +25312,7 @@ "zh-chs": "在此处输入保安编码以进行两步登录:", "zh-cht": "在此處輸入保安編碼以進行兩步登入:", "xloc": [ - "default.handlebars->41->203" + "default.handlebars->45->204" ] }, { @@ -25288,7 +25337,7 @@ "zh-chs": "输入支持SMS的电话号码。验证后,该号码可用于登录验证和其他通知。", "zh-cht": "輸入支持SMS的電話號碼。驗證後,該號碼可用於登入驗證和其他通知。", "xloc": [ - "default.handlebars->41->1509" + "default.handlebars->45->1524" ] }, { @@ -25296,9 +25345,10 @@ "nl": "Foutmelding #{0}", "pl": "Błąd #{0}", "ru": "Ошибка #{0}", + "fr": "Erreur #{0}", "xloc": [ "default-mobile.handlebars->11->66", - "default.handlebars->41->200" + "default.handlebars->45->201" ] }, { @@ -25386,7 +25436,7 @@ "zh-chs": "错误,无法添加密钥。", "zh-cht": "錯誤,無法新增密鑰。", "xloc": [ - "default.handlebars->41->230" + "default.handlebars->45->231" ] }, { @@ -25411,7 +25461,7 @@ "zh-chs": "错误,邀请码 \\\"{0}\\\" 已被使用。", "xloc": [ "default-mobile.handlebars->11->735", - "default.handlebars->41->2883" + "default.handlebars->45->2898" ] }, { @@ -25436,7 +25486,7 @@ "zh-chs": "错误,密码未更改。", "xloc": [ "default-mobile.handlebars->11->732", - "default.handlebars->41->2880" + "default.handlebars->45->2895" ] }, { @@ -25461,7 +25511,7 @@ "zh-chs": "错误,无法更改为常用密码。", "xloc": [ "default-mobile.handlebars->11->731", - "default.handlebars->41->2879" + "default.handlebars->45->2894" ] }, { @@ -25486,7 +25536,7 @@ "zh-chs": "错误,无法更改为以前使用的密码。", "xloc": [ "default-mobile.handlebars->11->730", - "default.handlebars->41->2878" + "default.handlebars->45->2893" ] }, { @@ -25536,7 +25586,7 @@ "zh-chs": "逃脱", "xloc": [ "default-mobile.handlebars->11->417", - "default.handlebars->41->1239" + "default.handlebars->45->1254" ] }, { @@ -25561,7 +25611,7 @@ "zh-chs": "世界文", "zh-cht": "世界語", "xloc": [ - "default.handlebars->41->1596" + "default.handlebars->45->1611" ] }, { @@ -25607,7 +25657,7 @@ "zh-chs": "爱沙尼亚文", "zh-cht": "愛沙尼亞語", "xloc": [ - "default.handlebars->41->1597" + "default.handlebars->45->1612" ] }, { @@ -25653,7 +25703,7 @@ "zh-chs": "事件详情", "zh-cht": "事件詳情", "xloc": [ - "default.handlebars->41->1397" + "default.handlebars->45->1412" ] }, { @@ -25678,7 +25728,7 @@ "zh-chs": "事件列表输出", "zh-cht": "事件列表輸出", "xloc": [ - "default.handlebars->41->2379" + "default.handlebars->45->2394" ] }, { @@ -25831,7 +25881,7 @@ "tr": "sona erme", "zh-chs": "到期", "xloc": [ - "default.handlebars->41->314" + "default.handlebars->45->315" ] }, { @@ -25856,9 +25906,9 @@ "zh-chs": "到期时间", "zh-cht": "到期時間", "xloc": [ - "default.handlebars->41->1078", - "default.handlebars->41->1760", - "default.handlebars->41->277" + "default.handlebars->45->1093", + "default.handlebars->45->1775", + "default.handlebars->45->278" ] }, { @@ -25908,7 +25958,7 @@ "zh-chs": "过期{0}", "zh-cht": "過期{0}", "xloc": [ - "default.handlebars->41->1823", + "default.handlebars->45->1838", "sharing.handlebars->11->95" ] }, @@ -25934,7 +25984,7 @@ "zh-chs": "输出设备信息", "zh-cht": "輸出裝置訊息", "xloc": [ - "default.handlebars->41->641" + "default.handlebars->45->644" ] }, { @@ -25959,7 +26009,7 @@ "zh-chs": "扩充式ASCII", "zh-cht": "擴充式ASCII", "xloc": [ - "default.handlebars->41->1329", + "default.handlebars->45->1344", "sharing.handlebars->11->34" ] }, @@ -26011,7 +26061,7 @@ "zh-chs": "外部", "zh-cht": "外部", "xloc": [ - "default.handlebars->41->2947" + "default.handlebars->45->2962" ] }, { @@ -26020,8 +26070,9 @@ "pl": "Klucz FIDO", "pt-br": "Chave FIDO", "ru": "ключ FIDO", + "fr": "Clé FIDO", "xloc": [ - "default.handlebars->41->2833" + "default.handlebars->45->2848" ] }, { @@ -26046,7 +26097,7 @@ "zh-chs": "完整网域名称", "zh-cht": "完整網域名稱", "xloc": [ - "default.handlebars->41->164" + "default.handlebars->45->165" ] }, { @@ -26071,7 +26122,7 @@ "zh-chs": "FYRO马其顿语", "zh-cht": "FYRO馬其頓語", "xloc": [ - "default.handlebars->41->1647" + "default.handlebars->45->1662" ] }, { @@ -26096,7 +26147,7 @@ "zh-chs": "法罗语", "zh-cht": "法羅語", "xloc": [ - "default.handlebars->41->1598" + "default.handlebars->45->1613" ] }, { @@ -26121,7 +26172,7 @@ "zh-chs": "失败", "zh-cht": "失敗", "xloc": [ - "default.handlebars->41->111" + "default.handlebars->45->112" ] }, { @@ -26146,7 +26197,7 @@ "zh-chs": "无法更改电子邮件地址,另一个帐户已在使用:{0}。", "xloc": [ "default-mobile.handlebars->11->726", - "default.handlebars->41->2874" + "default.handlebars->45->2889" ] }, { @@ -26173,6 +26224,14 @@ "login2.handlebars->7->29" ] }, + { + "en": "Failed to sign agent {0}: {1}", + "nl": "Kan de agent niet ondertekenen {0}: {1}", + "pl": "Nieudane przypisanie agenta {0}: {1}", + "xloc": [ + "default.handlebars->45->104" + ] + }, { "cs": "Vzdálenou plochu se nepodařilo spustit po odmítnutí místním uživatelem", "da": "Kunne ikke starte fjernskrivebord, da den lokale bruger afviste", @@ -26195,7 +26254,7 @@ "zh-chs": "本地用户拒绝后无法启动远程桌面", "zh-cht": "本地用戶拒絕後無法啟動遠程桌面", "xloc": [ - "default.handlebars->41->2230" + "default.handlebars->45->2245" ] }, { @@ -26241,7 +26300,7 @@ "zh-chs": "本地用户拒绝后无法启动远程文件", "zh-cht": "本地用戶拒絕後無法啟動遠程文件", "xloc": [ - "default.handlebars->41->2237" + "default.handlebars->45->2252" ] }, { @@ -26288,7 +26347,7 @@ "zh-cht": "無法啟動遠程終端接合{0}({1})", "xloc": [ "default-mobile.handlebars->11->408", - "default.handlebars->41->1199", + "default.handlebars->45->1214", "sharing.handlebars->11->30", "sharing.handlebars->11->8" ] @@ -26315,7 +26374,7 @@ "zh-chs": "波斯文(波斯文)", "zh-cht": "波斯語(波斯語)", "xloc": [ - "default.handlebars->41->1599" + "default.handlebars->45->1614" ] }, { @@ -26367,9 +26426,9 @@ "zh-chs": "功能", "zh-cht": "功能", "xloc": [ - "default.handlebars->41->1874", - "default.handlebars->41->2523", - "default.handlebars->41->2611" + "default.handlebars->45->1889", + "default.handlebars->45->2538", + "default.handlebars->45->2626" ] }, { @@ -26394,7 +26453,7 @@ "zh-chs": "斐济", "zh-cht": "斐濟", "xloc": [ - "default.handlebars->41->1600" + "default.handlebars->45->1615" ] }, { @@ -26445,8 +26504,8 @@ "zh-cht": "檔案編輯器", "xloc": [ "default-mobile.handlebars->11->487", - "default.handlebars->41->1365", - "default.handlebars->41->746", + "default.handlebars->45->1380", + "default.handlebars->45->754", "sharing.handlebars->11->66" ] }, @@ -26494,8 +26553,8 @@ "zh-chs": "档案操作", "zh-cht": "檔案操作", "xloc": [ - "default.handlebars->41->1344", - "default.handlebars->41->1346", + "default.handlebars->45->1359", + "default.handlebars->45->1361", "sharing.handlebars->11->46", "sharing.handlebars->11->48" ] @@ -26546,7 +26605,7 @@ "tr": "Dosya transferi", "zh-chs": "文件传输", "xloc": [ - "default.handlebars->41->2747" + "default.handlebars->45->2762" ] }, { @@ -26571,7 +26630,7 @@ "zh-chs": "文件系统驱动", "zh-cht": "FileSystemDriver", "xloc": [ - "default.handlebars->41->1285" + "default.handlebars->45->1300" ] }, { @@ -26598,15 +26657,15 @@ "xloc": [ "default-mobile.handlebars->11->216", "default-mobile.handlebars->11->354", - "default.handlebars->41->1051", - "default.handlebars->41->1927", - "default.handlebars->41->2005", - "default.handlebars->41->2754", - "default.handlebars->41->2813", - "default.handlebars->41->2844", - "default.handlebars->41->2935", - "default.handlebars->41->412", - "default.handlebars->41->967", + "default.handlebars->45->1066", + "default.handlebars->45->1942", + "default.handlebars->45->2020", + "default.handlebars->45->2769", + "default.handlebars->45->2828", + "default.handlebars->45->2859", + "default.handlebars->45->2950", + "default.handlebars->45->415", + "default.handlebars->45->981", "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevFiles", "default.handlebars->contextMenu->cxfiles", "sharing.handlebars->LeftSideToolBar" @@ -26659,10 +26718,10 @@ "zh-chs": "档案通知", "zh-cht": "檔案通知", "xloc": [ - "default.handlebars->41->1882", - "default.handlebars->41->2531", - "default.handlebars->41->2633", - "default.handlebars->41->855" + "default.handlebars->45->1897", + "default.handlebars->45->2546", + "default.handlebars->45->2648", + "default.handlebars->45->863" ] }, { @@ -26687,10 +26746,10 @@ "zh-chs": "档案提示", "zh-cht": "檔案提示", "xloc": [ - "default.handlebars->41->1881", - "default.handlebars->41->2530", - "default.handlebars->41->2632", - "default.handlebars->41->854" + "default.handlebars->45->1896", + "default.handlebars->45->2545", + "default.handlebars->45->2647", + "default.handlebars->45->862" ] }, { @@ -26716,7 +26775,7 @@ "zh-cht": "過濾", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p2->xdevicesBar->1", - "default.handlebars->41->1349", + "default.handlebars->45->1364", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->kvmListToolbar", "default.handlebars->container->column_l->p4->3->1->0->3->3", @@ -26791,7 +26850,7 @@ "zh-chs": "查找文件", "zh-cht": "查找文件", "xloc": [ - "default.handlebars->41->1352", + "default.handlebars->45->1367", "sharing.handlebars->11->54" ] }, @@ -26803,7 +26862,7 @@ "pt-br": "Gravação de sessão \\\"{0}\\\" finalizada, {1} segundo(s)", "ru": "Завершение сеанса записи \\\"{0}\\\", {1} сек.", "xloc": [ - "default.handlebars->41->2342" + "default.handlebars->45->2357" ] }, { @@ -26828,7 +26887,7 @@ "zh-chs": "录制会话已完成,{0}秒", "zh-cht": "錄製會話已完成,{0}秒", "xloc": [ - "default.handlebars->41->2203" + "default.handlebars->45->2218" ] }, { @@ -26853,7 +26912,7 @@ "zh-chs": "芬兰", "zh-cht": "芬蘭", "xloc": [ - "default.handlebars->41->1601" + "default.handlebars->45->1616" ] }, { @@ -26879,8 +26938,8 @@ "xloc": [ "default-mobile.handlebars->11->524", "default-mobile.handlebars->11->526", - "default.handlebars->41->837", - "default.handlebars->41->839" + "default.handlebars->45->845", + "default.handlebars->45->847" ] }, { @@ -26904,8 +26963,8 @@ "tr": "Güvenlik duvarı etkin değil", "zh-chs": "防火墙未激活", "xloc": [ - "default.handlebars->41->2135", - "default.handlebars->41->2149" + "default.handlebars->45->2150", + "default.handlebars->45->2164" ] }, { @@ -26955,7 +27014,7 @@ "ru": "Флаги", "tr": "Bayraklar", "xloc": [ - "default.handlebars->41->2352" + "default.handlebars->45->2367" ] }, { @@ -26980,7 +27039,7 @@ "zh-chs": "闪光", "xloc": [ "default-mobile.handlebars->11->358", - "default.handlebars->41->1089" + "default.handlebars->45->1104" ] }, { @@ -27056,7 +27115,7 @@ "zh-chs": "对于ACM激活,需要将英特尔®AMT设置为以下受信任的FQDN:", "zh-cht": "對於ACM激活,需要將英特爾®AMT設置為以下受信任的FQDN:", "xloc": [ - "default.handlebars->41->466" + "default.handlebars->45->469" ] }, { @@ -27167,7 +27226,7 @@ "tr": "Aracı güncellemesi için", "zh-chs": "代理更新", "xloc": [ - "default.handlebars->41->695" + "default.handlebars->45->698" ] }, { @@ -27191,7 +27250,7 @@ "tr": "Aracı güncellemesini zorla", "zh-chs": "强制代理更新", "xloc": [ - "default.handlebars->41->653" + "default.handlebars->45->656" ] }, { @@ -27215,7 +27274,7 @@ "tr": "Seçilen cihazlarda aracı güncellemesi zorunlu kılınsın mı?", "zh-chs": "在选定的设备上强制更新代理?", "xloc": [ - "default.handlebars->41->694" + "default.handlebars->45->697" ] }, { @@ -27240,8 +27299,8 @@ "zh-chs": "下次登录时强制重置密码。", "zh-cht": "下次登入時強制重置密碼。", "xloc": [ - "default.handlebars->41->2465", - "default.handlebars->41->2693" + "default.handlebars->45->2480", + "default.handlebars->45->2708" ] }, { @@ -27261,7 +27320,7 @@ "ru": "Принудительно отключен сеанс рабочего стола пользователя {0}", "tr": "{0} kullanıcısının bağlantısı zorla kesildi masaüstü oturumu", "xloc": [ - "default.handlebars->41->2330" + "default.handlebars->45->2345" ] }, { @@ -27281,7 +27340,7 @@ "ru": "Принудительно отключен файловый сеанс пользователя {0}", "tr": "{0} kullanıcısının bağlantısı zorla kesilen dosyalar oturumu", "xloc": [ - "default.handlebars->41->2332" + "default.handlebars->45->2347" ] }, { @@ -27301,7 +27360,7 @@ "ru": "Принудительно отключен сеанс маршрутизации пользователя {0}", "tr": "{0} kullanıcısının bağlantısı zorla kesildi yönlendirme oturumu", "xloc": [ - "default.handlebars->41->2333" + "default.handlebars->45->2348" ] }, { @@ -27321,7 +27380,7 @@ "ru": "Принудительно отключен терминальный сеанс пользователя {0}", "tr": "{0} kullanıcısının bağlantısı zorla kesildi terminal oturumu", "xloc": [ - "default.handlebars->41->2331" + "default.handlebars->45->2346" ] }, { @@ -27424,7 +27483,7 @@ "zh-chs": "格式化", "zh-cht": "格式化", "xloc": [ - "default.handlebars->41->2370" + "default.handlebars->45->2385" ] }, { @@ -27497,8 +27556,8 @@ "zh-chs": "自由", "zh-cht": "自由", "xloc": [ - "default.handlebars->41->2893", - "default.handlebars->41->2895" + "default.handlebars->45->2908", + "default.handlebars->45->2910" ] }, { @@ -27524,7 +27583,7 @@ "zh-cht": "FreeBSD x86-64", "xloc": [ "default-mobile.handlebars->11->36", - "default.handlebars->41->43" + "default.handlebars->45->43" ] }, { @@ -27549,7 +27608,7 @@ "zh-chs": "法文(比利时)", "zh-cht": "法語(比利時)", "xloc": [ - "default.handlebars->41->1603" + "default.handlebars->45->1618" ] }, { @@ -27574,7 +27633,7 @@ "zh-chs": "法文(加拿大)", "zh-cht": "法語(加拿大)", "xloc": [ - "default.handlebars->41->1604" + "default.handlebars->45->1619" ] }, { @@ -27599,7 +27658,7 @@ "zh-chs": "法文(法国)", "zh-cht": "法語(法國)", "xloc": [ - "default.handlebars->41->1605" + "default.handlebars->45->1620" ] }, { @@ -27624,7 +27683,7 @@ "zh-chs": "法文(卢森堡)", "zh-cht": "法語(盧森堡)", "xloc": [ - "default.handlebars->41->1606" + "default.handlebars->45->1621" ] }, { @@ -27649,7 +27708,7 @@ "zh-chs": "法文(摩纳哥)", "zh-cht": "法語(摩納哥)", "xloc": [ - "default.handlebars->41->1607" + "default.handlebars->45->1622" ] }, { @@ -27674,7 +27733,7 @@ "zh-chs": "法文(标准)", "zh-cht": "法語(標準)", "xloc": [ - "default.handlebars->41->1602" + "default.handlebars->45->1617" ] }, { @@ -27699,7 +27758,7 @@ "zh-chs": "法文(瑞士)", "zh-cht": "法語(瑞士)", "xloc": [ - "default.handlebars->41->1608" + "default.handlebars->45->1623" ] }, { @@ -27724,7 +27783,7 @@ "zh-chs": "弗里斯兰文", "zh-cht": "弗里斯蘭語", "xloc": [ - "default.handlebars->41->1609" + "default.handlebars->45->1624" ] }, { @@ -27749,7 +27808,7 @@ "zh-chs": "弗留利", "zh-cht": "弗留利", "xloc": [ - "default.handlebars->41->1610" + "default.handlebars->45->1625" ] }, { @@ -27778,9 +27837,9 @@ "default-mobile.handlebars->11->640", "default-mobile.handlebars->11->657", "default-mobile.handlebars->11->677", - "default.handlebars->41->1816", - "default.handlebars->41->2029", - "default.handlebars->41->2477" + "default.handlebars->45->1831", + "default.handlebars->45->2044", + "default.handlebars->45->2492" ] }, { @@ -27805,7 +27864,7 @@ "zh-chs": "完整管理员(保留所有权利)", "zh-cht": "完整管理員(保留所有權利)", "xloc": [ - "default.handlebars->41->2067" + "default.handlebars->45->2082" ] }, { @@ -27852,7 +27911,7 @@ "zh-chs": "完整设备权限", "zh-cht": "完整裝置權限", "xloc": [ - "default.handlebars->41->993" + "default.handlebars->45->1007" ] }, { @@ -27877,7 +27936,7 @@ "zh-chs": "全部权限", "zh-cht": "全部權限", "xloc": [ - "default.handlebars->41->1012" + "default.handlebars->45->1026" ] }, { @@ -27955,7 +28014,7 @@ "zh-chs": "完整管理员", "zh-cht": "完整管理員", "xloc": [ - "default.handlebars->41->2581" + "default.handlebars->45->2596" ] }, { @@ -27980,8 +28039,8 @@ "zh-chs": "全自动的", "zh-cht": "全自動的", "xloc": [ - "default.handlebars->41->1902", - "default.handlebars->41->1959" + "default.handlebars->45->1917", + "default.handlebars->45->1974" ] }, { @@ -28007,7 +28066,7 @@ "zh-cht": "GPU", "xloc": [ "default-mobile.handlebars->11->588", - "default.handlebars->41->1470" + "default.handlebars->45->1485" ] }, { @@ -28032,7 +28091,7 @@ "zh-chs": "盖尔文(爱尔兰)", "zh-cht": "蓋爾語(愛爾蘭)", "xloc": [ - "default.handlebars->41->1612" + "default.handlebars->45->1627" ] }, { @@ -28057,7 +28116,7 @@ "zh-chs": "盖尔文(苏格兰文)", "zh-cht": "蓋爾語(蘇格蘭語)", "xloc": [ - "default.handlebars->41->1611" + "default.handlebars->45->1626" ] }, { @@ -28082,7 +28141,7 @@ "zh-chs": "加拉契文", "zh-cht": "加拉契語", "xloc": [ - "default.handlebars->41->1613" + "default.handlebars->45->1628" ] }, { @@ -28107,7 +28166,14 @@ "zh-chs": "网关MAC", "zh-cht": "閘道MAC", "xloc": [ - "default.handlebars->41->159" + "default.handlebars->45->160" + ] + }, + { + "en": "Gateway: {0}", + "xloc": [ + "default-mobile.handlebars->11->556", + "default.handlebars->45->1453" ] }, { @@ -28188,7 +28254,7 @@ "zh-chs": "一般信息", "zh-cht": "一般訊息", "xloc": [ - "default.handlebars->41->753" + "default.handlebars->45->761" ] }, { @@ -28213,7 +28279,7 @@ "zh-chs": "生成新保安编码", "zh-cht": "產生新保安編碼", "xloc": [ - "default.handlebars->41->217" + "default.handlebars->45->218" ] }, { @@ -28233,7 +28299,7 @@ "ru": "Создать отчет", "tr": "Rapor oluştur", "xloc": [ - "default.handlebars->41->2794" + "default.handlebars->45->2809" ] }, { @@ -28278,7 +28344,7 @@ "zh-chs": "格鲁吉亚文", "zh-cht": "格魯吉亞文", "xloc": [ - "default.handlebars->41->1614" + "default.handlebars->45->1629" ] }, { @@ -28303,7 +28369,7 @@ "zh-chs": "德文(奥地利)", "zh-cht": "德語(奧地利)", "xloc": [ - "default.handlebars->41->1616" + "default.handlebars->45->1631" ] }, { @@ -28328,7 +28394,7 @@ "zh-chs": "德文(德国)", "zh-cht": "德文(德國)", "xloc": [ - "default.handlebars->41->1617" + "default.handlebars->45->1632" ] }, { @@ -28353,7 +28419,7 @@ "zh-chs": "德文(列支敦士登)", "zh-cht": "德文(列支敦士登)", "xloc": [ - "default.handlebars->41->1618" + "default.handlebars->45->1633" ] }, { @@ -28378,7 +28444,7 @@ "zh-chs": "德文(卢森堡)", "zh-cht": "德語(盧森堡)", "xloc": [ - "default.handlebars->41->1619" + "default.handlebars->45->1634" ] }, { @@ -28403,7 +28469,7 @@ "zh-chs": "德文(标准)", "zh-cht": "德語(標準)", "xloc": [ - "default.handlebars->41->1615" + "default.handlebars->45->1630" ] }, { @@ -28428,7 +28494,7 @@ "zh-chs": "德文(瑞士)", "zh-cht": "德文(瑞士)", "xloc": [ - "default.handlebars->41->1620" + "default.handlebars->45->1635" ] }, { @@ -28448,7 +28514,7 @@ "ru": "Получить буфер", "tr": "Pano Al", "xloc": [ - "default.handlebars->41->1270" + "default.handlebars->45->1285" ] }, { @@ -28473,7 +28539,7 @@ "zh-chs": "获取此设备的MQTT登录凭证。", "zh-cht": "獲取此裝置的MQTT登入憑證。", "xloc": [ - "default.handlebars->41->936" + "default.handlebars->45->946" ] }, { @@ -28524,7 +28590,7 @@ "zh-chs": "正在获取剪贴板内容,{0}个字节", "zh-cht": "正在獲取剪貼板內容,{0}個字節", "xloc": [ - "default.handlebars->41->2217" + "default.handlebars->45->2232" ] }, { @@ -28601,7 +28667,7 @@ "zh-chs": "好", "zh-cht": "好", "xloc": [ - "default.handlebars->41->1812" + "default.handlebars->45->1827" ] }, { @@ -28656,9 +28722,9 @@ "zh-chs": "Google云端硬盘备份", "zh-cht": "Google雲端硬盤備份", "xloc": [ - "default.handlebars->41->1833", - "default.handlebars->41->1836", - "default.handlebars->41->303" + "default.handlebars->45->1848", + "default.handlebars->45->1851", + "default.handlebars->45->304" ] }, { @@ -28683,7 +28749,7 @@ "zh-chs": "Google云端硬盘控制台", "zh-cht": "Google雲端硬盤控制台", "xloc": [ - "default.handlebars->41->1830" + "default.handlebars->45->1845" ] }, { @@ -28733,7 +28799,7 @@ "zh-chs": "Google云端硬盘备份当前处于活动状态。", "zh-cht": "Google雲端硬盤備份當前處於活動狀態。", "xloc": [ - "default.handlebars->41->1834" + "default.handlebars->45->1849" ] }, { @@ -28782,7 +28848,7 @@ "zh-chs": "希腊文", "zh-cht": "希臘文", "xloc": [ - "default.handlebars->41->1621" + "default.handlebars->45->1636" ] }, { @@ -28808,8 +28874,8 @@ "zh-cht": "群", "xloc": [ "default-mobile.handlebars->11->271", - "default.handlebars->41->2810", - "default.handlebars->41->781", + "default.handlebars->45->2825", + "default.handlebars->45->789", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSort->sortselect->1" ] }, @@ -28835,9 +28901,9 @@ "zh-chs": "集体指令", "zh-cht": "集體指令", "xloc": [ - "default.handlebars->41->2419", - "default.handlebars->41->2501", - "default.handlebars->41->658", + "default.handlebars->45->2434", + "default.handlebars->45->2516", + "default.handlebars->45->661", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar", "default.handlebars->container->column_l->p4->3->1->0->3->3", "default.handlebars->container->column_l->p50->3->1->0->3->p50userGroupOps" @@ -28865,7 +28931,7 @@ "zh-chs": "通过...分组", "zh-cht": "通過...分群", "xloc": [ - "default.handlebars->41->2366" + "default.handlebars->45->2381" ] }, { @@ -28891,7 +28957,7 @@ "zh-cht": "群標識符", "xloc": [ "agent-translations.json", - "default.handlebars->41->2518" + "default.handlebars->45->2533" ] }, { @@ -28916,7 +28982,7 @@ "zh-chs": "群组成员", "zh-cht": "群組成員", "xloc": [ - "default.handlebars->41->2542" + "default.handlebars->45->2557" ] }, { @@ -28952,8 +29018,8 @@ "zh-chs": "通过...分组", "zh-cht": "通過...分群", "xloc": [ - "default.handlebars->41->2780", - "default.handlebars->41->2783" + "default.handlebars->45->2795", + "default.handlebars->45->2798" ] }, { @@ -28973,7 +29039,7 @@ "ru": "Имя группы", "tr": "Grup ismi", "xloc": [ - "default.handlebars->41->2350" + "default.handlebars->45->2365" ] }, { @@ -28998,7 +29064,7 @@ "zh-chs": "用户{0}的群组权限。", "zh-cht": "用戶{0}的群組權限。", "xloc": [ - "default.handlebars->41->2028" + "default.handlebars->45->2043" ] }, { @@ -29023,7 +29089,7 @@ "zh-chs": "{0}的群组权限。", "zh-cht": "{0}的群組權限。", "xloc": [ - "default.handlebars->41->2027" + "default.handlebars->45->2042" ] }, { @@ -29118,7 +29184,7 @@ "ru": "Гость", "tr": "Misafir", "xloc": [ - "default.handlebars->41->2800" + "default.handlebars->45->2815" ] }, { @@ -29143,8 +29209,8 @@ "zh-chs": "访客姓名", "zh-cht": "來賓姓名", "xloc": [ - "default.handlebars->41->1048", - "default.handlebars->41->267" + "default.handlebars->45->1063", + "default.handlebars->45->268" ] }, { @@ -29168,8 +29234,8 @@ "tr": "Misafir Paylaşımı", "zh-chs": "嘉宾分享", "xloc": [ - "default.handlebars->41->1000", - "default.handlebars->41->1022" + "default.handlebars->45->1014", + "default.handlebars->45->1036" ] }, { @@ -29193,7 +29259,7 @@ "tr": "Misafir Paylaşımı", "zh-chs": "嘉宾分享", "xloc": [ - "default.handlebars->41->2036" + "default.handlebars->45->2051" ] }, { @@ -29218,7 +29284,7 @@ "zh-chs": "古久拉提", "zh-cht": "古久拉提", "xloc": [ - "default.handlebars->41->1622" + "default.handlebars->45->1637" ] }, { @@ -29242,7 +29308,21 @@ "tr": "HTTP", "zh-chs": "HTTP", "xloc": [ - "default.handlebars->41->2931" + "default.handlebars->45->2946", + "default.handlebars->45->392", + "default.handlebars->45->931" + ] + }, + { + "en": "HTTP Connection", + "xloc": [ + "default.handlebars->45->750" + ] + }, + { + "en": "HTTP remote connection port:", + "xloc": [ + "default.handlebars->45->749" ] }, { @@ -29264,7 +29344,23 @@ "ru": "HTTPS", "sv": "HTTPS", "tr": "HTTPS", - "zh-chs": "HTTPS" + "zh-chs": "HTTPS", + "xloc": [ + "default.handlebars->45->393", + "default.handlebars->45->932" + ] + }, + { + "en": "HTTPS Connection", + "xloc": [ + "default.handlebars->45->752" + ] + }, + { + "en": "HTTPS remote connection port:", + "xloc": [ + "default.handlebars->45->751" + ] }, { "cs": "HW připojení", @@ -29316,7 +29412,7 @@ "zh-chs": "海地文", "zh-cht": "海地文", "xloc": [ - "default.handlebars->41->1623" + "default.handlebars->45->1638" ] }, { @@ -29340,7 +29436,7 @@ "tr": "Tutamaç Sayısı", "zh-chs": "处理计数", "xloc": [ - "default.handlebars->41->123" + "default.handlebars->45->124" ] }, { @@ -29391,7 +29487,7 @@ "zh-cht": "強行斷開代理", "xloc": [ "default-mobile.handlebars->11->618", - "default.handlebars->41->1501" + "default.handlebars->45->1516" ] }, { @@ -29399,8 +29495,9 @@ "nl": "Hardware OTP", "pl": "Sprzętowe OTP", "ru": "Аппаратный OTP", + "fr": "Clé OTP matérielle", "xloc": [ - "default.handlebars->41->2835" + "default.handlebars->45->2850" ] }, { @@ -29425,7 +29522,7 @@ "zh-chs": "堆总数", "zh-cht": "堆總數", "xloc": [ - "default.handlebars->41->2949" + "default.handlebars->45->2964" ] }, { @@ -29450,7 +29547,7 @@ "zh-chs": "堆使用", "zh-cht": "堆使用", "xloc": [ - "default.handlebars->41->2948" + "default.handlebars->45->2963" ] }, { @@ -29475,7 +29572,7 @@ "zh-chs": "希伯来文", "zh-cht": "希伯來文", "xloc": [ - "default.handlebars->41->1624" + "default.handlebars->45->1639" ] }, { @@ -29572,7 +29669,7 @@ "zh-chs": "已请求帮助,用户:{0},详细信息:{1}", "zh-cht": "已請求幫助,用戶:{0},詳細信息:{1}", "xloc": [ - "default.handlebars->41->2294" + "default.handlebars->45->2309" ] }, { @@ -29598,7 +29695,7 @@ "zh-cht": "幫助請求", "xloc": [ "default-mobile.handlebars->11->200", - "default.handlebars->41->395" + "default.handlebars->45->398" ] }, { @@ -29623,7 +29720,7 @@ "zh-chs": "从{0}请求的帮助:{1}", "zh-cht": "從{0}請求的幫助:{1}", "xloc": [ - "default.handlebars->41->241" + "default.handlebars->45->242" ] }, { @@ -29648,7 +29745,7 @@ "zh-chs": "帮助翻译MeshCentral", "zh-cht": "幫助翻譯MeshCentral", "xloc": [ - "default.handlebars->41->1739" + "default.handlebars->45->1754" ] }, { @@ -29751,8 +29848,8 @@ "xloc": [ "default-mobile.handlebars->11->234", "default-mobile.handlebars->11->242", - "default.handlebars->41->5", - "default.handlebars->41->608" + "default.handlebars->45->5", + "default.handlebars->45->611" ] }, { @@ -29777,7 +29874,7 @@ "zh-chs": "印地文", "zh-cht": "印地文", "xloc": [ - "default.handlebars->41->1625" + "default.handlebars->45->1640" ] }, { @@ -29825,7 +29922,7 @@ "zh-cht": "保存1個項目進行複製", "xloc": [ "default-mobile.handlebars->11->496", - "default.handlebars->41->1375", + "default.handlebars->45->1390", "sharing.handlebars->11->76" ] }, @@ -29852,7 +29949,7 @@ "zh-cht": "保存1個項目進行移動", "xloc": [ "default-mobile.handlebars->11->500", - "default.handlebars->41->1379", + "default.handlebars->45->1394", "sharing.handlebars->11->80" ] }, @@ -29879,7 +29976,7 @@ "zh-cht": "保留{0}個項目進行複製", "xloc": [ "default-mobile.handlebars->11->494", - "default.handlebars->41->1373", + "default.handlebars->45->1388", "sharing.handlebars->11->74" ] }, @@ -29906,7 +30003,7 @@ "zh-cht": "保存{0}個項目以進行移動", "xloc": [ "default-mobile.handlebars->11->498", - "default.handlebars->41->1377", + "default.handlebars->45->1392", "sharing.handlebars->11->78" ] }, @@ -29933,7 +30030,7 @@ "zh-cht": "保存{0}項目{1}給{2}", "xloc": [ "default-mobile.handlebars->11->160", - "default.handlebars->41->2190" + "default.handlebars->45->2205" ] }, { @@ -29958,7 +30055,7 @@ "zh-chs": "家", "xloc": [ "default-mobile.handlebars->11->421", - "default.handlebars->41->1243" + "default.handlebars->45->1258" ] }, { @@ -29989,13 +30086,13 @@ "default-mobile.handlebars->11->401", "default-mobile.handlebars->11->547", "default-mobile.handlebars->11->633", - "default.handlebars->41->1192", - "default.handlebars->41->1419", - "default.handlebars->41->1805", - "default.handlebars->41->1863", - "default.handlebars->41->447", - "default.handlebars->41->456", - "default.handlebars->41->786" + "default.handlebars->45->1207", + "default.handlebars->45->1434", + "default.handlebars->45->1820", + "default.handlebars->45->1878", + "default.handlebars->45->450", + "default.handlebars->45->459", + "default.handlebars->45->794" ] }, { @@ -30020,7 +30117,7 @@ "zh-chs": "主机名同步", "zh-cht": "主機名同步", "xloc": [ - "default.handlebars->41->1870" + "default.handlebars->45->1885" ] }, { @@ -30045,15 +30142,17 @@ "zh-chs": "匈牙利文", "zh-cht": "匈牙利文", "xloc": [ - "default.handlebars->41->1626" + "default.handlebars->45->1641" ] }, { "en": "Hybrid required by server", "nl": "Hybride vereist door de server", + "pl": "Tryb Hybrydowy wymagany przez serwer", "ru": "Cервер требует гибридный режим", + "fr": "Hybrid requis par le serveur", "xloc": [ - "default.handlebars->41->1209" + "default.handlebars->45->1224" ] }, { @@ -30064,8 +30163,8 @@ "pt-br": "Endereço IP", "ru": "IP Адрес", "xloc": [ - "default.handlebars->41->2805", - "default.handlebars->41->2840" + "default.handlebars->45->2820", + "default.handlebars->45->2855" ] }, { @@ -30124,8 +30223,8 @@ "zh-chs": "IP范围", "zh-cht": "IP範圍", "xloc": [ - "default.handlebars->41->477", - "default.handlebars->41->479" + "default.handlebars->45->480", + "default.handlebars->45->482" ] }, { @@ -30174,8 +30273,8 @@ "default-mobile.handlebars->11->255", "default-mobile.handlebars->11->312", "default-mobile.handlebars->11->341", - "default.handlebars->41->374", - "default.handlebars->41->626" + "default.handlebars->45->375", + "default.handlebars->45->629" ] }, { @@ -30195,7 +30294,7 @@ "ru": "IP-KVM / Устройство питания", "tr": "IP-KVM / Güç cihazı", "xloc": [ - "default.handlebars->41->1795" + "default.handlebars->45->1810" ] }, { @@ -30203,8 +30302,9 @@ "nl": "IP-KVM / Power-apparaat doorgestuurd via agent", "pl": "IP-KVM / Urządzenie zasilające przekierowane przez agenta", "ru": "IP-KVM / Устройство питания, ретранслируемое через агента", + "fr": "Appareil IP-KVM / Power relayé par l'agent", "xloc": [ - "default.handlebars->41->1796" + "default.handlebars->45->1811" ] }, { @@ -30225,7 +30325,7 @@ "tr": "IP-KVM cihazı", "xloc": [ "default-mobile.handlebars->11->625", - "default.handlebars->41->1855" + "default.handlebars->45->1870" ] }, { @@ -30233,9 +30333,10 @@ "nl": "IP-KVM-apparaat doorgestuurd via agent", "pl": "Urządzenie IP-KVM przekierowane przzez agenta", "ru": "Устройство IP-KVM ретранслируемое через агента", + "fr": "Appareil IP-KAM relayé par l'agent", "xloc": [ "default-mobile.handlebars->11->626", - "default.handlebars->41->1856" + "default.handlebars->45->1871" ] }, { @@ -30255,8 +30356,8 @@ "ru": "Порт IP-KVM подключен", "tr": "IP-KVM bağlantı noktası bağlandı", "xloc": [ - "default.handlebars->41->942", - "default.handlebars->41->943" + "default.handlebars->45->952", + "default.handlebars->45->953" ] }, { @@ -30276,7 +30377,7 @@ "ru": "Порт IP-KVM подключен и готов к использованию.", "tr": "IP-KVM portu bağlı ve kullanıma hazır.", "xloc": [ - "default.handlebars->41->373" + "default.handlebars->45->374" ] }, { @@ -30296,7 +30397,7 @@ "ru": "Порт IP-KVM запущен и готов к использованию.", "tr": "IP-KVM portu hazır ve kullanıma hazır.", "xloc": [ - "default.handlebars->41->625" + "default.handlebars->45->628" ] }, { @@ -30321,9 +30422,9 @@ "zh-chs": "IP:{0}", "zh-cht": "IP:{0}", "xloc": [ - "default.handlebars->41->1429", - "default.handlebars->41->1439", - "default.handlebars->41->1443" + "default-mobile.handlebars->11->554", + "default.handlebars->45->1444", + "default.handlebars->45->1451" ] }, { @@ -30348,9 +30449,7 @@ "zh-chs": "IP:{0},掩码:{1},网关:{2}", "zh-cht": "IP:{0},遮罩:{1},閘道:{2}", "xloc": [ - "default.handlebars->41->1427", - "default.handlebars->41->1437", - "default.handlebars->41->1441" + "default.handlebars->45->1442" ] }, { @@ -30375,12 +30474,10 @@ "zh-chs": "IPv4层", "zh-cht": "IPv4層", "xloc": [ - "default-mobile.handlebars->11->554", - "default-mobile.handlebars->11->556", - "default.handlebars->41->1426", - "default.handlebars->41->1428", - "default.handlebars->41->1436", - "default.handlebars->41->1438" + "default-mobile.handlebars->11->557", + "default.handlebars->45->1441", + "default.handlebars->45->1443", + "default.handlebars->45->1454" ] }, { @@ -30405,8 +30502,8 @@ "zh-chs": "IPv4地址", "zh-cht": "IPv4地址", "xloc": [ - "default.handlebars->41->153", - "default.handlebars->41->171" + "default.handlebars->45->154", + "default.handlebars->45->172" ] }, { @@ -30431,8 +30528,8 @@ "zh-chs": "IPv4网关", "zh-cht": "IPv4閘道", "xloc": [ - "default.handlebars->41->157", - "default.handlebars->41->175" + "default.handlebars->45->158", + "default.handlebars->45->176" ] }, { @@ -30457,8 +30554,8 @@ "zh-chs": "IPv4掩码", "zh-cht": "IPv4遮罩", "xloc": [ - "default.handlebars->41->155", - "default.handlebars->41->173" + "default.handlebars->45->156", + "default.handlebars->45->174" ] }, { @@ -30483,10 +30580,8 @@ "zh-chs": "IPv6层", "zh-cht": "IPv6層", "xloc": [ - "default-mobile.handlebars->11->558", - "default-mobile.handlebars->11->560", - "default.handlebars->41->1440", - "default.handlebars->41->1442" + "default-mobile.handlebars->11->559", + "default.handlebars->45->1456" ] }, { @@ -30511,7 +30606,7 @@ "zh-chs": "IPv6地址", "zh-cht": "IPv6地址", "xloc": [ - "default.handlebars->41->165" + "default.handlebars->45->166" ] }, { @@ -30536,7 +30631,7 @@ "zh-chs": "IPv6网关", "zh-cht": "IPv6閘道", "xloc": [ - "default.handlebars->41->169" + "default.handlebars->45->170" ] }, { @@ -30561,7 +30656,7 @@ "zh-chs": "IPv6掩码", "zh-cht": "IPv6遮罩", "xloc": [ - "default.handlebars->41->167" + "default.handlebars->45->168" ] }, { @@ -30586,7 +30681,7 @@ "zh-chs": "冰岛文", "zh-cht": "冰島文", "xloc": [ - "default.handlebars->41->1627" + "default.handlebars->45->1642" ] }, { @@ -30612,7 +30707,7 @@ "zh-cht": "圖符選擇", "xloc": [ "default-mobile.handlebars->11->395", - "default.handlebars->41->1186" + "default.handlebars->45->1201" ] }, { @@ -30639,8 +30734,8 @@ "xloc": [ "default-mobile.handlebars->11->546", "default-mobile.handlebars->11->586", - "default.handlebars->41->1418", - "default.handlebars->41->1468" + "default.handlebars->45->1433", + "default.handlebars->45->1483" ] }, { @@ -30665,7 +30760,7 @@ "zh-chs": "如果在CCM中,请重新激活英特尔®AMT", "zh-cht": "如果在CCM中,請重新激活英特爾®AMT", "xloc": [ - "default.handlebars->41->1973" + "default.handlebars->45->1988" ] }, { @@ -30841,9 +30936,9 @@ "tr": "Intel® AMT Cihazlarını İçe Aktarın", "zh-chs": "导入英特尔® AMT 设备", "xloc": [ - "default.handlebars->41->1947", - "default.handlebars->41->1948", - "default.handlebars->41->1952" + "default.handlebars->45->1962", + "default.handlebars->45->1963", + "default.handlebars->45->1967" ] }, { @@ -30867,7 +30962,7 @@ "tr": "MeshCommander JSON formatında yerel Intel® AMT cihazlarının bir listesini içe aktarın.", "zh-chs": "以 MeshCommander JSON 格式导入本地英特尔® AMT 设备列表。", "xloc": [ - "default.handlebars->41->1946" + "default.handlebars->45->1961" ] }, { @@ -30891,7 +30986,7 @@ "tr": "Cihaz listesini içe aktar", "zh-chs": "导入设备列表", "xloc": [ - "default.handlebars->41->1942" + "default.handlebars->45->1957" ] }, { @@ -30915,7 +31010,7 @@ "tr": "Anında bildirim kimlik doğrulamasını kullanmak için, hesabınızda tam haklara sahip bir mobil cihaz kurulmalıdır.", "zh-chs": "为了使用推送通知身份验证,必须在您的帐户中设置具有完全权限的移动设备。", "xloc": [ - "default.handlebars->41->1522" + "default.handlebars->45->1537" ] }, { @@ -30939,7 +31034,7 @@ "tr": "Kaldırılana kadar günleri devre dışı bırak", "zh-chs": "停用天数直到移除", "xloc": [ - "default.handlebars->41->2013" + "default.handlebars->45->2028" ] }, { @@ -30987,7 +31082,7 @@ "tr": "Cihaz ayrıntılarını dahil et", "zh-chs": "包括设备详细信息", "xloc": [ - "default.handlebars->41->707" + "default.handlebars->45->711" ] }, { @@ -31035,9 +31130,11 @@ { "en": "Inconsistent flags", "nl": "Inconsistente vlaggen", + "pl": "Niespójne argumenty", "ru": "Несоответствие флагов", + "fr": "Indicateurs incohérents", "xloc": [ - "default.handlebars->41->1208" + "default.handlebars->45->1223" ] }, { @@ -31048,8 +31145,8 @@ "pt-br": "2ª etapa incorreta", "ru": "Неверный 2-й фактор", "xloc": [ - "default.handlebars->41->2828", - "default.handlebars->41->2848" + "default.handlebars->45->2843", + "default.handlebars->45->2863" ] }, { @@ -31100,9 +31197,9 @@ "zh-cht": "個別裝置", "xloc": [ "default-mobile.handlebars->11->187", - "default.handlebars->41->333", - "default.handlebars->41->334", - "default.handlebars->41->335" + "default.handlebars->45->334", + "default.handlebars->45->335", + "default.handlebars->45->336" ] }, { @@ -31127,7 +31224,7 @@ "zh-chs": "印度尼西亚文", "zh-cht": "印度尼西亞文", "xloc": [ - "default.handlebars->41->1628" + "default.handlebars->45->1643" ] }, { @@ -31229,7 +31326,7 @@ "zh-chs": "插", "xloc": [ "default-mobile.handlebars->11->419", - "default.handlebars->41->1241" + "default.handlebars->45->1256" ] }, { @@ -31279,7 +31376,7 @@ "zh-chs": "安装 Google Authenticator或兼容的应用软件并扫描条码,使用此连结或输入密码。然后,在下面输入当前的6位数保安编码以激活两步登录。", "zh-cht": "安裝 Google Authenticator或兼容的應用軟體並掃描條碼,使用此鏈結或輸入密碼。然後,在下面輸入當前的6位數保安編碼以啟動兩步登入。", "xloc": [ - "default.handlebars->41->201" + "default.handlebars->45->202" ] }, { @@ -31463,12 +31560,12 @@ "zh-chs": "安装类型", "zh-cht": "安裝方式", "xloc": [ - "default.handlebars->41->2108", - "default.handlebars->41->2115", - "default.handlebars->41->507", - "default.handlebars->41->527", - "default.handlebars->41->543", - "default.handlebars->41->547" + "default.handlebars->45->2123", + "default.handlebars->45->2130", + "default.handlebars->45->510", + "default.handlebars->45->530", + "default.handlebars->45->546", + "default.handlebars->45->550" ] }, { @@ -31493,7 +31590,7 @@ "zh-chs": "英特尔(F10 = ESC + [OM)", "zh-cht": "Intel(F10 = ESC + [OM)", "xloc": [ - "default.handlebars->41->1331", + "default.handlebars->45->1346", "default.handlebars->container->column_l->p12->termTable->1->1->4->1->1->terminalSettingsButtons", "sharing.handlebars->11->36", "sharing.handlebars->p12->9->1->terminalSettingsButtons" @@ -31521,7 +31618,7 @@ "zh-chs": "英特尔AMT", "zh-cht": "英特爾AMT", "xloc": [ - "default.handlebars->41->2945" + "default.handlebars->45->2960" ] }, { @@ -31541,7 +31638,7 @@ "ru": "Intel AMT CIRA подключен", "tr": "Intel AMT CIRA bağlandı", "xloc": [ - "default.handlebars->41->245" + "default.handlebars->45->246" ] }, { @@ -31561,7 +31658,7 @@ "ru": "Intel AMT CIRA отключен", "tr": "Intel AMT CIRA'nın bağlantısı kesildi", "xloc": [ - "default.handlebars->41->249" + "default.handlebars->45->250" ] }, { @@ -31581,7 +31678,7 @@ "ru": "Обнаружен Intel AMT", "tr": "Intel AMT algılandı", "xloc": [ - "default.handlebars->41->244" + "default.handlebars->45->245" ] }, { @@ -31605,7 +31702,7 @@ "tr": "Intel AMT yöneticisi", "zh-chs": "英特尔 AMT 经理", "xloc": [ - "default.handlebars->41->2974" + "default.handlebars->45->2989" ] }, { @@ -31625,7 +31722,7 @@ "ru": "Intel AMT не обнаружен", "tr": "Intel AMT algılanmadı", "xloc": [ - "default.handlebars->41->248" + "default.handlebars->45->249" ] }, { @@ -31650,7 +31747,7 @@ "zh-chs": "英特尔ASCII", "zh-cht": "Intel ASCII", "xloc": [ - "default.handlebars->41->1330", + "default.handlebars->45->1345", "sharing.handlebars->11->35" ] }, @@ -31679,15 +31776,16 @@ "default-mobile.handlebars->11->258", "default-mobile.handlebars->11->308", "default-mobile.handlebars->11->315", - "default.handlebars->41->1889", - "default.handlebars->41->1903", - "default.handlebars->41->2130", - "default.handlebars->41->2143", - "default.handlebars->41->2973", - "default.handlebars->41->756", - "default.handlebars->41->823", - "default.handlebars->41->862", - "default.handlebars->41->872" + "default.handlebars->45->1904", + "default.handlebars->45->1918", + "default.handlebars->45->2145", + "default.handlebars->45->2158", + "default.handlebars->45->2988", + "default.handlebars->45->764", + "default.handlebars->45->831", + "default.handlebars->45->870", + "default.handlebars->45->880", + "default.handlebars->45->966" ] }, { @@ -31712,7 +31810,7 @@ "zh-chs": "英特尔®AMT ACM", "zh-cht": "英特爾®AMT ACM", "xloc": [ - "default.handlebars->41->475" + "default.handlebars->45->478" ] }, { @@ -31738,7 +31836,7 @@ "zh-cht": "Intel® AMT CIRA", "xloc": [ "default-mobile.handlebars->11->314", - "default.handlebars->41->870" + "default.handlebars->45->878" ] }, { @@ -31807,9 +31905,9 @@ "zh-chs": "英特尔®AMT CIRA已连接并可以使用。", "zh-cht": "Intel® AMT CIRA已連接並可以使用。", "xloc": [ - "default.handlebars->41->377", - "default.handlebars->41->629", - "default.handlebars->41->869" + "default.handlebars->45->378", + "default.handlebars->45->632", + "default.handlebars->45->877" ] }, { @@ -31835,7 +31933,7 @@ "zh-cht": "Intel® AMT已連接", "xloc": [ "default-mobile.handlebars->11->5", - "default.handlebars->41->12", + "default.handlebars->45->12", "sharing.handlebars->11->5", "xterm.handlebars->9->5" ] @@ -31861,7 +31959,7 @@ "tr": "Intel® AMT JSON", "zh-chs": "英特尔® AMT JSON", "xloc": [ - "default.handlebars->41->705" + "default.handlebars->45->709" ] }, { @@ -31910,8 +32008,8 @@ "tr": "Intel® AMT Tek Tıkla Kurtarma", "zh-chs": "英特尔® AMT 一键恢复", "xloc": [ - "default.handlebars->41->1104", - "default.handlebars->41->1117" + "default.handlebars->45->1119", + "default.handlebars->45->1132" ] }, { @@ -31936,7 +32034,7 @@ "zh-chs": "英特尔®AMT政策", "zh-cht": "Intel® AMT政策", "xloc": [ - "default.handlebars->41->1960" + "default.handlebars->45->1975" ] }, { @@ -31963,9 +32061,9 @@ "default-mobile.handlebars->11->374", "default-mobile.handlebars->11->376", "default-mobile.handlebars->11->378", - "default.handlebars->41->1118", - "default.handlebars->41->1120", - "default.handlebars->41->1122" + "default.handlebars->45->1133", + "default.handlebars->45->1135", + "default.handlebars->45->1137" ] }, { @@ -31989,8 +32087,8 @@ "tr": "Intel® AMT Kapatma", "zh-chs": "英特尔® AMT 关机", "xloc": [ - "default-mobile.handlebars->11->370", - "default.handlebars->41->1103" + "default-mobile.handlebars->11->369", + "default.handlebars->45->1117" ] }, { @@ -32014,8 +32112,8 @@ "tr": "Intel® AMT Gücü açık", "zh-chs": "英特尔® AMT 开机", "xloc": [ - "default-mobile.handlebars->11->369", - "default.handlebars->41->1102" + "default-mobile.handlebars->11->370", + "default.handlebars->45->1118" ] }, { @@ -32040,8 +32138,8 @@ "zh-chs": "英特尔®AMT重定向", "zh-cht": "Intel® AMT重定向", "xloc": [ - "default.handlebars->41->2749", - "default.handlebars->41->2756", + "default.handlebars->45->2764", + "default.handlebars->45->2771", "player.handlebars->3->30" ] }, @@ -32067,7 +32165,7 @@ "zh-chs": "英特尔® AMT 重置", "xloc": [ "default-mobile.handlebars->11->368", - "default.handlebars->41->1101" + "default.handlebars->45->1116" ] }, { @@ -32092,7 +32190,7 @@ "zh-chs": "英特尔®AMT标签", "zh-cht": "Intel® AMT標籤", "xloc": [ - "default.handlebars->41->827" + "default.handlebars->45->835" ] }, { @@ -32117,8 +32215,8 @@ "zh-chs": "英特尔®AMT WSMAN", "zh-cht": "Intle® AMT WSMAN", "xloc": [ - "default.handlebars->41->2748", - "default.handlebars->41->2755", + "default.handlebars->45->2763", + "default.handlebars->45->2770", "player.handlebars->3->29" ] }, @@ -32167,8 +32265,8 @@ "zh-cht": "Intel ®AMT已連接", "xloc": [ "default-mobile.handlebars->11->343", - "default.handlebars->41->946", - "default.handlebars->41->947" + "default.handlebars->45->956", + "default.handlebars->45->957" ] }, { @@ -32193,9 +32291,9 @@ "zh-chs": "英特尔®AMT桌面和串行事件", "zh-cht": "Intel® AMT桌面和串行事件", "xloc": [ - "default.handlebars->41->1766", - "default.handlebars->41->2123", - "default.handlebars->41->988" + "default.handlebars->45->1002", + "default.handlebars->45->1781", + "default.handlebars->45->2138" ] }, { @@ -32221,8 +32319,8 @@ "zh-cht": "檢測到Intel® AMT", "xloc": [ "default-mobile.handlebars->11->344", - "default.handlebars->41->948", - "default.handlebars->41->949" + "default.handlebars->45->958", + "default.handlebars->45->959" ] }, { @@ -32247,7 +32345,7 @@ "zh-chs": "在Intel® AMT尔AMT", "zh-cht": "在管理控制模式下啟動了Intel® AMT", "xloc": [ - "default.handlebars->41->809" + "default.handlebars->45->817" ] }, { @@ -32272,7 +32370,7 @@ "zh-chs": "英特尔AMT在客户端控制模式下被激活", "zh-cht": "Intel® AMT在客户端控制模式下被启动", "xloc": [ - "default.handlebars->41->807" + "default.handlebars->45->815" ] }, { @@ -32297,7 +32395,7 @@ "zh-chs": "英特尔®AMT可路由并可以使用。", "zh-cht": "Intel® AMT可路由並可以使用。", "xloc": [ - "default.handlebars->41->871" + "default.handlebars->45->879" ] }, { @@ -32322,8 +32420,8 @@ "zh-chs": "英特尔®AMT是可路由的。", "zh-cht": "Intel® AMT是可路由的。", "xloc": [ - "default.handlebars->41->379", - "default.handlebars->41->631" + "default.handlebars->45->380", + "default.handlebars->45->634" ] }, { @@ -32349,7 +32447,7 @@ "zh-cht": "Intel® AMT已設置TLS網絡安全性", "xloc": [ "default-mobile.handlebars->11->298", - "default.handlebars->41->811" + "default.handlebars->45->819" ] }, { @@ -32422,8 +32520,8 @@ "zh-cht": "僅限Intel® AMT,無代理", "xloc": [ "default-mobile.handlebars->11->621", - "default.handlebars->41->1799", - "default.handlebars->41->1851" + "default.handlebars->45->1814", + "default.handlebars->45->1866" ] }, { @@ -32448,7 +32546,7 @@ "zh-chs": "英特尔®AMT设置", "zh-cht": "英特爾®AMT設置", "xloc": [ - "default.handlebars->41->467" + "default.handlebars->45->470" ] }, { @@ -32495,7 +32593,7 @@ "zh-chs": "英特尔®主动管理技术", "zh-cht": "Intel® Active Management Technology", "xloc": [ - "default.handlebars->41->822" + "default.handlebars->45->830" ] }, { @@ -32521,7 +32619,7 @@ "zh-cht": "Intel ® Active Management Technology(Intel® AMT)", "xloc": [ "default-mobile.handlebars->11->578", - "default.handlebars->41->1460" + "default.handlebars->45->1475" ] }, { @@ -32547,7 +32645,7 @@ "zh-cht": "Intel® ME", "xloc": [ "default-mobile.handlebars->11->307", - "default.handlebars->41->821" + "default.handlebars->45->829" ] }, { @@ -32572,7 +32670,7 @@ "zh-chs": "英特尔®可管理性引擎", "zh-cht": "Intel® Management Engine", "xloc": [ - "default.handlebars->41->820" + "default.handlebars->45->828" ] }, { @@ -32598,7 +32696,8 @@ "zh-cht": "Intel® M", "xloc": [ "default-mobile.handlebars->11->309", - "default.handlebars->41->825" + "default.handlebars->45->833", + "default.handlebars->45->964" ] }, { @@ -32623,7 +32722,32 @@ "zh-chs": "英特尔®标准可管理性", "zh-cht": "Intel® Standard Manageability", "xloc": [ - "default.handlebars->41->824" + "default.handlebars->45->832" + ] + }, + { + "en": "Intel® Standard Manageability (Intel® SM)", + "nl": "Intel® Standaard beheerbaarheid (Intel® SM)", + "pl": "Intel® Standard Manageability (Intel® SM)", + "xloc": [ + "default-mobile.handlebars->11->577", + "default.handlebars->45->1474" + ] + }, + { + "en": "Intel®AMT", + "nl": "Intel®AMT", + "pl": "Intel®AMT", + "xloc": [ + "default.handlebars->45->965" + ] + }, + { + "en": "Intel®SM", + "nl": "Intel®SM", + "pl": "Intel®SM", + "xloc": [ + "default.handlebars->45->963" ] }, { @@ -32643,7 +32767,7 @@ "ru": "Изменение политик Intel(r) AMT", "tr": "Intel(r) AMT ilke değişikliği", "xloc": [ - "default.handlebars->41->2337" + "default.handlebars->45->2352" ] }, { @@ -32669,6 +32793,7 @@ "zh-cht": "Intel® AMT", "xloc": [ "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar->DevFilterSelect->11", + "default.handlebars->container->column_l->p14->p14title->5->p14deviceNamePrefix", "default.handlebars->container->dialog->dialogBody->dialog7->1->td7amtkvm" ] }, @@ -32692,10 +32817,7 @@ "sv": "Intel® AMT -", "tr": "Intel® AMT -", "zh-chs": "英特尔®AMT -", - "zh-cht": "Intel® AMT -", - "xloc": [ - "default.handlebars->container->column_l->p14->p14title->5" - ] + "zh-cht": "Intel® AMT -" }, { "cs": "Intel® AMT hardwarové KVM", @@ -32745,8 +32867,6 @@ "zh-chs": "英特尔®AMT重定向端口或KVM功能已禁用", "zh-cht": "Intel® AMT重定向端口或KVM功能已禁用", "xloc": [ - "default.handlebars->container->column_l->p11->p11warning->3", - "default.handlebars->container->column_l->p12->p12warning->3", "sharing.handlebars->p12->p12warning->3" ] }, @@ -32860,7 +32980,7 @@ "zh-chs": "互动", "zh-cht": "互動", "xloc": [ - "default.handlebars->41->1286" + "default.handlebars->45->1301" ] }, { @@ -32885,11 +33005,11 @@ "zh-chs": "仅限互动", "zh-cht": "僅限互動", "xloc": [ - "default.handlebars->41->2111", - "default.handlebars->41->2118", - "default.handlebars->41->510", - "default.handlebars->41->530", - "default.handlebars->41->546" + "default.handlebars->45->2126", + "default.handlebars->45->2133", + "default.handlebars->45->513", + "default.handlebars->45->533", + "default.handlebars->45->549" ] }, { @@ -32914,7 +33034,7 @@ "zh-chs": "介面", "zh-cht": "介面", "xloc": [ - "default.handlebars->41->916" + "default.handlebars->45->924" ] }, { @@ -32963,7 +33083,7 @@ "zh-chs": "因纽特文", "zh-cht": "因紐特文", "xloc": [ - "default.handlebars->41->1629" + "default.handlebars->45->1644" ] }, { @@ -32988,7 +33108,7 @@ "zh-chs": "无效的 2FA", "xloc": [ "default-mobile.handlebars->11->83", - "default.handlebars->41->307" + "default.handlebars->45->308" ] }, { @@ -33014,7 +33134,7 @@ "zh-cht": "無效證件", "xloc": [ "default-mobile.handlebars->11->303", - "default.handlebars->41->816" + "default.handlebars->45->824" ] }, { @@ -33039,7 +33159,7 @@ "zh-chs": "无效的设备组类型", "zh-cht": "無效的裝置群類型", "xloc": [ - "default.handlebars->41->2907" + "default.handlebars->45->2922" ] }, { @@ -33064,7 +33184,7 @@ "zh-chs": "无效的JSON", "zh-cht": "無效的JSON", "xloc": [ - "default.handlebars->41->2901" + "default.handlebars->45->2916" ] }, { @@ -33089,9 +33209,9 @@ "zh-chs": "无效的JSON档案格式。", "zh-cht": "無效的JSON檔案格式。", "xloc": [ - "default.handlebars->41->1953", - "default.handlebars->41->2439", - "default.handlebars->41->2441" + "default.handlebars->45->1968", + "default.handlebars->45->2454", + "default.handlebars->45->2456" ] }, { @@ -33116,8 +33236,8 @@ "zh-chs": "无效的JSON档案:{0}。", "zh-cht": "無效的JSON檔案:{0}。", "xloc": [ - "default.handlebars->41->1949", - "default.handlebars->41->2437" + "default.handlebars->45->1964", + "default.handlebars->45->2452" ] }, { @@ -33137,7 +33257,7 @@ "ru": "Недопустимый адрес электронной почты Let's Encrypt, не удалось разрешить: {0}", "tr": "Geçersiz Let's Encrypt e-posta adresi çözülemedi: {0}", "xloc": [ - "default.handlebars->41->97" + "default.handlebars->45->97" ] }, { @@ -33157,7 +33277,7 @@ "ru": "Недопустимые имена хостов Let's Encrypt.", "tr": "Geçersiz Let's Encrypt ana bilgisayar adları.", "xloc": [ - "default.handlebars->41->93" + "default.handlebars->45->93" ] }, { @@ -33177,7 +33297,7 @@ "ru": "Недопустимые имена Let's Encrypt, имена не могут содержать *.", "tr": "Geçersiz Let's Encrypt adları, * içeremez.", "xloc": [ - "default.handlebars->41->94" + "default.handlebars->45->94" ] }, { @@ -33197,7 +33317,7 @@ "ru": "Недопустимые имена Let's Encrypt, не удалось разрешить: {0}", "tr": "Geçersiz Let's Encrypt adları çözülemedi: {0}", "xloc": [ - "default.handlebars->41->96" + "default.handlebars->45->96" ] }, { @@ -33222,7 +33342,7 @@ "zh-chs": "无效的PKCS签名", "zh-cht": "無效的PKCS簽名", "xloc": [ - "default.handlebars->41->2899" + "default.handlebars->45->2914" ] }, { @@ -33247,7 +33367,7 @@ "zh-chs": "無效的RSA密碼", "zh-cht": "無效的RSA密碼", "xloc": [ - "default.handlebars->41->2900" + "default.handlebars->45->2915" ] }, { @@ -33272,7 +33392,7 @@ "zh-chs": "无效的短信", "xloc": [ "default-mobile.handlebars->11->738", - "default.handlebars->41->2886" + "default.handlebars->45->2901" ] }, { @@ -33292,7 +33412,7 @@ "ru": "Некорректный \\\"LoginCookieEncryptionKey\\\" в config.json.", "tr": "config.json'da geçersiz \\\"LoginCookieEncryptionKey\\\".", "xloc": [ - "default.handlebars->41->102" + "default.handlebars->45->102" ] }, { @@ -33344,7 +33464,7 @@ "zh-chs": "无效域", "xloc": [ "default-mobile.handlebars->11->718", - "default.handlebars->41->2866" + "default.handlebars->45->2881" ] }, { @@ -33390,7 +33510,7 @@ "zh-chs": "不合规电邮", "xloc": [ "default-mobile.handlebars->11->717", - "default.handlebars->41->2865" + "default.handlebars->45->2880" ] }, { @@ -33479,8 +33599,8 @@ "pt-br": "Tentativa de login inválida", "ru": "Неудачная попытка входа", "xloc": [ - "default.handlebars->41->2830", - "default.handlebars->41->2850" + "default.handlebars->45->2845", + "default.handlebars->45->2865" ] }, { @@ -33506,8 +33626,8 @@ "xloc": [ "default-mobile.handlebars->11->716", "default-mobile.handlebars->11->85", - "default.handlebars->41->2864", - "default.handlebars->41->309" + "default.handlebars->45->2879", + "default.handlebars->45->310" ] }, { @@ -33532,7 +33652,7 @@ "zh-chs": "网站权限无效", "xloc": [ "default-mobile.handlebars->11->719", - "default.handlebars->41->2867" + "default.handlebars->45->2882" ] }, { @@ -33583,7 +33703,7 @@ "tr": "{0}, {1}, {2}'den geçersiz kullanıcı giriş denemesi", "zh-chs": "来自 {0}、{1}、{2} 的无效用户登录尝试", "xloc": [ - "default.handlebars->41->2306" + "default.handlebars->45->2321" ] }, { @@ -33608,7 +33728,7 @@ "zh-chs": "无效的用户名", "xloc": [ "default-mobile.handlebars->11->715", - "default.handlebars->41->2863" + "default.handlebars->45->2878" ] }, { @@ -33654,7 +33774,7 @@ "zh-chs": "使电邮无效", "zh-cht": "使電郵無效", "xloc": [ - "default.handlebars->41->2413" + "default.handlebars->45->2428" ] }, { @@ -33701,7 +33821,7 @@ "zh-chs": "邀请连接({0})", "zh-cht": "邀請鏈結({0})", "xloc": [ - "default.handlebars->41->265" + "default.handlebars->45->266" ] }, { @@ -33726,7 +33846,7 @@ "zh-chs": "邀请类型", "zh-cht": "邀請類型", "xloc": [ - "default.handlebars->41->486" + "default.handlebars->45->489" ] }, { @@ -33751,7 +33871,7 @@ "zh-chs": "任何人都可以使用邀请代码通过以下公共连接将设备加入该设备组:", "zh-cht": "任何人都可以使用邀請代碼通過以下公共鏈結將裝置加入該裝置群:", "xloc": [ - "default.handlebars->41->2113" + "default.handlebars->45->2128" ] }, { @@ -33801,9 +33921,9 @@ "zh-chs": "邀请", "zh-cht": "邀請", "xloc": [ - "default.handlebars->41->1913", - "default.handlebars->41->442", - "default.handlebars->41->532" + "default.handlebars->45->1928", + "default.handlebars->45->445", + "default.handlebars->45->535" ] }, { @@ -33829,12 +33949,12 @@ "zh-cht": "邀請碼", "xloc": [ "default-mobile.handlebars->11->713", - "default.handlebars->41->1895", - "default.handlebars->41->2101", - "default.handlebars->41->2112", - "default.handlebars->41->2114", - "default.handlebars->41->2119", - "default.handlebars->41->2861" + "default.handlebars->45->1910", + "default.handlebars->45->2116", + "default.handlebars->45->2127", + "default.handlebars->45->2129", + "default.handlebars->45->2134", + "default.handlebars->45->2876" ] }, { @@ -33854,7 +33974,7 @@ "ru": "Код приглашения", "tr": "Davet kodu", "xloc": [ - "default.handlebars->41->2355" + "default.handlebars->45->2370" ] }, { @@ -33879,7 +33999,7 @@ "zh-chs": "通过共享邀请连结来邀请某人安装网格代理。该连结为用户提供“ {0} ”设备组的安装说明。该连结是公用的,不需要这服务器的帐户。", "zh-cht": "通過共享邀請鏈結來邀請某人安裝mesh agent。該鏈結將用戶指向“ {0} ”裝置群的安裝說明。該鏈結是公用的,不需要這伺服器的帳戶。", "xloc": [ - "default.handlebars->41->513" + "default.handlebars->45->516" ] }, { @@ -33904,8 +34024,8 @@ "zh-chs": "邀请某人在该设备组上安装网格代理。", "zh-cht": "邀請某人在該裝置群上安裝mesh agent。", "xloc": [ - "default.handlebars->41->1912", - "default.handlebars->41->441" + "default.handlebars->45->1927", + "default.handlebars->45->444" ] }, { @@ -33930,7 +34050,7 @@ "zh-chs": "邀请某人安装网状代理。将发送一封电邮,其中包含指向“ {0} ”设备组的网状代理安装的连结。", "zh-cht": "邀請某人安裝mesh agent。將發送一封電郵,其中包含指向“ {0} ”裝置群的mesh agent安裝的鏈結。", "xloc": [ - "default.handlebars->41->489" + "default.handlebars->45->492" ] }, { @@ -33955,7 +34075,7 @@ "zh-chs": "爱尔兰文", "zh-cht": "愛爾蘭文", "xloc": [ - "default.handlebars->41->1630" + "default.handlebars->45->1645" ] }, { @@ -33963,8 +34083,9 @@ "nl": "Is een relay voor \\\"{0}\\\".", "pl": "Jest bramką dla \\\"{0}\\\".", "ru": "Установлен ретранслятором для \\\"{0}\\\".", + "fr": "Est un relais de \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->2349" + "default.handlebars->45->2364" ] }, { @@ -33989,7 +34110,7 @@ "zh-chs": "意大利文(标准)", "zh-cht": "意大利文(標準)", "xloc": [ - "default.handlebars->41->1631" + "default.handlebars->45->1646" ] }, { @@ -34014,7 +34135,7 @@ "zh-chs": "意大利文(瑞士)", "zh-cht": "義大利文(瑞士)", "xloc": [ - "default.handlebars->41->1632" + "default.handlebars->45->1647" ] }, { @@ -34060,7 +34181,7 @@ "zh-chs": "JSON", "zh-cht": "JSON", "xloc": [ - "default.handlebars->41->2372" + "default.handlebars->45->2387" ] }, { @@ -34085,9 +34206,9 @@ "zh-chs": "JSON格式", "zh-cht": "JSON格式", "xloc": [ - "default.handlebars->41->2377", - "default.handlebars->41->2445", - "default.handlebars->41->703" + "default.handlebars->45->2392", + "default.handlebars->45->2460", + "default.handlebars->45->707" ] }, { @@ -34112,7 +34233,7 @@ "zh-chs": "日文", "zh-cht": "日文", "xloc": [ - "default.handlebars->41->1633" + "default.handlebars->45->1648" ] }, { @@ -34137,7 +34258,7 @@ "zh-chs": "已加入桌面Multiplex会话", "zh-cht": "已加入桌面Multiplex會話", "xloc": [ - "default.handlebars->41->2200" + "default.handlebars->45->2215" ] }, { @@ -34148,7 +34269,7 @@ "pt-br": "Entrou na sessão \\\"{0}\\\" multiplex de área de trabalho", "ru": "Присоединился к сеансу мультиплексированного рабочего стола \\\"{0}\\\"", "xloc": [ - "default.handlebars->41->2339" + "default.handlebars->45->2354" ] }, { @@ -34173,7 +34294,7 @@ "zh-chs": "卡纳达文", "zh-cht": "卡納達文", "xloc": [ - "default.handlebars->41->1634" + "default.handlebars->45->1649" ] }, { @@ -34198,7 +34319,7 @@ "zh-chs": "克什米尔文", "zh-cht": "克什米爾文", "xloc": [ - "default.handlebars->41->1635" + "default.handlebars->45->1650" ] }, { @@ -34223,7 +34344,7 @@ "zh-chs": "哈萨克文", "zh-cht": "哈薩克文", "xloc": [ - "default.handlebars->41->1636" + "default.handlebars->45->1651" ] }, { @@ -34248,7 +34369,7 @@ "zh-chs": "保留现有密码", "zh-cht": "保留現有密碼", "xloc": [ - "default.handlebars->41->1961" + "default.handlebars->45->1976" ] }, { @@ -34273,7 +34394,7 @@ "zh-chs": "内核驱动器", "zh-cht": "內核驅動器", "xloc": [ - "default.handlebars->41->1287" + "default.handlebars->45->1302" ] }, { @@ -34298,7 +34419,7 @@ "zh-chs": "密钥文件", "xloc": [ "default-mobile.handlebars->11->457", - "default.handlebars->41->1317", + "default.handlebars->45->1332", "ssh.handlebars->3->15" ] }, @@ -34324,8 +34445,8 @@ "zh-chs": "键名", "zh-cht": "鍵名", "xloc": [ - "default.handlebars->41->1527", - "default.handlebars->41->1530" + "default.handlebars->45->1542", + "default.handlebars->45->1545" ] }, { @@ -34350,7 +34471,7 @@ "zh-chs": "密钥密码", "xloc": [ "default-mobile.handlebars->11->459", - "default.handlebars->41->1319", + "default.handlebars->45->1334", "ssh.handlebars->3->17" ] }, @@ -34376,7 +34497,7 @@ "zh-chs": "密钥文件必须是 OpenSSH 格式。", "xloc": [ "default-mobile.handlebars->11->458", - "default.handlebars->41->1318", + "default.handlebars->45->1333", "ssh.handlebars->3->16" ] }, @@ -34424,7 +34545,7 @@ "zh-chs": "键盘快捷键自定义", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p10->p10dialog->1->1", - "default.handlebars->41->1261" + "default.handlebars->45->1276" ] }, { @@ -34444,7 +34565,7 @@ "ru": "Настройка клавиатурных строк", "tr": "Klavye Dizileri Özelleştirme", "xloc": [ - "default.handlebars->41->1266" + "default.handlebars->45->1281" ] }, { @@ -34491,7 +34612,7 @@ "zh-chs": "高棉文", "zh-cht": "高棉文", "xloc": [ - "default.handlebars->41->1637" + "default.handlebars->45->1652" ] }, { @@ -34516,7 +34637,7 @@ "zh-chs": "杀死进程{0}", "zh-cht": "殺死進程{0}", "xloc": [ - "default.handlebars->41->2215" + "default.handlebars->45->2230" ] }, { @@ -34541,7 +34662,7 @@ "zh-chs": "吉尔吉斯", "zh-cht": "吉爾吉斯", "xloc": [ - "default.handlebars->41->1638" + "default.handlebars->45->1653" ] }, { @@ -34566,7 +34687,7 @@ "zh-chs": "克林贡", "zh-cht": "克林貢", "xloc": [ - "default.handlebars->41->1639" + "default.handlebars->45->1654" ] }, { @@ -34591,8 +34712,8 @@ "zh-chs": "已知的", "zh-cht": "已知的", "xloc": [ - "default-mobile.handlebars->11->577", - "default.handlebars->41->1459" + "default-mobile.handlebars->11->576", + "default.handlebars->45->1473" ] }, { @@ -34617,7 +34738,7 @@ "zh-chs": "韩文", "zh-cht": "韓文", "xloc": [ - "default.handlebars->41->1640" + "default.handlebars->45->1655" ] }, { @@ -34642,7 +34763,7 @@ "zh-chs": "韩文(朝鲜)", "zh-cht": "韓文(朝鮮)", "xloc": [ - "default.handlebars->41->1641" + "default.handlebars->45->1656" ] }, { @@ -34667,7 +34788,7 @@ "zh-chs": "韩文(韩国)", "zh-cht": "韓文(韓國)", "xloc": [ - "default.handlebars->41->1642" + "default.handlebars->45->1657" ] }, { @@ -34692,8 +34813,8 @@ "zh-chs": "如果", "zh-cht": "如果", "xloc": [ - "default.handlebars->41->1304", - "default.handlebars->41->1335", + "default.handlebars->45->1319", + "default.handlebars->45->1350", "sharing.handlebars->11->26", "sharing.handlebars->11->40" ] @@ -34720,7 +34841,7 @@ "zh-chs": "语言", "zh-cht": "語言", "xloc": [ - "default.handlebars->41->1737" + "default.handlebars->45->1752" ] }, { @@ -34791,7 +34912,7 @@ "zh-chs": "大焦点", "zh-cht": "大焦點", "xloc": [ - "default.handlebars->41->1235" + "default.handlebars->45->1250" ] }, { @@ -34949,7 +35070,7 @@ "zh-chs": "过去30天", "zh-cht": "過去30天", "xloc": [ - "default.handlebars->41->2788", + "default.handlebars->45->2803", "default.handlebars->container->column_l->p40->3->1->p40time->9" ] }, @@ -35025,7 +35146,7 @@ "ru": "Последние 7 дней", "tr": "Son 7 gün", "xloc": [ - "default.handlebars->41->2787" + "default.handlebars->45->2802" ] }, { @@ -35075,7 +35196,7 @@ "zh-chs": "最后访问", "zh-cht": "最後訪問", "xloc": [ - "default.handlebars->41->2385" + "default.handlebars->45->2400" ] }, { @@ -35095,7 +35216,7 @@ "ru": "Последний день", "tr": "Son gun", "xloc": [ - "default.handlebars->41->2786" + "default.handlebars->45->2801" ] }, { @@ -35120,7 +35241,7 @@ "zh-chs": "上次登录", "zh-cht": "上次登入", "xloc": [ - "default.handlebars->41->2615" + "default.handlebars->45->2630" ] }, { @@ -35144,8 +35265,8 @@ "tr": "Son görülen", "zh-chs": "最后一次露面", "xloc": [ - "default.handlebars->41->328", - "default.handlebars->41->353", + "default.handlebars->45->329", + "default.handlebars->45->354", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSort->sortselect->11" ] }, @@ -35166,7 +35287,7 @@ "ru": "Последний доступ: {0}", "tr": "Son erişim: {0}", "xloc": [ - "default.handlebars->41->2395" + "default.handlebars->45->2410" ] }, { @@ -35194,12 +35315,12 @@ "default-mobile.handlebars->11->538", "default-mobile.handlebars->11->539", "default-mobile.handlebars->11->540", - "default.handlebars->41->140", - "default.handlebars->41->1410", - "default.handlebars->41->1411", - "default.handlebars->41->1412", - "default.handlebars->41->142", - "default.handlebars->41->144" + "default.handlebars->45->141", + "default.handlebars->45->1425", + "default.handlebars->45->1426", + "default.handlebars->45->1427", + "default.handlebars->45->143", + "default.handlebars->45->145" ] }, { @@ -35226,9 +35347,9 @@ "xloc": [ "default-mobile.handlebars->11->535", "default-mobile.handlebars->11->537", - "default.handlebars->41->139", - "default.handlebars->41->1407", - "default.handlebars->41->1409" + "default.handlebars->45->140", + "default.handlebars->45->1422", + "default.handlebars->45->1424" ] }, { @@ -35253,7 +35374,7 @@ "zh-chs": "上次更改:{0}", "zh-cht": "上次更改:{0}", "xloc": [ - "default.handlebars->41->2619" + "default.handlebars->45->2634" ] }, { @@ -35303,7 +35424,7 @@ "zh-chs": "最后接口更新", "zh-cht": "最後介面更新", "xloc": [ - "default.handlebars->41->146" + "default.handlebars->45->147" ] }, { @@ -35328,7 +35449,7 @@ "zh-chs": "上次登录:{0}", "zh-cht": "上次登入:{0}", "xloc": [ - "default.handlebars->41->2396" + "default.handlebars->45->2411" ] }, { @@ -35353,8 +35474,8 @@ "zh-chs": "最后一次发现:", "zh-cht": "最後一次發現:", "xloc": [ - "default.handlebars->41->109", - "default.handlebars->41->952" + "default.handlebars->45->110", + "default.handlebars->45->962" ] }, { @@ -35450,7 +35571,7 @@ "zh-chs": "最新版本", "zh-cht": "最新版本", "xloc": [ - "default.handlebars->41->185" + "default.handlebars->45->186" ] }, { @@ -35475,7 +35596,7 @@ "zh-chs": "拉丁文", "zh-cht": "拉丁文", "xloc": [ - "default.handlebars->41->1643" + "default.handlebars->45->1658" ] }, { @@ -35500,7 +35621,7 @@ "zh-chs": "拉脱维亚文", "zh-cht": "拉脫維亞文", "xloc": [ - "default.handlebars->41->1644" + "default.handlebars->45->1659" ] }, { @@ -35525,7 +35646,7 @@ "zh-chs": "启动MeshCentral路由器", "zh-cht": "啟動MeshCentral路由器", "xloc": [ - "default.handlebars->41->1159" + "default.handlebars->45->1174" ] }, { @@ -35572,7 +35693,7 @@ "zh-chs": "启动基于Web的RDP连接到此设备", "zh-cht": "啟動基於Web的RDP連接到此裝置", "xloc": [ - "default.handlebars->41->932" + "default.handlebars->45->942" ] }, { @@ -35596,7 +35717,7 @@ "tr": "Bu cihaza web tabanlı SSH oturumu başlat", "zh-chs": "启动与此设备的基于 Web 的 SSH 会话", "xloc": [ - "default.handlebars->41->934" + "default.handlebars->45->944" ] }, { @@ -35620,7 +35741,7 @@ "tr": "Bu cihaza web tabanlı VNC oturumu başlat", "zh-chs": "启动与此设备的基于 Web 的 VNC 会话", "xloc": [ - "default.handlebars->41->930" + "default.handlebars->45->940" ] }, { @@ -35645,7 +35766,7 @@ "zh-chs": "如没有请留空。", "zh-cht": "如沒有請留空。", "xloc": [ - "default.handlebars->41->2665" + "default.handlebars->45->2680" ] }, { @@ -35670,7 +35791,7 @@ "zh-chs": "剩下", "xloc": [ "default-mobile.handlebars->11->425", - "default.handlebars->41->1247" + "default.handlebars->45->1262" ] }, { @@ -35681,7 +35802,7 @@ "pt-br": "Deixar a sessão WEB-RDP \\\"{1}\\\" depois de {0} segundo(s)", "ru": "Завершен сеанс Web-RDP \\\"{1}\\\", {0} с.", "xloc": [ - "default.handlebars->41->2321" + "default.handlebars->45->2336" ] }, { @@ -35709,7 +35830,7 @@ "pt-br": "Deixar a sessão WEB-SFTP \\\"{1}\\\" depois de {0} segundo(s)", "ru": "Завершен сеанс Web-SFTP \\\"{1}\\\", {0} с.", "xloc": [ - "default.handlebars->41->2320" + "default.handlebars->45->2335" ] }, { @@ -35737,7 +35858,7 @@ "pt-br": "Deixar a sessão WEB-SSH \\\"{1}\\\" depois de {0} segundo(s)", "ru": "Завершен сеанс Web-SSH \\\"{1}\\\", {0} с.", "xloc": [ - "default.handlebars->41->2319" + "default.handlebars->45->2334" ] }, { @@ -35774,7 +35895,7 @@ "ru": "Завершен сеанс Web-VNC, {0} с.", "tr": "{0} saniye sonra Web-VNC oturumundan ayrıldı.", "xloc": [ - "default.handlebars->41->2322" + "default.handlebars->45->2337" ] }, { @@ -35829,7 +35950,7 @@ "zh-chs": "离开桌面多路复用会话", "zh-cht": "離開桌面多路復用會話", "xloc": [ - "default.handlebars->41->2201" + "default.handlebars->45->2216" ] }, { @@ -35840,7 +35961,7 @@ "pt-br": "Deixar a sessão \\\"{0}\\\" de área de trabalho multiplex depois de {1} segundo(s)", "ru": "Покинул сеанс мультиплексного режима рабочего стола \\\"{0}\\\" через {1} с.", "xloc": [ - "default.handlebars->41->2340" + "default.handlebars->45->2355" ] }, { @@ -35860,7 +35981,7 @@ "ru": "Покинул сеанс мультиплексного режима рабочего стола через {0} с.", "tr": "{0} saniye sonra masaüstü multipleks oturumundan ayrıldı.", "xloc": [ - "default.handlebars->41->2318" + "default.handlebars->45->2333" ] }, { @@ -35880,7 +36001,7 @@ "ru": "Продолжительность", "tr": "Uzunluk", "xloc": [ - "default.handlebars->41->2801" + "default.handlebars->45->2816" ] }, { @@ -35927,7 +36048,7 @@ "zh-chs": "灯光模式", "xloc": [ "default-mobile.handlebars->11->91", - "default.handlebars->41->63" + "default.handlebars->45->63" ] }, { @@ -35952,8 +36073,8 @@ "zh-chs": "限制事件", "zh-cht": "限制事件", "xloc": [ - "default.handlebars->41->1006", - "default.handlebars->41->1028" + "default.handlebars->45->1020", + "default.handlebars->45->1042" ] }, { @@ -36005,9 +36126,9 @@ "zh-cht": "有限輸入", "xloc": [ "default-mobile.handlebars->11->690", - "default.handlebars->41->1020", - "default.handlebars->41->2081", - "default.handlebars->41->998" + "default.handlebars->45->1012", + "default.handlebars->45->1034", + "default.handlebars->45->2096" ] }, { @@ -36033,7 +36154,7 @@ "zh-cht": "僅有限輸入", "xloc": [ "default-mobile.handlebars->11->663", - "default.handlebars->41->2035" + "default.handlebars->45->2050" ] }, { @@ -36084,8 +36205,8 @@ "zh-chs": "连结过期", "zh-cht": "鏈結過期", "xloc": [ - "default.handlebars->41->500", - "default.handlebars->41->514" + "default.handlebars->45->503", + "default.handlebars->45->517" ] }, { @@ -36110,7 +36231,7 @@ "zh-chs": "连结邀请", "zh-cht": "鏈結邀請", "xloc": [ - "default.handlebars->41->487" + "default.handlebars->45->490" ] }, { @@ -36134,7 +36255,7 @@ "tr": "Bağlantılar", "zh-chs": "链接", "xloc": [ - "default.handlebars->41->349" + "default.handlebars->45->350" ] }, { @@ -36162,8 +36283,8 @@ "agentinvite.handlebars->container->column_l->5->1->tlinuxtab", "agentinvite.handlebars->container->column_l->5->linuxtab->1", "default-mobile.handlebars->11->285", - "default.handlebars->41->56", - "default.handlebars->41->796" + "default.handlebars->45->56", + "default.handlebars->45->804" ] }, { @@ -36187,7 +36308,7 @@ "tr": "Linux (SSH/SCP/VNC)", "zh-chs": "Linux (SSH/SCP/VNC)", "xloc": [ - "default.handlebars->41->451" + "default.handlebars->45->454" ] }, { @@ -36212,7 +36333,7 @@ "zh-chs": "Linux / BSD", "zh-cht": "Linux / BSD", "xloc": [ - "default.handlebars->41->534" + "default.handlebars->45->537" ] }, { @@ -36237,7 +36358,7 @@ "zh-chs": "Linux / BSD(卸载)", "zh-cht": "Linux / BSD(解除安裝)", "xloc": [ - "default.handlebars->41->540" + "default.handlebars->45->543" ] }, { @@ -36262,7 +36383,7 @@ "zh-chs": "Linux / BSD / macOS二进制安装程序", "zh-cht": "Linux / BSD / macOS二進制安裝軟體", "xloc": [ - "default.handlebars->41->535" + "default.handlebars->45->538" ] }, { @@ -36288,7 +36409,7 @@ "zh-cht": "Linux 32位", "xloc": [ "default-mobile.handlebars->11->11", - "default.handlebars->41->18" + "default.handlebars->45->18" ] }, { @@ -36314,7 +36435,7 @@ "zh-cht": "Linux 64位", "xloc": [ "default-mobile.handlebars->11->12", - "default.handlebars->41->19" + "default.handlebars->45->19" ] }, { @@ -36340,7 +36461,7 @@ "zh-cht": "Linux ARM", "xloc": [ "default-mobile.handlebars->11->16", - "default.handlebars->41->23" + "default.handlebars->45->23" ] }, { @@ -36366,7 +36487,7 @@ "zh-cht": "Linux ARM 64 bit (glibc/2.24 NOKVM)", "xloc": [ "default-mobile.handlebars->11->38", - "default.handlebars->41->45" + "default.handlebars->45->45" ] }, { @@ -36391,7 +36512,7 @@ "zh-chs": "Linux ARM,Raspberry Pi(32位)", "zh-cht": "Linux ARM,Raspberry Pi(32位)", "xloc": [ - "default.handlebars->41->1167" + "default.handlebars->45->1182" ] }, { @@ -36416,7 +36537,7 @@ "zh-chs": "Linux ARM, Raspberry Pi (64位)", "zh-cht": "Linux ARM, Raspberry Pi (64位)", "xloc": [ - "default.handlebars->41->1168" + "default.handlebars->45->1183" ] }, { @@ -36427,8 +36548,8 @@ "pt-br": "MeshAgent Linux", "ru": "MeshAgent для Linux", "xloc": [ - "default.handlebars->41->2105", - "default.handlebars->41->524" + "default.handlebars->45->2120", + "default.handlebars->45->527" ] }, { @@ -36454,7 +36575,7 @@ "zh-cht": "Linux NoKVM x86-32位", "xloc": [ "default-mobile.handlebars->11->25", - "default.handlebars->41->32" + "default.handlebars->45->32" ] }, { @@ -36480,7 +36601,7 @@ "zh-cht": "Linux NoKVM x86-64位", "xloc": [ "default-mobile.handlebars->11->26", - "default.handlebars->41->33" + "default.handlebars->45->33" ] }, { @@ -36505,7 +36626,7 @@ "zh-chs": "Linux路径", "zh-cht": "Linux路徑", "xloc": [ - "default.handlebars->41->690" + "default.handlebars->45->693" ] }, { @@ -36531,7 +36652,7 @@ "zh-cht": "Linux Poky x86-32位", "xloc": [ "default-mobile.handlebars->11->21", - "default.handlebars->41->28" + "default.handlebars->45->28" ] }, { @@ -36557,7 +36678,7 @@ "zh-cht": "Linux Poky x86-64位", "xloc": [ "default-mobile.handlebars->11->24", - "default.handlebars->41->31" + "default.handlebars->45->31" ] }, { @@ -36582,7 +36703,7 @@ "zh-chs": "只限Linux", "zh-cht": "只限Linux", "xloc": [ - "default.handlebars->41->498" + "default.handlebars->45->501" ] }, { @@ -36607,7 +36728,7 @@ "zh-chs": "Linux x86(32位)", "zh-cht": "Linux x86(32位)", "xloc": [ - "default.handlebars->41->1164" + "default.handlebars->45->1179" ] }, { @@ -36632,7 +36753,7 @@ "zh-chs": "Linux x86(64位)", "zh-cht": "Linux x86(64位)", "xloc": [ - "default.handlebars->41->1163" + "default.handlebars->45->1178" ] }, { @@ -36657,8 +36778,8 @@ "zh-chs": "Linux / BSD / macOS命令外壳", "zh-cht": "Linux / BSD / macOS命令外殼", "xloc": [ - "default.handlebars->41->1112", - "default.handlebars->41->670" + "default.handlebars->45->1127", + "default.handlebars->45->673" ] }, { @@ -36752,7 +36873,7 @@ "zh-chs": "立陶宛文", "zh-cht": "立陶宛文", "xloc": [ - "default.handlebars->41->1645" + "default.handlebars->45->1660" ] }, { @@ -36804,13 +36925,13 @@ "xloc": [ "default-mobile.handlebars->11->103", "default-mobile.handlebars->11->88", - "default.handlebars->41->1154", - "default.handlebars->41->1504", - "default.handlebars->41->1516", - "default.handlebars->41->1842", - "default.handlebars->41->1846", - "default.handlebars->41->2688", - "default.handlebars->41->2737" + "default.handlebars->45->1169", + "default.handlebars->45->1519", + "default.handlebars->45->1531", + "default.handlebars->45->1857", + "default.handlebars->45->1861", + "default.handlebars->45->2703", + "default.handlebars->45->2752" ] }, { @@ -36835,7 +36956,7 @@ "zh-chs": "本地", "zh-cht": "本地", "xloc": [ - "default.handlebars->41->388", + "default.handlebars->45->389", "messenger.handlebars->localVideo->1", "messenger.handlebars->remoteImage->3->4" ] @@ -36890,7 +37011,7 @@ { "cs": "Místní přístav", "da": "Lokal Port", - "de": "Lokaler Hafen", + "de": "Lokaler Port", "en": "Local Port", "es": "Puerto Local", "fi": "Paikallinen satama", @@ -36930,8 +37051,8 @@ "zh-chs": "本地设备,无代理", "xloc": [ "default-mobile.handlebars->11->623", - "default.handlebars->41->1793", - "default.handlebars->41->1853" + "default.handlebars->45->1808", + "default.handlebars->45->1868" ] }, { @@ -36964,8 +37085,9 @@ "nl": "Lokale netwerkverbinding via een relay-agent.", "pl": "Lokalne połączenie sieciowe za pośrednictwem przekierowania agenta.", "ru": "Подключение к локальной сети через агент ретрансляции.", + "fr": "Connexion au réseau local au travers d'un agent relais", "xloc": [ - "default.handlebars->41->385" + "default.handlebars->45->386" ] }, { @@ -36973,8 +37095,9 @@ "nl": "Lokale netwerkverbinding.", "pl": "Lokalne połączenie sieciowe.", "ru": "Локальное сетевое подключение.", + "fr": "Connexion au réseau local.", "xloc": [ - "default.handlebars->41->387" + "default.handlebars->45->388" ] }, { @@ -36999,7 +37122,7 @@ "zh-chs": "本地用户接受的远程终端请求", "zh-cht": "本地用戶接受的遠程終端請求", "xloc": [ - "default.handlebars->41->2223" + "default.handlebars->45->2238" ] }, { @@ -37024,7 +37147,7 @@ "zh-chs": "本地用户拒绝了远程终端请求", "zh-cht": "本地用戶拒絕了遠程終端請求", "xloc": [ - "default.handlebars->41->2224" + "default.handlebars->45->2239" ] }, { @@ -37049,7 +37172,7 @@ "zh-chs": "本地化设置", "zh-cht": "本地化設置", "xloc": [ - "default.handlebars->41->1740", + "default.handlebars->45->1755", "default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->7" ] }, @@ -37075,7 +37198,7 @@ "zh-chs": "位置", "zh-cht": "位置", "xloc": [ - "default.handlebars->41->918" + "default.handlebars->45->926" ] }, { @@ -37125,7 +37248,7 @@ "zh-chs": "锁定账户", "zh-cht": "鎖定賬戶", "xloc": [ - "default.handlebars->41->2485" + "default.handlebars->45->2500" ] }, { @@ -37150,7 +37273,7 @@ "zh-chs": "锁定帐户设置", "zh-cht": "鎖定帳戶設置", "xloc": [ - "default.handlebars->41->2489" + "default.handlebars->45->2504" ] }, { @@ -37174,7 +37297,7 @@ "tr": "Masaüstünü Kilitle", "zh-chs": "锁定桌面", "xloc": [ - "default.handlebars->41->1045" + "default.handlebars->45->1060" ] }, { @@ -37199,7 +37322,7 @@ "zh-chs": "锁定账户", "zh-cht": "鎖定賬戶", "xloc": [ - "default.handlebars->41->2416" + "default.handlebars->45->2431" ] }, { @@ -37244,7 +37367,7 @@ "tr": "Uzak kullanıcının faresi ve klavyesi kilitlensin mi?", "zh-chs": "锁定远程用户的鼠标和键盘?", "xloc": [ - "default.handlebars->41->1042" + "default.handlebars->45->1057" ] }, { @@ -37292,7 +37415,7 @@ "tr": "Kullanıcı masaüstü kilitlensin mi?", "zh-chs": "锁定用户桌面?", "xloc": [ - "default.handlebars->41->1046" + "default.handlebars->45->1061" ] }, { @@ -37317,7 +37440,7 @@ "zh-chs": "已锁定", "zh-cht": "已鎖定", "xloc": [ - "default.handlebars->41->2397" + "default.handlebars->45->2412" ] }, { @@ -37343,10 +37466,10 @@ "zh-cht": "被鎖定賬戶", "xloc": [ "default-mobile.handlebars->11->84", - "default.handlebars->41->2578", - "default.handlebars->41->2829", - "default.handlebars->41->2849", - "default.handlebars->41->308" + "default.handlebars->45->2593", + "default.handlebars->45->2844", + "default.handlebars->45->2864", + "default.handlebars->45->309" ] }, { @@ -37371,7 +37494,7 @@ "zh-chs": "将远程用户锁定在桌面之外", "zh-cht": "將遠程用戶鎖定在桌面之外", "xloc": [ - "default.handlebars->41->2249" + "default.handlebars->45->2264" ] }, { @@ -37396,7 +37519,7 @@ "zh-chs": "记录事件", "zh-cht": "記錄事件", "xloc": [ - "default.handlebars->41->897" + "default.handlebars->45->905" ] }, { @@ -37524,7 +37647,7 @@ "tr": "Oturum açmış kullanıcılar", "zh-chs": "已登录用户", "xloc": [ - "default.handlebars->41->325" + "default.handlebars->45->326" ] }, { @@ -37587,8 +37710,9 @@ "pl": "Token Logowania", "pt-br": "Token de Login", "ru": "Токен входа", + "fr": "Jeton de connexion", "xloc": [ - "default.handlebars->41->2839" + "default.handlebars->45->2854" ] }, { @@ -37649,9 +37773,10 @@ "nl": "Inlogtoken in gebruik", "pl": "Używany token logowania", "ru": "Токен входа используется", + "fr": "Jeton de connexion utilisé", "xloc": [ "default-mobile.handlebars->11->62", - "default.handlebars->41->196" + "default.handlebars->45->197" ] }, { @@ -37705,7 +37830,7 @@ "zh-cht": "登出", "xloc": [ "default-mobile.handlebars->topMenu->logoutMenuOption->0->0", - "default.handlebars->41->59", + "default.handlebars->45->59", "terms.handlebars->3->2" ] }, @@ -37731,7 +37856,7 @@ "zh-chs": "卢森堡文", "zh-cht": "盧森堡文", "xloc": [ - "default.handlebars->41->1646" + "default.handlebars->45->1661" ] }, { @@ -37758,10 +37883,10 @@ "xloc": [ "default-mobile.handlebars->11->550", "default-mobile.handlebars->11->552", - "default.handlebars->41->1422", - "default.handlebars->41->1424", - "default.handlebars->41->1432", - "default.handlebars->41->1434" + "default.handlebars->45->1437", + "default.handlebars->45->1439", + "default.handlebars->45->1447", + "default.handlebars->45->1449" ] }, { @@ -37786,8 +37911,8 @@ "zh-chs": "MAC地址", "zh-cht": "MAC地址", "xloc": [ - "default.handlebars->41->151", - "default.handlebars->41->162" + "default.handlebars->45->152", + "default.handlebars->45->163" ] }, { @@ -37813,8 +37938,8 @@ "zh-cht": "MAC:{0}", "xloc": [ "default-mobile.handlebars->11->553", - "default.handlebars->41->1425", - "default.handlebars->41->1435" + "default.handlebars->45->1440", + "default.handlebars->45->1450" ] }, { @@ -37840,8 +37965,8 @@ "zh-cht": "MAC:{0},網關:{1}", "xloc": [ "default-mobile.handlebars->11->551", - "default.handlebars->41->1423", - "default.handlebars->41->1433" + "default.handlebars->45->1438", + "default.handlebars->45->1448" ] }, { @@ -37867,7 +37992,7 @@ "zh-cht": "MIPS", "xloc": [ "default-mobile.handlebars->11->13", - "default.handlebars->41->20" + "default.handlebars->45->20" ] }, { @@ -37893,7 +38018,7 @@ "zh-cht": "MIPS24KC(OpenWRT)", "xloc": [ "default-mobile.handlebars->11->34", - "default.handlebars->41->41" + "default.handlebars->45->41" ] }, { @@ -37918,7 +38043,7 @@ "zh-chs": "MIPSEL24KC (OpenWRT)", "xloc": [ "default-mobile.handlebars->11->46", - "default.handlebars->41->53" + "default.handlebars->45->53" ] }, { @@ -37970,11 +38095,11 @@ "default-mobile.handlebars->11->606", "default-mobile.handlebars->11->608", "default-mobile.handlebars->container->page_content->column_l->p10->p10console->consoleTable->1->4->1->1->1->0->p15outputselecttd->p15outputselect->p15outputselect2", - "default.handlebars->41->1489", - "default.handlebars->41->1491", - "default.handlebars->41->384", - "default.handlebars->41->636", - "default.handlebars->41->876", + "default.handlebars->45->1504", + "default.handlebars->45->1506", + "default.handlebars->45->385", + "default.handlebars->45->639", + "default.handlebars->45->884", "default.handlebars->container->column_l->p15->consoleTable->1->6->1->1->1->0->p15outputselecttd->p15outputselect->p15outputselect2" ] }, @@ -38000,7 +38125,7 @@ "zh-chs": "MQTT凭证", "zh-cht": "MQTT憑證", "xloc": [ - "default.handlebars->41->297" + "default.handlebars->45->298" ] }, { @@ -38025,7 +38150,7 @@ "zh-chs": "MQTT登录", "zh-cht": "MQTT登入", "xloc": [ - "default.handlebars->41->937" + "default.handlebars->45->947" ] }, { @@ -38051,7 +38176,7 @@ "zh-cht": "MQTT通道已連接", "xloc": [ "default-mobile.handlebars->11->345", - "default.handlebars->41->951" + "default.handlebars->45->961" ] }, { @@ -38076,8 +38201,8 @@ "zh-chs": "MQTT已连接", "zh-cht": "MQTT已連接", "xloc": [ - "default.handlebars->41->246", - "default.handlebars->41->950" + "default.handlebars->45->247", + "default.handlebars->45->960" ] }, { @@ -38102,9 +38227,9 @@ "zh-chs": "与设备的MQTT连接已激活。", "zh-cht": "與裝置的MQTT連接已啟動。", "xloc": [ - "default.handlebars->41->383", - "default.handlebars->41->635", - "default.handlebars->41->875" + "default.handlebars->45->384", + "default.handlebars->45->638", + "default.handlebars->45->883" ] }, { @@ -38129,7 +38254,7 @@ "zh-chs": "MQTT已断开连接", "zh-cht": "MQTT已斷開連接", "xloc": [ - "default.handlebars->41->250" + "default.handlebars->45->251" ] }, { @@ -38270,7 +38395,7 @@ "tr": "MacOS Yükleyici", "zh-chs": "MacOS 安装程序", "xloc": [ - "default.handlebars->41->1157" + "default.handlebars->45->1172" ] }, { @@ -38281,8 +38406,8 @@ "pt-br": "MeshAgent MacOS", "ru": "MeshAgent для MacOS", "xloc": [ - "default.handlebars->41->2106", - "default.handlebars->41->525" + "default.handlebars->45->2121", + "default.handlebars->45->528" ] }, { @@ -38306,7 +38431,7 @@ "tr": "Makine adı", "zh-chs": "机器名称", "xloc": [ - "default.handlebars->41->113" + "default.handlebars->45->114" ] }, { @@ -38331,7 +38456,7 @@ "zh-chs": "主服务器信息", "zh-cht": "主伺服器訊息", "xloc": [ - "default.handlebars->41->2961" + "default.handlebars->45->2976" ] }, { @@ -38356,7 +38481,7 @@ "zh-chs": "马来文", "zh-cht": "馬來文", "xloc": [ - "default.handlebars->41->1648" + "default.handlebars->45->1663" ] }, { @@ -38381,7 +38506,7 @@ "zh-chs": "玛拉雅拉姆文", "zh-cht": "馬拉雅拉姆文", "xloc": [ - "default.handlebars->41->1649" + "default.handlebars->45->1664" ] }, { @@ -38406,7 +38531,7 @@ "zh-chs": "马耳他文", "zh-cht": "馬耳他文", "xloc": [ - "default.handlebars->41->1650" + "default.handlebars->45->1665" ] }, { @@ -38431,7 +38556,7 @@ "zh-chs": "管理帐户图片", "xloc": [ "default-mobile.handlebars->11->89", - "default.handlebars->41->1505" + "default.handlebars->45->1520" ] }, { @@ -38457,7 +38582,7 @@ "zh-cht": "管理備用碼", "xloc": [ "default-mobile.handlebars->11->79", - "default.handlebars->41->220" + "default.handlebars->45->221" ] }, { @@ -38484,8 +38609,8 @@ "xloc": [ "default-mobile.handlebars->11->660", "default-mobile.handlebars->11->680", - "default.handlebars->41->2032", - "default.handlebars->41->2070" + "default.handlebars->45->2047", + "default.handlebars->45->2085" ] }, { @@ -38512,8 +38637,8 @@ "xloc": [ "default-mobile.handlebars->11->659", "default-mobile.handlebars->11->679", - "default.handlebars->41->2031", - "default.handlebars->41->2069" + "default.handlebars->45->2046", + "default.handlebars->45->2084" ] }, { @@ -38538,7 +38663,7 @@ "zh-chs": "管理设备", "zh-cht": "管理裝置", "xloc": [ - "default.handlebars->41->1015" + "default.handlebars->45->1029" ] }, { @@ -38563,7 +38688,7 @@ "zh-chs": "管理录音", "zh-cht": "管理錄音", "xloc": [ - "default.handlebars->41->2483" + "default.handlebars->45->2498" ] }, { @@ -38588,7 +38713,7 @@ "zh-chs": "管理安全密钥", "zh-cht": "管理安全密鑰", "xloc": [ - "default.handlebars->41->228" + "default.handlebars->45->229" ] }, { @@ -38613,7 +38738,7 @@ "zh-chs": "管理用户组", "zh-cht": "管理用戶群", "xloc": [ - "default.handlebars->41->2482" + "default.handlebars->45->2497" ] }, { @@ -38638,8 +38763,8 @@ "zh-chs": "管理用户", "zh-cht": "管理用戶", "xloc": [ - "default.handlebars->41->1014", - "default.handlebars->41->2481" + "default.handlebars->45->1028", + "default.handlebars->45->2496" ] }, { @@ -38819,7 +38944,7 @@ "zh-chs": "使用软件代理进行管理", "zh-cht": "使用軟體代理進行管理", "xloc": [ - "default.handlebars->41->1798" + "default.handlebars->45->1813" ] }, { @@ -38845,7 +38970,7 @@ "zh-cht": "使用軟體代理進行管理", "xloc": [ "default-mobile.handlebars->11->622", - "default.handlebars->41->1852" + "default.handlebars->45->1867" ] }, { @@ -38870,7 +38995,7 @@ "zh-chs": "经理", "zh-cht": "經理", "xloc": [ - "default.handlebars->41->2402" + "default.handlebars->45->2417" ] }, { @@ -38939,7 +39064,7 @@ "zh-chs": "毛利文", "zh-cht": "毛利文", "xloc": [ - "default.handlebars->41->1651" + "default.handlebars->45->1666" ] }, { @@ -39032,7 +39157,14 @@ "zh-chs": "马拉地文", "zh-cht": "馬拉地文", "xloc": [ - "default.handlebars->41->1652" + "default.handlebars->45->1667" + ] + }, + { + "en": "Mask: {0}", + "xloc": [ + "default-mobile.handlebars->11->555", + "default.handlebars->45->1452" ] }, { @@ -39057,7 +39189,7 @@ "zh-chs": "达到连接数量上限", "zh-cht": "達到連接數量上限", "xloc": [ - "default.handlebars->41->2905" + "default.handlebars->45->2920" ] }, { @@ -39068,7 +39200,7 @@ "pt-br": "Máximo de teclas atingido.", "ru": "Достигнуто максимальное количество ключей.", "xloc": [ - "default.handlebars->41->227" + "default.handlebars->45->228" ] }, { @@ -39148,8 +39280,8 @@ "zh-chs": "Megabyte", "zh-cht": "Megabyte", "xloc": [ - "default.handlebars->41->2946", - "default.handlebars->41->2951" + "default.handlebars->45->2961", + "default.handlebars->45->2966" ] }, { @@ -39175,8 +39307,8 @@ "zh-cht": "記憶體", "xloc": [ "default-mobile.handlebars->11->595", - "default.handlebars->41->1477", - "default.handlebars->41->2925", + "default.handlebars->45->1492", + "default.handlebars->45->2940", "default.handlebars->container->column_l->p40->3->1->p40type->3" ] }, @@ -39206,16 +39338,16 @@ "default-mobile.handlebars->11->342", "default-mobile.handlebars->11->534", "default-mobile.handlebars->11->542", - "default.handlebars->41->1406", - "default.handlebars->41->1414", - "default.handlebars->41->554", - "default.handlebars->41->558", - "default.handlebars->41->569", - "default.handlebars->41->582", - "default.handlebars->41->585", - "default.handlebars->41->591", - "default.handlebars->41->800", - "default.handlebars->41->868" + "default.handlebars->45->1421", + "default.handlebars->45->1429", + "default.handlebars->45->557", + "default.handlebars->45->561", + "default.handlebars->45->572", + "default.handlebars->45->585", + "default.handlebars->45->588", + "default.handlebars->45->594", + "default.handlebars->45->808", + "default.handlebars->45->876" ] }, { @@ -39241,7 +39373,7 @@ "zh-cht": "網格代理控制台", "xloc": [ "default-mobile.handlebars->11->667", - "default.handlebars->41->2041" + "default.handlebars->45->2056" ] }, { @@ -39310,7 +39442,7 @@ "zh-chs": "网格中继", "zh-cht": "Mesh Relay", "xloc": [ - "default.handlebars->41->874" + "default.handlebars->45->882" ] }, { @@ -39335,9 +39467,9 @@ "zh-chs": "已连接网状代理并准备使用。", "zh-cht": "已連接Mesh Agent並準備使用。", "xloc": [ - "default.handlebars->41->375", - "default.handlebars->41->627", - "default.handlebars->41->867" + "default.handlebars->45->376", + "default.handlebars->45->630", + "default.handlebars->45->875" ] }, { @@ -39362,9 +39494,9 @@ "zh-chs": "网格代理可以经过其他代理作为中继访问得到。", "zh-cht": "Mesh Agent可以經過其他代理作為中繼訪問得到。", "xloc": [ - "default.handlebars->41->381", - "default.handlebars->41->633", - "default.handlebars->41->873" + "default.handlebars->45->382", + "default.handlebars->45->636", + "default.handlebars->45->881" ] }, { @@ -39389,8 +39521,8 @@ "zh-chs": "MeshAction(.txt)", "zh-cht": "MeshAction(.txt)", "xloc": [ - "default.handlebars->41->1174", - "default.handlebars->41->1176" + "default.handlebars->45->1189", + "default.handlebars->45->1191" ] }, { @@ -39415,7 +39547,7 @@ "zh-chs": "MeshAgent流量", "zh-cht": "MeshAgent流量", "xloc": [ - "default.handlebars->41->2963" + "default.handlebars->45->2978" ] }, { @@ -39440,7 +39572,7 @@ "zh-chs": "MeshAgent更新", "zh-cht": "MeshAgent更新", "xloc": [ - "default.handlebars->41->2964" + "default.handlebars->45->2979" ] }, { @@ -39462,7 +39594,11 @@ "ru": "MeshCentral", "sv": "MeshCentral", "tr": "MeshCentral", - "zh-chs": "网格中心" + "zh-chs": "网格中心", + "xloc": [ + "default.handlebars->45->1055", + "default.handlebars->45->703" + ] }, { "cs": "MeshCentral Agent pro Android", @@ -39509,10 +39645,10 @@ "tr": "MeshCentral Yardımcısı", "zh-chs": "MeshCentral 助手", "xloc": [ - "default.handlebars->41->2107", - "default.handlebars->41->499", - "default.handlebars->41->526", - "default.handlebars->41->538" + "default.handlebars->45->2122", + "default.handlebars->45->502", + "default.handlebars->45->529", + "default.handlebars->45->541" ] }, { @@ -39536,8 +39672,8 @@ "tr": "Windows için MeshCentral Yardımcısı", "zh-chs": "适用于 Windows 的 MeshCentral 助手", "xloc": [ - "default.handlebars->41->574", - "default.handlebars->41->578" + "default.handlebars->45->577", + "default.handlebars->45->581" ] }, { @@ -39582,7 +39718,7 @@ "tr": "MeshCentral Assistant, kullanıcıların yardım istemek için kullanabilecekleri bir Windows aracıdır. \\\"{0}\\\" cihaz grubuna bağlanacak bir sürümü indirmek için aşağıdaki bağlantıyı kullanın.", "zh-chs": "MeshCentral Assistant 是一个 Windows 工具,用户可以使用它来寻求帮助。使用下面的链接下载将连接到设备组 \\\"{0}\\\" 的版本。", "xloc": [ - "default.handlebars->41->573" + "default.handlebars->45->576" ] }, { @@ -39606,7 +39742,7 @@ "tr": "MeshCentral Assistant, kullanıcıların yardım istemek için kullanabilecekleri bir Windows aracıdır. Arka plan aracısını izleyecek bir sürümü indirmek için aşağıdaki bağlantıyı kullanın.", "zh-chs": "MeshCentral Assistant 是一个 Windows 工具,用户可以使用它来寻求帮助。使用下面的链接下载将监控后台代理的版本。", "xloc": [ - "default.handlebars->41->577" + "default.handlebars->45->580" ] }, { @@ -39656,7 +39792,7 @@ "zh-chs": "MeshCentral错误", "zh-cht": "MeshCentral錯誤", "xloc": [ - "default.handlebars->41->1845" + "default.handlebars->45->1860" ] }, { @@ -39681,7 +39817,7 @@ "zh-chs": "MeshCentral路由器", "zh-cht": "MeshCentral Router", "xloc": [ - "default.handlebars->41->1160" + "default.handlebars->45->1175" ] }, { @@ -39726,7 +39862,7 @@ "tr": "MeshCentral Yönlendirici Bağlantıları", "zh-chs": "MeshCentral 路由器链接", "xloc": [ - "default.handlebars->41->324" + "default.handlebars->45->325" ] }, { @@ -39793,7 +39929,7 @@ "zh-chs": "MeshCentral 路由器是Windows工具,用于TCP端口映射。例如,您可以通过该服务器将RDP放入远程设备。", "zh-cht": "MeshCentral Router是Windows工具,用於TCP介面映射。例如,你可以通過該伺服器將RDP放入遠程裝置。", "xloc": [ - "default.handlebars->41->1155" + "default.handlebars->45->1170" ] }, { @@ -39813,7 +39949,7 @@ "ru": "Для поддержки MeshCentral SSH требуется NodeJS 11 или выше..", "tr": "MeshCentral SSH desteği, NodeJS 11 veya üstünü gerektirir.", "xloc": [ - "default.handlebars->41->83" + "default.handlebars->45->83" ] }, { @@ -39838,8 +39974,8 @@ "zh-chs": "MeshCentral服务器错误", "zh-cht": "MeshCentral伺服器錯誤", "xloc": [ - "default.handlebars->41->189", - "default.handlebars->41->193" + "default.handlebars->45->190", + "default.handlebars->45->194" ] }, { @@ -39864,7 +40000,7 @@ "zh-chs": "MeshCentral服务器同级化", "zh-cht": "MeshCentral伺服器同級化", "xloc": [ - "default.handlebars->41->2962" + "default.handlebars->45->2977" ] }, { @@ -39914,9 +40050,9 @@ "zh-chs": "MeshCentral版本", "zh-cht": "MeshCentral版本", "xloc": [ - "default.handlebars->41->1841", - "default.handlebars->41->186", - "default.handlebars->41->188" + "default.handlebars->45->1856", + "default.handlebars->45->187", + "default.handlebars->45->189" ] }, { @@ -39941,9 +40077,9 @@ "zh-chs": "MeshCmd", "zh-cht": "MeshCmd", "xloc": [ - "default.handlebars->41->1172", - "default.handlebars->41->358", - "default.handlebars->41->920" + "default.handlebars->45->1187", + "default.handlebars->45->359", + "default.handlebars->45->928" ] }, { @@ -39968,7 +40104,7 @@ "zh-chs": "MeshCmd(Linux ARM,32位)", "zh-cht": "MeshCmd(Linux ARM,32位)", "xloc": [ - "default.handlebars->41->1184" + "default.handlebars->45->1199" ] }, { @@ -39993,7 +40129,7 @@ "zh-chs": "MeshCmd(Linux ARM,64位)", "zh-cht": "MeshCmd(Linux ARM,64位)", "xloc": [ - "default.handlebars->41->1185" + "default.handlebars->45->1200" ] }, { @@ -40018,7 +40154,7 @@ "zh-chs": "MeshCmd(Linux x86,32bit)", "zh-cht": "MeshCmd(Linux x86,32bit)", "xloc": [ - "default.handlebars->41->1180" + "default.handlebars->45->1195" ] }, { @@ -40043,7 +40179,7 @@ "zh-chs": "MeshCmd(Linux x86,64位)", "zh-cht": "MeshCmd(Linux x86,64位)", "xloc": [ - "default.handlebars->41->1181" + "default.handlebars->45->1196" ] }, { @@ -40068,7 +40204,7 @@ "zh-chs": "MeshCmd(Win32可执行档案)", "zh-cht": "MeshCmd(Win32可執行檔案)", "xloc": [ - "default.handlebars->41->1178" + "default.handlebars->45->1193" ] }, { @@ -40093,7 +40229,7 @@ "zh-chs": "MeshCmd(Win64可执行档案)", "zh-cht": "MeshCmd(Win64可執行檔案)", "xloc": [ - "default.handlebars->41->1179" + "default.handlebars->45->1194" ] }, { @@ -40140,7 +40276,7 @@ "zh-chs": "MeshCmd(macOS,ARM-64位)", "zh-cht": "MeshCmd(macOS,ARM-64位)", "xloc": [ - "default.handlebars->41->1183" + "default.handlebars->45->1198" ] }, { @@ -40165,7 +40301,7 @@ "zh-chs": "MeshCmd(macOS,x86-ARM-64位)", "zh-cht": "MeshCmd(macOS,x86-ARM-64位)", "xloc": [ - "default.handlebars->41->1182" + "default.handlebars->45->1197" ] }, { @@ -40190,7 +40326,7 @@ "zh-chs": "MeshCmd是一个可以执行许多不同操作的命令行工具。可以选择下载和编辑操作档案以提供服务器信息和凭据。", "zh-cht": "MeshCmd是一個可以執行許多不同操作的命令行工具。可以選擇下載和編輯操作檔案以提供伺服器訊息和憑據。", "xloc": [ - "default.handlebars->41->1169" + "default.handlebars->45->1184" ] }, { @@ -40284,10 +40420,10 @@ "zh-chs": "消息", "zh-cht": "訊息", "xloc": [ - "default.handlebars->41->1135", - "default.handlebars->41->2807", - "default.handlebars->41->511", - "default.handlebars->41->899" + "default.handlebars->45->1150", + "default.handlebars->45->2822", + "default.handlebars->45->514", + "default.handlebars->45->907" ] }, { @@ -40312,7 +40448,7 @@ "zh-chs": "留言框", "zh-cht": "留言框", "xloc": [ - "default.handlebars->41->685" + "default.handlebars->45->688" ] }, { @@ -40337,7 +40473,7 @@ "zh-chs": "消息调度器", "zh-cht": "電郵調度器", "xloc": [ - "default.handlebars->41->2960" + "default.handlebars->45->2975" ] }, { @@ -40411,8 +40547,8 @@ "tr": "haberci", "zh-chs": "信使", "xloc": [ - "default.handlebars->41->2750", - "default.handlebars->41->2816" + "default.handlebars->45->2765", + "default.handlebars->45->2831" ] }, { @@ -40509,7 +40645,7 @@ "ru": "Отсутствует адрес электронной почты Let's Encrypt.", "tr": "Let's Encrypt e-posta adresi eksik.", "xloc": [ - "default.handlebars->41->92" + "default.handlebars->45->92" ] }, { @@ -40529,7 +40665,7 @@ "ru": "Отсутствуют параметры WebDAV.", "tr": "WebDAV parametreleri eksik.", "xloc": [ - "default.handlebars->41->84" + "default.handlebars->45->84" ] }, { @@ -40554,7 +40690,7 @@ "zh-chs": "移动设备", "xloc": [ "default-mobile.handlebars->11->548", - "default.handlebars->41->1420" + "default.handlebars->45->1435" ] }, { @@ -40578,7 +40714,7 @@ "tr": "Mobil cihaz", "zh-chs": "移动设备", "xloc": [ - "default.handlebars->41->537" + "default.handlebars->45->540" ] }, { @@ -40605,9 +40741,9 @@ "xloc": [ "default-mobile.handlebars->11->543", "default-mobile.handlebars->11->596", - "default.handlebars->41->1415", - "default.handlebars->41->1478", - "default.handlebars->41->1802" + "default.handlebars->45->1430", + "default.handlebars->45->1493", + "default.handlebars->45->1817" ] }, { @@ -40632,7 +40768,7 @@ "zh-chs": "修改节点位置", "zh-cht": "修改節點位置", "xloc": [ - "default.handlebars->41->750" + "default.handlebars->45->758" ] }, { @@ -40657,7 +40793,7 @@ "zh-chs": "摩尔达维亚文", "zh-cht": "摩爾達維亞文", "xloc": [ - "default.handlebars->41->1653" + "default.handlebars->45->1668" ] }, { @@ -40705,7 +40841,7 @@ "zh-cht": "母板", "xloc": [ "default-mobile.handlebars->11->589", - "default.handlebars->41->1471" + "default.handlebars->45->1486" ] }, { @@ -40730,7 +40866,7 @@ "zh-chs": "将此设备移到其他设备组", "zh-cht": "將此裝置移至其他裝置群", "xloc": [ - "default.handlebars->41->911" + "default.handlebars->45->919" ] }, { @@ -40755,7 +40891,7 @@ "zh-chs": "移至设备组", "zh-cht": "移至裝置群", "xloc": [ - "default.handlebars->41->642" + "default.handlebars->45->645" ] }, { @@ -40780,7 +40916,7 @@ "zh-chs": "移动:“{0}”到“{1}”", "zh-cht": "移動:“{0}”到“{1}”", "xloc": [ - "default.handlebars->41->2248" + "default.handlebars->45->2263" ] }, { @@ -40805,7 +40941,7 @@ "zh-chs": "将设备{0}移动到组{1}", "zh-cht": "將設備{0}移動到組{1}", "xloc": [ - "default.handlebars->41->2281" + "default.handlebars->45->2296" ] }, { @@ -40854,8 +40990,8 @@ "tr": "Birden Çok Sorun", "zh-chs": "多个问题", "xloc": [ - "default.handlebars->41->2136", - "default.handlebars->41->2150" + "default.handlebars->45->2151", + "default.handlebars->45->2165" ] }, { @@ -40901,7 +41037,7 @@ "zh-chs": "多路复用器", "zh-cht": "多工器", "xloc": [ - "default.handlebars->41->2768" + "default.handlebars->45->2783" ] }, { @@ -40926,8 +41062,8 @@ "zh-chs": "必须以用户身份运行", "zh-cht": "必須以用戶身份運行", "xloc": [ - "default.handlebars->41->1115", - "default.handlebars->41->673" + "default.handlebars->45->1130", + "default.handlebars->45->676" ] }, { @@ -41110,7 +41246,7 @@ "zh-chs": "我的服务器控制台", "zh-cht": "我的伺服器控制台", "xloc": [ - "default.handlebars->41->1484" + "default.handlebars->45->1499" ] }, { @@ -41312,16 +41448,18 @@ "zh-chs": "我的密钥", "zh-cht": "我的密鍵", "xloc": [ - "default.handlebars->41->1528", - "default.handlebars->41->1531" + "default.handlebars->45->1543", + "default.handlebars->45->1546" ] }, { "en": "NLA not supported", "nl": "NLA niet ondersteund", + "pl": "NLA nie obsługiwane", "ru": "NLA не поддерживается", + "fr": "NLA non supporté", "xloc": [ - "default.handlebars->41->1204" + "default.handlebars->45->1219" ] }, { @@ -41379,6 +41517,7 @@ "nl": "NUM", "pl": "NUM", "ru": "NUM", + "fr": "NUM", "xloc": [ "default.handlebars->container->column_l->p11->7->p11numlock" ] @@ -41405,7 +41544,7 @@ "zh-chs": "导航到下面的URL,授予访问权限并将令牌代码复制回去。", "zh-cht": "導航到下面的URL,授予訪問權限並將令牌代碼複製回去。", "xloc": [ - "default.handlebars->41->300" + "default.handlebars->45->301" ] }, { @@ -41436,25 +41575,25 @@ "default-mobile.handlebars->11->583", "default-mobile.handlebars->11->627", "default-mobile.handlebars->11->650", - "default.handlebars->41->1263", - "default.handlebars->41->1279", - "default.handlebars->41->1398", - "default.handlebars->41->1465", - "default.handlebars->41->147", - "default.handlebars->41->161", - "default.handlebars->41->1792", - "default.handlebars->41->1820", - "default.handlebars->41->1825", - "default.handlebars->41->1857", - "default.handlebars->41->1991", - "default.handlebars->41->2383", - "default.handlebars->41->2492", - "default.handlebars->41->2508", - "default.handlebars->41->2515", - "default.handlebars->41->2565", - "default.handlebars->41->2584", - "default.handlebars->41->313", - "default.handlebars->41->779", + "default.handlebars->45->1278", + "default.handlebars->45->1294", + "default.handlebars->45->1413", + "default.handlebars->45->148", + "default.handlebars->45->1480", + "default.handlebars->45->162", + "default.handlebars->45->1807", + "default.handlebars->45->1835", + "default.handlebars->45->1840", + "default.handlebars->45->1872", + "default.handlebars->45->2006", + "default.handlebars->45->2398", + "default.handlebars->45->2507", + "default.handlebars->45->2523", + "default.handlebars->45->2530", + "default.handlebars->45->2580", + "default.handlebars->45->2599", + "default.handlebars->45->314", + "default.handlebars->45->787", "default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsArea->DeskToolsProcessTab->deskToolsHeader->3", "default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsArea->DeskToolsServiceTab->deskToolsServiceHeader->3", "default.handlebars->container->column_l->p42->p42tbl->1->0->2" @@ -41482,7 +41621,7 @@ "zh-chs": "名称(可选)", "zh-cht": "名稱(可選)", "xloc": [ - "default.handlebars->41->490" + "default.handlebars->45->493" ] }, { @@ -41507,7 +41646,7 @@ "zh-chs": "名称1,名称2,名称3", "zh-cht": "名稱1,名稱2,名稱3", "xloc": [ - "default.handlebars->41->2473" + "default.handlebars->45->2488" ] }, { @@ -41532,7 +41671,7 @@ "zh-chs": "纳瓦霍文", "zh-cht": "納瓦霍文", "xloc": [ - "default.handlebars->41->1654" + "default.handlebars->45->1669" ] }, { @@ -41557,7 +41696,7 @@ "zh-chs": "恩东加", "zh-cht": "恩東加", "xloc": [ - "default.handlebars->41->1655" + "default.handlebars->45->1670" ] }, { @@ -41582,7 +41721,7 @@ "zh-chs": "尼泊尔文", "zh-cht": "尼泊爾文", "xloc": [ - "default.handlebars->41->1656" + "default.handlebars->45->1671" ] }, { @@ -41607,7 +41746,7 @@ "zh-chs": "网络接口", "zh-cht": "網絡介面", "xloc": [ - "default.handlebars->41->1153" + "default.handlebars->45->1168" ] }, { @@ -41654,9 +41793,9 @@ "zh-chs": "网络", "zh-cht": "網路", "xloc": [ - "default-mobile.handlebars->11->562", - "default.handlebars->41->1430", - "default.handlebars->41->1444" + "default-mobile.handlebars->11->561", + "default.handlebars->45->1445", + "default.handlebars->45->1458" ] }, { @@ -41682,7 +41821,7 @@ "zh-cht": "新", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p3->p3info->3->p3createMeshLink1->1", - "default.handlebars->41->1819", + "default.handlebars->45->1834", "default.handlebars->container->column_l->p2->p2info->p2createMeshLink1->1" ] }, @@ -41708,7 +41847,7 @@ "zh-chs": "生成新的2FA备份代码", "zh-cht": "生成新的2FA備份代碼", "xloc": [ - "default.handlebars->41->2288" + "default.handlebars->45->2303" ] }, { @@ -41733,7 +41872,7 @@ "zh-chs": "新账户", "xloc": [ "default-mobile.handlebars->11->708", - "default.handlebars->41->2856" + "default.handlebars->45->2871" ] }, { @@ -41806,9 +41945,9 @@ "zh-cht": "新裝置群", "xloc": [ "default-mobile.handlebars->11->122", - "default.handlebars->41->1145", - "default.handlebars->41->1785", - "default.handlebars->41->1808" + "default.handlebars->45->1160", + "default.handlebars->45->1800", + "default.handlebars->45->1823" ] }, { @@ -41835,8 +41974,8 @@ "xloc": [ "default-mobile.handlebars->11->151", "default-mobile.handlebars->11->480", - "default.handlebars->41->1358", - "default.handlebars->41->2180", + "default.handlebars->45->1373", + "default.handlebars->45->2195", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3", "sharing.handlebars->11->59", @@ -41890,8 +42029,8 @@ "zh-chs": "新密码*", "zh-cht": "新密碼*", "xloc": [ - "default.handlebars->41->471", - "default.handlebars->41->472" + "default.handlebars->45->474", + "default.handlebars->45->475" ] }, { @@ -41961,8 +42100,8 @@ "zh-chs": "新密码*", "zh-cht": "新密碼*", "xloc": [ - "default.handlebars->41->1965", - "default.handlebars->41->1966" + "default.handlebars->45->1980", + "default.handlebars->45->1981" ] }, { @@ -41989,8 +42128,8 @@ "xloc": [ "default-mobile.handlebars->11->117", "default-mobile.handlebars->11->118", - "default.handlebars->41->1780", - "default.handlebars->41->1781" + "default.handlebars->45->1795", + "default.handlebars->45->1796" ] }, { @@ -42036,7 +42175,7 @@ "zh-chs": "夜间模式", "xloc": [ "default-mobile.handlebars->11->93", - "default.handlebars->41->65" + "default.handlebars->45->65" ] }, { @@ -42061,8 +42200,8 @@ "zh-chs": "没有AMT", "zh-cht": "沒有AMT", "xloc": [ - "default.handlebars->41->1019", - "default.handlebars->41->997" + "default.handlebars->45->1011", + "default.handlebars->45->1033" ] }, { @@ -42088,7 +42227,7 @@ "zh-cht": "沒有有效保安編碼", "xloc": [ "default-mobile.handlebars->11->75", - "default.handlebars->41->215" + "default.handlebars->45->216" ] }, { @@ -42134,7 +42273,7 @@ "tr": "Aracı Konsolu Yok", "zh-chs": "无座席控制台", "xloc": [ - "default.handlebars->41->2674" + "default.handlebars->45->2689" ] }, { @@ -42158,7 +42297,7 @@ "tr": "Konsol Yok", "zh-chs": "没有控制台", "xloc": [ - "default.handlebars->41->2605" + "default.handlebars->45->2620" ] }, { @@ -42185,8 +42324,8 @@ "xloc": [ "default-mobile.handlebars->11->301", "default-mobile.handlebars->11->302", - "default.handlebars->41->814", - "default.handlebars->41->815" + "default.handlebars->45->822", + "default.handlebars->45->823" ] }, { @@ -42211,10 +42350,10 @@ "zh-chs": "没有桌面", "zh-cht": "沒有桌面", "xloc": [ - "default.handlebars->41->1021", - "default.handlebars->41->2077", - "default.handlebars->41->2601", - "default.handlebars->41->999" + "default.handlebars->45->1013", + "default.handlebars->45->1035", + "default.handlebars->45->2092", + "default.handlebars->45->2616" ] }, { @@ -42239,8 +42378,8 @@ "zh-chs": "不能访问桌面", "zh-cht": "不能訪問桌面", "xloc": [ - "default.handlebars->41->2037", - "default.handlebars->41->2670" + "default.handlebars->45->2052", + "default.handlebars->45->2685" ] }, { @@ -42286,9 +42425,9 @@ "zh-chs": "找不到事件", "zh-cht": "找不到事件", "xloc": [ - "default.handlebars->41->1396", - "default.handlebars->41->2359", - "default.handlebars->41->2736" + "default.handlebars->45->1411", + "default.handlebars->45->2374", + "default.handlebars->45->2751" ] }, { @@ -42314,8 +42453,8 @@ "zh-cht": "不能存取檔案", "xloc": [ "default-mobile.handlebars->11->665", - "default.handlebars->41->2039", - "default.handlebars->41->2673" + "default.handlebars->45->2054", + "default.handlebars->45->2688" ] }, { @@ -42341,10 +42480,10 @@ "zh-cht": "沒有檔案", "xloc": [ "default-mobile.handlebars->11->688", - "default.handlebars->41->1018", - "default.handlebars->41->2079", - "default.handlebars->41->2604", - "default.handlebars->41->996" + "default.handlebars->45->1010", + "default.handlebars->45->1032", + "default.handlebars->45->2094", + "default.handlebars->45->2619" ] }, { @@ -42369,8 +42508,8 @@ "zh-chs": "无输入", "zh-cht": "無輸入", "xloc": [ - "default.handlebars->41->1016", - "default.handlebars->41->994" + "default.handlebars->45->1008", + "default.handlebars->45->1030" ] }, { @@ -42397,8 +42536,8 @@ "xloc": [ "default-mobile.handlebars->11->666", "default-mobile.handlebars->11->689", - "default.handlebars->41->2040", - "default.handlebars->41->2080" + "default.handlebars->45->2055", + "default.handlebars->45->2095" ] }, { @@ -42422,7 +42561,7 @@ "tr": "Bu cihaz grubunda Intel® AMT cihazı yok", "zh-chs": "此设备组中没有英特尔® AMT 设备", "xloc": [ - "default.handlebars->41->339" + "default.handlebars->45->340" ] }, { @@ -42479,7 +42618,7 @@ "en": "No Keys Configured", "es": "No hay Claves Configuradas", "fi": "Ei avaimia määritetty", - "fr": "Aucun clé configurée", + "fr": "Aucune clé configurée", "hi": "कोई कुंजी कॉन्फ़िगर नहीं है", "it": "Nessuna chiave configurata", "ja": "キーが設定されていません", @@ -42494,7 +42633,7 @@ "zh-chs": "未配置任何键", "zh-cht": "未配置任何鍵", "xloc": [ - "default.handlebars->41->223" + "default.handlebars->45->224" ] }, { @@ -42519,7 +42658,7 @@ "zh-chs": "没有成员", "zh-cht": "沒有成員", "xloc": [ - "default.handlebars->41->2545" + "default.handlebars->45->2560" ] }, { @@ -42531,7 +42670,7 @@ "fi": "Ei uusia laiteryhmiä.", "fr": "Pas de nouveau groupe d'appareils", "hi": "कोई नया उपकरण समूह नहीं", - "it": "Nessun nuovo gruppo di dispositivi ", + "it": "Nessun nuovo gruppo di dispositivi", "ja": "新しいデバイスグループはありません", "ko": "새로운 장치 그룹이 없습니다.", "nl": "Geen nieuwe apparaatgroepen", @@ -42544,7 +42683,7 @@ "zh-chs": "没有新的设备组", "zh-cht": "沒有新的裝置群", "xloc": [ - "default.handlebars->41->2486" + "default.handlebars->45->2501" ] }, { @@ -42564,7 +42703,7 @@ "ru": "Запретить добавление новых устройств", "tr": "Yeni Cihaz Yok", "xloc": [ - "default.handlebars->41->2487" + "default.handlebars->45->2502" ] }, { @@ -42576,7 +42715,7 @@ "fi": "Ei politiikkaa", "fr": "Aucune restriction", "hi": "कोई नीति नहीं", - "it": "Nessuna politica ", + "it": "Nessuna politica", "ja": "ポリシーなし", "ko": "정책이 없습니다.", "nl": "Geen beleid", @@ -42589,8 +42728,8 @@ "zh-chs": "没有政策", "zh-cht": "沒有政策", "xloc": [ - "default.handlebars->41->1896", - "default.handlebars->41->1956" + "default.handlebars->45->1911", + "default.handlebars->45->1971" ] }, { @@ -42631,8 +42770,8 @@ "ru": "Нет доступа к выполнению команд", "tr": "Uzaktan Komut Yok", "xloc": [ - "default.handlebars->41->2607", - "default.handlebars->41->2676" + "default.handlebars->45->2622", + "default.handlebars->45->2691" ] }, { @@ -42652,8 +42791,8 @@ "ru": "Нет доступа к удаленному управлению", "tr": "Uzaktan Kumanda Yok", "xloc": [ - "default.handlebars->41->2600", - "default.handlebars->41->2669" + "default.handlebars->45->2615", + "default.handlebars->45->2684" ] }, { @@ -42673,8 +42812,8 @@ "ru": "Нет доступа к перезагрузке/выключению", "tr": "Sıfırlama/Kapatma Yok", "xloc": [ - "default.handlebars->41->2609", - "default.handlebars->41->2678" + "default.handlebars->45->2624", + "default.handlebars->45->2693" ] }, { @@ -42702,10 +42841,10 @@ "default-mobile.handlebars->11->137", "default-mobile.handlebars->11->641", "default-mobile.handlebars->11->696", - "default.handlebars->41->1011", - "default.handlebars->41->1033", - "default.handlebars->41->1817", - "default.handlebars->41->2089" + "default.handlebars->45->1025", + "default.handlebars->45->1047", + "default.handlebars->45->1832", + "default.handlebars->45->2104" ] }, { @@ -42752,8 +42891,8 @@ "zh-cht": "沒有TLS加密", "xloc": [ "default-mobile.handlebars->11->389", - "default.handlebars->41->1131", - "default.handlebars->41->462" + "default.handlebars->45->1146", + "default.handlebars->45->465" ] }, { @@ -42779,10 +42918,10 @@ "zh-cht": "沒有終端", "xloc": [ "default-mobile.handlebars->11->687", - "default.handlebars->41->1017", - "default.handlebars->41->2078", - "default.handlebars->41->2603", - "default.handlebars->41->995" + "default.handlebars->45->1009", + "default.handlebars->45->1031", + "default.handlebars->45->2093", + "default.handlebars->45->2618" ] }, { @@ -42808,8 +42947,8 @@ "zh-cht": "不能訪問終端", "xloc": [ "default-mobile.handlebars->11->664", - "default.handlebars->41->2038", - "default.handlebars->41->2672" + "default.handlebars->45->2053", + "default.handlebars->45->2687" ] }, { @@ -42834,7 +42973,7 @@ "zh-chs": "没有工具(MeshCmd /路由器)", "zh-cht": "沒有工具(MeshCmd /路由器)", "xloc": [ - "default.handlebars->41->2488" + "default.handlebars->45->2503" ] }, { @@ -42854,8 +42993,8 @@ "ru": "Нет доступа к удалению", "tr": "Kaldırma Yok", "xloc": [ - "default.handlebars->41->2606", - "default.handlebars->41->2675" + "default.handlebars->45->2621", + "default.handlebars->45->2690" ] }, { @@ -42875,8 +43014,8 @@ "ru": "Нет доступа к пробуждению", "tr": "Uyanmak yok", "xloc": [ - "default.handlebars->41->2608", - "default.handlebars->41->2677" + "default.handlebars->45->2623", + "default.handlebars->45->2692" ] }, { @@ -42902,7 +43041,7 @@ "zh-cht": "該設備當前無可用操作。", "xloc": [ "default-mobile.handlebars->11->372", - "default.handlebars->41->1107" + "default.handlebars->45->1122" ] }, { @@ -42931,10 +43070,11 @@ "nl": "Geen apparaten doorgestuurd via agent", "pl": "Brak przekierowanych urządzeń przez agenta", "ru": "Устройства без агента, ретранслируемые через агент", + "fr": "Aucun agent d'appareil relayé au travers de l'agent", "xloc": [ "default-mobile.handlebars->11->624", - "default.handlebars->41->1794", - "default.handlebars->41->1854" + "default.handlebars->45->1809", + "default.handlebars->45->1869" ] }, { @@ -42958,8 +43098,8 @@ "tr": "Otomatik güncelleme yok", "zh-chs": "没有自动更新", "xloc": [ - "default.handlebars->41->2134", - "default.handlebars->41->2148" + "default.handlebars->45->2149", + "default.handlebars->45->2163" ] }, { @@ -42984,8 +43124,8 @@ "zh-chs": "没有共同的设备组", "zh-cht": "沒有共同的裝置群", "xloc": [ - "default.handlebars->41->2551", - "default.handlebars->41->2704" + "default.handlebars->45->2566", + "default.handlebars->45->2719" ] }, { @@ -43063,7 +43203,7 @@ "zh-chs": "没有一个设备被加入任何一组,请单击一个设备的“组”以添加到一个组中。", "zh-cht": "沒有一個裝置被加入任何一群,請單擊一個裝置的“群”以新增到一個群中。", "xloc": [ - "default.handlebars->41->336" + "default.handlebars->45->337" ] }, { @@ -43110,7 +43250,7 @@ "zh-chs": "找不到设备。", "zh-cht": "找不到裝置。", "xloc": [ - "default.handlebars->41->767" + "default.handlebars->45->775" ] }, { @@ -43135,8 +43275,8 @@ "zh-chs": "没有共同的设备", "zh-cht": "沒有共同的裝置", "xloc": [ - "default.handlebars->41->2557", - "default.handlebars->41->2716" + "default.handlebars->45->2572", + "default.handlebars->45->2731" ] }, { @@ -43160,8 +43300,8 @@ "tr": "Bu cihaz grubunda cihaz yok", "zh-chs": "此设备组中没有设备", "xloc": [ - "default.handlebars->41->341", - "default.handlebars->41->345" + "default.handlebars->45->342", + "default.handlebars->45->346" ] }, { @@ -43186,7 +43326,7 @@ "zh-chs": "该设备组中没有设备。", "zh-cht": "該裝置群中沒有裝置。", "xloc": [ - "default.handlebars->41->2152" + "default.handlebars->45->2167" ] }, { @@ -43238,7 +43378,7 @@ "xloc": [ "default-mobile.handlebars->11->188", "default-mobile.handlebars->11->192", - "default.handlebars->41->337" + "default.handlebars->45->338" ] }, { @@ -43263,7 +43403,7 @@ "zh-chs": "找不到带有标签的设备。", "zh-cht": "找不到帶有標籤的裝置。", "xloc": [ - "default.handlebars->41->354" + "default.handlebars->45->355" ] }, { @@ -43288,7 +43428,7 @@ "zh-chs": "找不到文件", "zh-cht": "找不到文件", "xloc": [ - "default.handlebars->41->1339", + "default.handlebars->45->1354", "sharing.handlebars->11->45" ] }, @@ -43314,7 +43454,7 @@ "zh-chs": "找不到群组。", "zh-cht": "找不到群組。", "xloc": [ - "default.handlebars->41->2491" + "default.handlebars->45->2506" ] }, { @@ -43340,7 +43480,7 @@ "zh-cht": "沒有此裝置的訊息。", "xloc": [ "default-mobile.handlebars->11->601", - "default.handlebars->41->1483" + "default.handlebars->45->1498" ] }, { @@ -43364,7 +43504,7 @@ "tr": "bilgi verilmedi", "zh-chs": "未提供信息", "xloc": [ - "default.handlebars->41->138" + "default.handlebars->45->139" ] }, { @@ -43389,7 +43529,7 @@ "zh-chs": "未定义键盘快捷键", "xloc": [ "default-mobile.handlebars->11->439", - "default.handlebars->41->1262" + "default.handlebars->45->1277" ] }, { @@ -43409,7 +43549,7 @@ "ru": "Клавиатурные строки не заданны", "tr": "Tanımlanmış klavye dizesi yok", "xloc": [ - "default.handlebars->41->1267" + "default.handlebars->45->1282" ] }, { @@ -43458,7 +43598,7 @@ "tr": "Bu cihaz grubunda yerel cihaz yok", "zh-chs": "此设备组中没有本地设备", "xloc": [ - "default.handlebars->41->343" + "default.handlebars->45->344" ] }, { @@ -43483,7 +43623,7 @@ "zh-chs": "找不到位置。", "zh-cht": "找不到位置。", "xloc": [ - "default.handlebars->41->769" + "default.handlebars->45->777" ] }, { @@ -43491,8 +43631,9 @@ "nl": "Niet langer een relay voor \\\"{0}\\\".", "pl": "Nie jest już bramką dla \\\"{0}\\\".", "ru": "Больше не является ретранслятором для \\\"{0}\\\".", + "fr": "Plus de relais pour \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->2348" + "default.handlebars->45->2363" ] }, { @@ -43517,7 +43658,7 @@ "zh-chs": "没有适用于此设备的网络接口讯息。", "zh-cht": "沒有適用於此裝置的網絡介面訊息。", "xloc": [ - "default.handlebars->41->177" + "default.handlebars->45->178" ] }, { @@ -43542,7 +43683,7 @@ "zh-chs": "没有其他相同类型的设备组。", "zh-cht": "沒有其他相同類型的裝置群。", "xloc": [ - "default.handlebars->41->1148" + "default.handlebars->45->1163" ] }, { @@ -43567,7 +43708,7 @@ "zh-chs": "此用户没有电话号码", "xloc": [ "default-mobile.handlebars->11->739", - "default.handlebars->41->2887" + "default.handlebars->45->2902" ] }, { @@ -43617,7 +43758,7 @@ "zh-chs": "没有录音。", "zh-cht": "沒有錄音。", "xloc": [ - "default.handlebars->41->2738" + "default.handlebars->45->2753" ] }, { @@ -43625,9 +43766,10 @@ "nl": "Geen relay apparaten beschikbaar.", "pl": "Brak urządzeń do przekierowań.", "ru": "Нет доступных устройств-релеев.", + "fr": "Pas d'appareil relais disponible.", "xloc": [ "default-mobile.handlebars->11->647", - "default.handlebars->41->1988" + "default.handlebars->45->2003" ] }, { @@ -43673,7 +43815,7 @@ "zh-chs": "没有服务器权限", "zh-cht": "沒有伺服器權限", "xloc": [ - "default.handlebars->41->2579" + "default.handlebars->45->2594" ] }, { @@ -43719,7 +43861,7 @@ "zh-chs": "没有用户组成员身份", "zh-cht": "沒有用戶群成員身份", "xloc": [ - "default.handlebars->41->2710" + "default.handlebars->45->2725" ] }, { @@ -43744,7 +43886,7 @@ "zh-chs": "无用户管理权限", "xloc": [ "default-mobile.handlebars->11->737", - "default.handlebars->41->2885" + "default.handlebars->45->2900" ] }, { @@ -43769,7 +43911,7 @@ "zh-chs": "未找到相应的用户。", "zh-cht": "未找到相應的用戶。", "xloc": [ - "default.handlebars->41->2391" + "default.handlebars->45->2406" ] }, { @@ -43794,7 +43936,7 @@ "zh-chs": "没有拥有特殊设备权限的用户", "zh-cht": "沒有擁有特殊裝置權限的用戶", "xloc": [ - "default.handlebars->41->960" + "default.handlebars->45->974" ] }, { @@ -43845,7 +43987,7 @@ "zh-cht": "NodeJS", "xloc": [ "default-mobile.handlebars->11->29", - "default.handlebars->41->36" + "default.handlebars->45->36" ] }, { @@ -43869,7 +44011,7 @@ "tr": "Disk belleği olmayan bellek", "zh-chs": "非分页内存", "xloc": [ - "default.handlebars->41->130" + "default.handlebars->45->131" ] }, { @@ -43904,39 +44046,39 @@ "default-mobile.handlebars->11->429", "default-mobile.handlebars->11->477", "default-mobile.handlebars->11->629", - "default.handlebars->41->1251", - "default.handlebars->41->1848", - "default.handlebars->41->1859", - "default.handlebars->41->1873", - "default.handlebars->41->1885", - "default.handlebars->41->1892", - "default.handlebars->41->1894", - "default.handlebars->41->1944", - "default.handlebars->41->2137", - "default.handlebars->41->2162", - "default.handlebars->41->2167", - "default.handlebars->41->2367", - "default.handlebars->41->2512", - "default.handlebars->41->2514", - "default.handlebars->41->2522", - "default.handlebars->41->2534", - "default.handlebars->41->257", - "default.handlebars->41->2598", - "default.handlebars->41->2610", - "default.handlebars->41->2620", - "default.handlebars->41->2624", - "default.handlebars->41->2636", - "default.handlebars->41->2831", - "default.handlebars->41->285", - "default.handlebars->41->367", - "default.handlebars->41->368", - "default.handlebars->41->776", - "default.handlebars->41->787", - "default.handlebars->41->788", - "default.handlebars->41->82", - "default.handlebars->41->858", - "default.handlebars->41->865", - "default.handlebars->41->878", + "default.handlebars->45->1266", + "default.handlebars->45->1863", + "default.handlebars->45->1874", + "default.handlebars->45->1888", + "default.handlebars->45->1900", + "default.handlebars->45->1907", + "default.handlebars->45->1909", + "default.handlebars->45->1959", + "default.handlebars->45->2152", + "default.handlebars->45->2177", + "default.handlebars->45->2182", + "default.handlebars->45->2382", + "default.handlebars->45->2527", + "default.handlebars->45->2529", + "default.handlebars->45->2537", + "default.handlebars->45->2549", + "default.handlebars->45->258", + "default.handlebars->45->2613", + "default.handlebars->45->2625", + "default.handlebars->45->2635", + "default.handlebars->45->2639", + "default.handlebars->45->2651", + "default.handlebars->45->2846", + "default.handlebars->45->286", + "default.handlebars->45->368", + "default.handlebars->45->369", + "default.handlebars->45->784", + "default.handlebars->45->795", + "default.handlebars->45->796", + "default.handlebars->45->82", + "default.handlebars->45->866", + "default.handlebars->45->873", + "default.handlebars->45->886", "default.handlebars->container->column_l->p41->3->3->p41traceStatus" ] }, @@ -44008,7 +44150,7 @@ "zh-chs": "挪威文", "zh-cht": "挪威文", "xloc": [ - "default.handlebars->41->1657" + "default.handlebars->45->1672" ] }, { @@ -44033,7 +44175,7 @@ "zh-chs": "挪威文(Bokmal)", "zh-cht": "挪威文(Bokmal)", "xloc": [ - "default.handlebars->41->1658" + "default.handlebars->45->1673" ] }, { @@ -44058,7 +44200,7 @@ "zh-chs": "挪威文(尼诺斯克)", "zh-cht": "挪威文(尼諾斯克)", "xloc": [ - "default.handlebars->41->1659" + "default.handlebars->45->1674" ] }, { @@ -44083,7 +44225,7 @@ "zh-chs": "未激活", "zh-cht": "未激活", "xloc": [ - "default.handlebars->41->1447" + "default.handlebars->45->1461" ] }, { @@ -44109,8 +44251,8 @@ "zh-cht": "未啟動(輸入)", "xloc": [ "default-mobile.handlebars->11->291", - "default-mobile.handlebars->11->566", - "default.handlebars->41->802" + "default-mobile.handlebars->11->565", + "default.handlebars->45->810" ] }, { @@ -44136,8 +44278,8 @@ "zh-cht": "未啟動(預)", "xloc": [ "default-mobile.handlebars->11->290", - "default-mobile.handlebars->11->565", - "default.handlebars->41->801" + "default-mobile.handlebars->11->564", + "default.handlebars->45->809" ] }, { @@ -44162,8 +44304,8 @@ "zh-chs": "未连接", "zh-cht": "未連接", "xloc": [ - "default.handlebars->41->2128", - "default.handlebars->41->2141" + "default.handlebars->45->2143", + "default.handlebars->45->2156" ] }, { @@ -44188,8 +44330,8 @@ "zh-chs": "未知", "zh-cht": "未知", "xloc": [ - "default-mobile.handlebars->11->576", - "default.handlebars->41->1458" + "default-mobile.handlebars->11->575", + "default.handlebars->45->1472" ] }, { @@ -44213,7 +44355,7 @@ "tr": "İzin verilmez, yalnızca görüntüleme", "zh-chs": "不允许,只能查看", "xloc": [ - "default.handlebars->41->269" + "default.handlebars->45->270" ] }, { @@ -44238,7 +44380,7 @@ "zh-chs": "不在服务器上", "zh-cht": "不在伺服器上", "xloc": [ - "default.handlebars->41->2760" + "default.handlebars->45->2775" ] }, { @@ -44263,8 +44405,8 @@ "zh-chs": "没有设置", "zh-cht": "沒有設置", "xloc": [ - "default.handlebars->41->2585", - "default.handlebars->41->2586" + "default.handlebars->45->2600", + "default.handlebars->45->2601" ] }, { @@ -44289,7 +44431,7 @@ "zh-chs": "未经审核的", "zh-cht": "未經審核的", "xloc": [ - "default.handlebars->41->2684" + "default.handlebars->45->2699" ] }, { @@ -44317,12 +44459,12 @@ "default-mobile.handlebars->11->332", "default-mobile.handlebars->11->381", "default-mobile.handlebars->11->635", - "default.handlebars->41->1005", - "default.handlebars->41->1027", - "default.handlebars->41->1037", - "default.handlebars->41->1904", - "default.handlebars->41->2646", - "default.handlebars->41->895" + "default.handlebars->45->1019", + "default.handlebars->45->1041", + "default.handlebars->45->1051", + "default.handlebars->45->1919", + "default.handlebars->45->2661", + "default.handlebars->45->903" ] }, { @@ -44372,9 +44514,9 @@ "zh-chs": "通知设置", "zh-cht": "通知設定", "xloc": [ - "default.handlebars->41->1767", - "default.handlebars->41->2127", - "default.handlebars->41->992", + "default.handlebars->45->1006", + "default.handlebars->45->1782", + "default.handlebars->45->2142", "default.handlebars->container->column_l->p2->p2info->p2AccountActions->3->10" ] }, @@ -44443,7 +44585,7 @@ "zh-chs": "通知音效", "zh-cht": "通知音效", "xloc": [ - "default.handlebars->41->1762" + "default.handlebars->45->1777" ] }, { @@ -44468,8 +44610,8 @@ "zh-chs": "通知", "zh-cht": "通知", "xloc": [ - "default.handlebars->41->1893", - "default.handlebars->41->866" + "default.handlebars->45->1908", + "default.handlebars->45->874" ] }, { @@ -44494,8 +44636,8 @@ "zh-chs": "通知", "zh-cht": "通知", "xloc": [ - "default.handlebars->41->2652", - "default.handlebars->41->282" + "default.handlebars->45->2667", + "default.handlebars->45->283" ] }, { @@ -44520,7 +44662,7 @@ "zh-chs": "仅通知", "zh-cht": "只通知", "xloc": [ - "default.handlebars->41->1086" + "default.handlebars->45->1101" ] }, { @@ -44545,9 +44687,9 @@ "zh-chs": "通知使用者", "zh-cht": "通知使用者", "xloc": [ - "default.handlebars->41->1999", - "default.handlebars->41->2003", - "default.handlebars->41->2006" + "default.handlebars->45->2014", + "default.handlebars->45->2018", + "default.handlebars->45->2021" ] }, { @@ -44572,7 +44714,7 @@ "zh-chs": "通知{0}", "zh-cht": "通知{0}", "xloc": [ - "default.handlebars->41->2431" + "default.handlebars->45->2446" ] }, { @@ -44596,13 +44738,13 @@ "tr": "Boş", "zh-chs": "空值", "xloc": [ - "default.handlebars->41->2954" + "default.handlebars->45->2969" ] }, { "cs": "Web O & pen ...", "da": "O&pen Site...", - "de": "Website öffnen...", + "de": "Webseite öffnen...", "en": "O&pen Site...", "es": "Sitio de O & pen ...", "fi": "O & kynä -sivusto ...", @@ -44649,13 +44791,13 @@ "default-mobile.handlebars->11->531", "default-mobile.handlebars->container->page_content->column_l->p10->p10dialog->5", "default-mobile.handlebars->dialog->idx_dlgButtonBar", - "default.handlebars->41->1839", - "default.handlebars->41->2132", - "default.handlebars->41->2146", - "default.handlebars->41->830", - "default.handlebars->41->834", - "default.handlebars->41->838", - "default.handlebars->41->844", + "default.handlebars->45->1854", + "default.handlebars->45->2147", + "default.handlebars->45->2161", + "default.handlebars->45->838", + "default.handlebars->45->842", + "default.handlebars->45->846", + "default.handlebars->45->852", "default.handlebars->container->dialog->idx_dlgButtonBar", "login-mobile.handlebars->dialog->idx_dlgButtonBar", "login.handlebars->dialog->idx_dlgButtonBar", @@ -44687,7 +44829,7 @@ "tr": "işletim sistemi", "zh-chs": "操作系统", "xloc": [ - "default.handlebars->41->348" + "default.handlebars->45->349" ] }, { @@ -44713,7 +44855,7 @@ "zh-cht": "操作系統名稱", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p2->xdevicesBar->1->5", - "default.handlebars->41->784", + "default.handlebars->45->792", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar->15->1" ] }, @@ -44722,9 +44864,10 @@ "nl": "OTP 2FA niet toegestaan", "pl": "OTP 2FA niedozwolone", "ru": "Двухфакторная аутентификация одноразовым паролем не разрешена", + "fr": "OTP 2FA non autorisé", "xloc": [ "default-mobile.handlebars->11->63", - "default.handlebars->41->197" + "default.handlebars->45->198" ] }, { @@ -44749,7 +44892,7 @@ "zh-chs": "欧舒丹", "zh-cht": "歐舒丹", "xloc": [ - "default.handlebars->41->1660" + "default.handlebars->45->1675" ] }, { @@ -44775,7 +44918,7 @@ "zh-cht": "發生在{0}", "xloc": [ "default-mobile.handlebars->11->705", - "default.handlebars->41->2853" + "default.handlebars->45->2868" ] }, { @@ -44796,7 +44939,7 @@ "xloc": [ "default-mobile.handlebars->11->237", "default-mobile.handlebars->11->245", - "default.handlebars->41->614" + "default.handlebars->45->617" ] }, { @@ -44846,7 +44989,7 @@ "zh-chs": "离线用户", "zh-cht": "離線用戶", "xloc": [ - "default.handlebars->41->2388" + "default.handlebars->45->2403" ] }, { @@ -44871,7 +45014,7 @@ "zh-chs": "旧密码", "zh-cht": "舊密碼", "xloc": [ - "default.handlebars->41->470" + "default.handlebars->45->473" ] }, { @@ -44897,7 +45040,7 @@ "zh-cht": "舊密碼:", "xloc": [ "default-mobile.handlebars->11->116", - "default.handlebars->41->1779" + "default.handlebars->45->1794" ] }, { @@ -44922,7 +45065,7 @@ "zh-chs": "一天", "zh-cht": "一天", "xloc": [ - "default.handlebars->41->2364" + "default.handlebars->45->2379" ] }, { @@ -44948,7 +45091,7 @@ "zh-cht": "一次性保安編碼可以用作輔助身份驗證。生成一群,打印並保存在安全的地方。", "xloc": [ "default-mobile.handlebars->11->74", - "default.handlebars->41->214" + "default.handlebars->45->215" ] }, { @@ -44957,8 +45100,9 @@ "pl": "Hasło Jednorazowe", "pt-br": "One-Time Password (Senha de único acesso)", "ru": "Одноразовый пароль", + "fr": "Mot de passe à usage unique (OTP)", "xloc": [ - "default.handlebars->41->2837" + "default.handlebars->45->2852" ] }, { @@ -45010,7 +45154,7 @@ "zh-chs": "在线用户", "zh-cht": "在線用戶", "xloc": [ - "default.handlebars->41->2387" + "default.handlebars->45->2402" ] }, { @@ -45034,7 +45178,7 @@ "tr": "Yalnızca ilk 100 kullanıcıyı göster", "zh-chs": "只显示前 100 个用户", "xloc": [ - "default.handlebars->41->2432" + "default.handlebars->45->2447" ] }, { @@ -45060,8 +45204,8 @@ "zh-cht": "只能編輯小於200k的檔案。", "xloc": [ "default-mobile.handlebars->11->488", - "default.handlebars->41->1366", - "default.handlebars->41->747", + "default.handlebars->45->1381", + "default.handlebars->45->755", "sharing.handlebars->11->67" ] }, @@ -45138,7 +45282,7 @@ "zh-chs": "在设备上打开页面", "zh-cht": "在裝置上打開頁面", "xloc": [ - "default.handlebars->41->1038" + "default.handlebars->45->1052" ] }, { @@ -45191,7 +45335,7 @@ { "cs": "Otevřete web", "da": "Åbn webstedet", - "de": "Website öffnen", + "de": "Webseite öffnen", "en": "Open Web Site", "es": "Abrir Sitio Web", "fi": "Avaa verkkosivusto", @@ -45231,7 +45375,7 @@ "zh-chs": "打开XTerm终端", "zh-cht": "打開XTerm終端", "xloc": [ - "default.handlebars->41->921" + "default.handlebars->45->929" ] }, { @@ -45281,7 +45425,7 @@ "zh-chs": "打开此计算机的聊天窗口", "zh-cht": "打開此電腦的聊天窗口", "xloc": [ - "default.handlebars->41->902", + "default.handlebars->45->910", "default.handlebars->container->column_l->p11->deskarea0->deskarea4->1" ] }, @@ -45324,7 +45468,7 @@ "tr": "OpenBSD x86-64", "xloc": [ "default-mobile.handlebars->11->43", - "default.handlebars->41->50" + "default.handlebars->45->50" ] }, { @@ -45366,7 +45510,7 @@ "tr": "OpenWRT x86-64", "xloc": [ "default-mobile.handlebars->11->42", - "default.handlebars->41->49" + "default.handlebars->45->49" ] }, { @@ -45391,7 +45535,7 @@ "zh-chs": "开头:{0}", "zh-cht": "開場:{0}", "xloc": [ - "default.handlebars->41->2216" + "default.handlebars->45->2231" ] }, { @@ -45417,13 +45561,13 @@ "zh-cht": "操作系統", "xloc": [ "default-mobile.handlebars->11->533", - "default.handlebars->41->1171", - "default.handlebars->41->1405", - "default.handlebars->41->2804", - "default.handlebars->41->323", - "default.handlebars->41->493", - "default.handlebars->41->541", - "default.handlebars->41->828" + "default.handlebars->45->1186", + "default.handlebars->45->1420", + "default.handlebars->45->2819", + "default.handlebars->45->324", + "default.handlebars->45->496", + "default.handlebars->45->544", + "default.handlebars->45->836" ] }, { @@ -45449,11 +45593,11 @@ "zh-cht": "操作", "xloc": [ "default-mobile.handlebars->11->371", - "default.handlebars->41->1106", - "default.handlebars->41->2415", - "default.handlebars->41->2499", - "default.handlebars->41->657", - "default.handlebars->41->676" + "default.handlebars->45->1121", + "default.handlebars->45->2430", + "default.handlebars->45->2514", + "default.handlebars->45->660", + "default.handlebars->45->679" ] }, { @@ -45461,6 +45605,7 @@ "nl": "Opties", "pl": "Opcje", "ru": "Опции", + "fr": "Options", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->1" ] @@ -45509,7 +45654,7 @@ "zh-chs": "奥里亚", "zh-cht": "奧里亞", "xloc": [ - "default.handlebars->41->1661" + "default.handlebars->45->1676" ] }, { @@ -45534,7 +45679,7 @@ "zh-chs": "奥罗莫", "zh-cht": "奧羅莫", "xloc": [ - "default.handlebars->41->1662" + "default.handlebars->45->1677" ] }, { @@ -45610,7 +45755,7 @@ "zh-cht": "過時的", "xloc": [ "default-mobile.handlebars->11->530", - "default.handlebars->41->843" + "default.handlebars->45->851" ] }, { @@ -45722,7 +45867,7 @@ "zh-chs": "是否覆盖文件存在?", "zh-cht": "是否覆蓋文件存在?", "xloc": [ - "default.handlebars->41->692" + "default.handlebars->45->695" ] }, { @@ -45768,7 +45913,7 @@ "zh-chs": "自己的过程", "zh-cht": "自己的過程", "xloc": [ - "default.handlebars->41->1288" + "default.handlebars->45->1303" ] }, { @@ -45793,7 +45938,7 @@ "zh-chs": "PID", "zh-cht": "PID", "xloc": [ - "default.handlebars->41->1284", + "default.handlebars->45->1299", "default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsArea->DeskToolsProcessTab->deskToolsHeader->1" ] }, @@ -45819,7 +45964,7 @@ "zh-chs": "推", "xloc": [ "default-mobile.handlebars->11->607", - "default.handlebars->41->1490" + "default.handlebars->45->1505" ] }, { @@ -45844,7 +45989,7 @@ "zh-chs": "向下翻页", "xloc": [ "default-mobile.handlebars->11->424", - "default.handlebars->41->1246" + "default.handlebars->45->1261" ] }, { @@ -45869,7 +46014,7 @@ "zh-chs": "向上翻页", "xloc": [ "default-mobile.handlebars->11->423", - "default.handlebars->41->1245" + "default.handlebars->45->1260" ] }, { @@ -45893,7 +46038,7 @@ "tr": "Sayfalı Bellek", "zh-chs": "分页内存", "xloc": [ - "default.handlebars->41->131" + "default.handlebars->45->132" ] }, { @@ -45919,7 +46064,7 @@ "zh-cht": "零件號", "xloc": [ "default-mobile.handlebars->11->594", - "default.handlebars->41->1476" + "default.handlebars->45->1491" ] }, { @@ -45944,7 +46089,7 @@ "zh-chs": "部分的", "zh-cht": "部分的", "xloc": [ - "default.handlebars->41->2403" + "default.handlebars->45->2418" ] }, { @@ -46015,7 +46160,7 @@ "xloc": [ "default-mobile.handlebars->11->135", "default-mobile.handlebars->11->639", - "default.handlebars->41->1815" + "default.handlebars->45->1830" ] }, { @@ -46040,7 +46185,7 @@ "zh-chs": "部分权限", "zh-cht": "部分權限", "xloc": [ - "default.handlebars->41->2582" + "default.handlebars->45->2597" ] }, { @@ -46093,20 +46238,20 @@ "default-mobile.handlebars->11->387", "default-mobile.handlebars->11->455", "default-mobile.handlebars->11->462", - "default.handlebars->41->1129", - "default.handlebars->41->1218", - "default.handlebars->41->1315", - "default.handlebars->41->1322", - "default.handlebars->41->1807", - "default.handlebars->41->1962", - "default.handlebars->41->2461", - "default.handlebars->41->2462", - "default.handlebars->41->2616", - "default.handlebars->41->2618", - "default.handlebars->41->2689", - "default.handlebars->41->2690", - "default.handlebars->41->317", - "default.handlebars->41->460", + "default.handlebars->45->1144", + "default.handlebars->45->1233", + "default.handlebars->45->1330", + "default.handlebars->45->1337", + "default.handlebars->45->1822", + "default.handlebars->45->1977", + "default.handlebars->45->2476", + "default.handlebars->45->2477", + "default.handlebars->45->2631", + "default.handlebars->45->2633", + "default.handlebars->45->2704", + "default.handlebars->45->2705", + "default.handlebars->45->318", + "default.handlebars->45->463", "login2.handlebars->centralTable->1->0->logincell->loginpanel->loginpanelform->loginuserpassdiv->1->1->2->1", "login2.handlebars->centralTable->1->0->logincell->loginpanel->loginpanelform->loginuserpassdiv->1->1->2->1", "mstsc.handlebars->main->1->3->1->rowpassword->1->0", @@ -46253,7 +46398,7 @@ "zh-chs": "密码已更改。", "xloc": [ "default-mobile.handlebars->11->733", - "default.handlebars->41->2881" + "default.handlebars->45->2896" ] }, { @@ -46304,7 +46449,7 @@ "zh-chs": "密码提示", "zh-cht": "密碼提示", "xloc": [ - "default.handlebars->41->2691" + "default.handlebars->45->2706" ] }, { @@ -46330,7 +46475,7 @@ "zh-cht": "密碼提示:", "xloc": [ "default-mobile.handlebars->11->119", - "default.handlebars->41->1782" + "default.handlebars->45->1797" ] }, { @@ -46429,8 +46574,8 @@ "account-invite.html->2->5", "default-mobile.handlebars->11->111", "default-mobile.handlebars->11->112", - "default.handlebars->41->1774", - "default.handlebars->41->1775", + "default.handlebars->45->1789", + "default.handlebars->45->1790", "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->createpanel->1->1->9->1->4->1", "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->createpanel->1->1->9->1->6->1", "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->loginpanel->1->7->1->2->1", @@ -46473,9 +46618,9 @@ "default-mobile.handlebars->11->493", "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->3", "default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->3", - "default.handlebars->41->1336", - "default.handlebars->41->1372", - "default.handlebars->41->2189", + "default.handlebars->45->1351", + "default.handlebars->45->1387", + "default.handlebars->45->2204", "default.handlebars->container->column_l->p12->termTable->1->1->4->1->3", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3", @@ -46578,7 +46723,7 @@ "tr": "En Yüksek Sayfalı Bellek", "zh-chs": "峰值分页内存", "xloc": [ - "default.handlebars->41->136" + "default.handlebars->45->137" ] }, { @@ -46602,7 +46747,7 @@ "tr": "En Yüksek Sanal Bellek", "zh-chs": "峰值虚拟内存", "xloc": [ - "default.handlebars->41->137" + "default.handlebars->45->138" ] }, { @@ -46626,7 +46771,7 @@ "tr": "Tepe Çalışma Seti", "zh-chs": "峰值工作集", "xloc": [ - "default.handlebars->41->135" + "default.handlebars->45->136" ] }, { @@ -46652,7 +46797,7 @@ "zh-cht": "執行代理指令", "xloc": [ "default-mobile.handlebars->11->610", - "default.handlebars->41->1493" + "default.handlebars->45->1508" ] }, { @@ -46721,8 +46866,8 @@ "zh-chs": "执行英特尔®AMT激活和配置。", "zh-cht": "執行英特爾®AMT激活和配置。", "xloc": [ - "default.handlebars->41->1908", - "default.handlebars->41->437" + "default.handlebars->45->1923", + "default.handlebars->45->440" ] }, { @@ -46835,7 +46980,7 @@ "zh-chs": "执行英特尔® AMT 关机?", "xloc": [ "default-mobile.handlebars->11->377", - "default.handlebars->41->1121" + "default.handlebars->45->1136" ] }, { @@ -46860,7 +47005,7 @@ "zh-chs": "执行英特尔® AMT 电源?", "xloc": [ "default-mobile.handlebars->11->375", - "default.handlebars->41->1119" + "default.handlebars->45->1134" ] }, { @@ -46885,7 +47030,7 @@ "zh-chs": "执行英特尔® AMT 重置?", "xloc": [ "default-mobile.handlebars->11->379", - "default.handlebars->41->1123" + "default.handlebars->45->1138" ] }, { @@ -46910,7 +47055,7 @@ "zh-chs": "执行批量设备通知", "zh-cht": "執行批量設備通知", "xloc": [ - "default.handlebars->41->683" + "default.handlebars->45->686" ] }, { @@ -46935,7 +47080,7 @@ "zh-chs": "执行批量设备标签操作", "zh-cht": "執行批次裝置標籤操作", "xloc": [ - "default.handlebars->41->675" + "default.handlebars->45->678" ] }, { @@ -46961,7 +47106,7 @@ "zh-cht": "在裝置上執行電源操作", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea4->1->3", - "default.handlebars->41->894", + "default.handlebars->45->902", "default.handlebars->container->column_l->p11->deskarea0->deskarea1->1", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->1", "default.handlebars->container->column_l->p13->p13toolbar->1->0->1->1" @@ -46985,7 +47130,7 @@ "tr": "Güç kapatılsın mı?", "xloc": [ "default-mobile.handlebars->11->347", - "default.handlebars->41->982" + "default.handlebars->45->996" ] }, { @@ -47006,7 +47151,7 @@ "tr": "Güç açık mı?", "xloc": [ "default-mobile.handlebars->11->349", - "default.handlebars->41->984" + "default.handlebars->45->998" ] }, { @@ -47031,7 +47176,7 @@ "zh-chs": "执行电源操作= {0},强制执行= {1}", "zh-cht": "執行電源操作= {0},強制執行= {1}", "xloc": [ - "default.handlebars->41->2221" + "default.handlebars->45->2236" ] }, { @@ -47056,7 +47201,7 @@ "zh-chs": "没有权限", "xloc": [ "default-mobile.handlebars->11->714", - "default.handlebars->41->2862" + "default.handlebars->45->2877" ] }, { @@ -47082,8 +47227,8 @@ "zh-cht": "權限", "xloc": [ "default-mobile.handlebars->11->699", - "default.handlebars->41->2092", - "default.handlebars->41->2386" + "default.handlebars->45->2107", + "default.handlebars->45->2401" ] }, { @@ -47108,7 +47253,7 @@ "zh-chs": "波斯/伊朗", "zh-cht": "波斯/伊朗", "xloc": [ - "default.handlebars->41->1663" + "default.handlebars->45->1678" ] }, { @@ -47184,10 +47329,10 @@ "default-mobile.handlebars->11->81", "default-mobile.handlebars->11->96", "default-mobile.handlebars->11->98", - "default.handlebars->41->1508", - "default.handlebars->41->1511", - "default.handlebars->41->240", - "default.handlebars->41->2667" + "default.handlebars->45->1523", + "default.handlebars->45->1526", + "default.handlebars->45->241", + "default.handlebars->45->2682" ] }, { @@ -47212,7 +47357,7 @@ "zh-chs": "电话号码", "zh-cht": "電話號碼", "xloc": [ - "default.handlebars->41->2597" + "default.handlebars->45->2612" ] }, { @@ -47238,8 +47383,8 @@ "zh-cht": "電話號碼:", "xloc": [ "default-mobile.handlebars->11->97", - "default.handlebars->41->1510", - "default.handlebars->41->2666" + "default.handlebars->45->1525", + "default.handlebars->45->2681" ] }, { @@ -47286,7 +47431,7 @@ "zh-chs": "将节点放在这里", "zh-cht": "將節點放在這裡", "xloc": [ - "default.handlebars->41->762" + "default.handlebars->45->770" ] }, { @@ -47336,7 +47481,7 @@ "zh-chs": "请添加两因素认证的备用验证码。如果丢失了当前因素,则无法恢复该帐户。", "zh-cht": "請新增二因子鑑別的備用鑑別碼。如果丟失了當前因子,則無法恢復該帳戶。", "xloc": [ - "default.handlebars->41->68" + "default.handlebars->45->68" ] }, { @@ -47361,7 +47506,7 @@ "zh-chs": "请注意,不建议降级。请仅在最近的升级后发生问题时才这样做。", "zh-cht": "請注意,不建議降級。請僅在最近的升級後發生問題時才這樣做。", "xloc": [ - "default.handlebars->41->299" + "default.handlebars->45->300" ] }, { @@ -47438,7 +47583,7 @@ "zh-cht": "請等待幾分鐘以接收驗證。", "xloc": [ "default-mobile.handlebars->11->107", - "default.handlebars->41->1769" + "default.handlebars->45->1784" ] }, { @@ -47463,8 +47608,8 @@ "zh-chs": "插件指令", "zh-cht": "外掛指令", "xloc": [ - "default.handlebars->41->298", - "default.handlebars->41->2991" + "default.handlebars->45->299", + "default.handlebars->45->3006" ] }, { @@ -47489,7 +47634,7 @@ "zh-chs": "插件错误", "zh-cht": "外掛錯誤", "xloc": [ - "default.handlebars->41->304" + "default.handlebars->45->305" ] }, { @@ -47514,7 +47659,7 @@ "zh-chs": "PluginHandler无法事件消息:", "zh-cht": "PluginHandler無法事件消息:", "xloc": [ - "default.handlebars->41->258" + "default.handlebars->45->259" ] }, { @@ -47617,7 +47762,7 @@ "zh-cht": "PogoPlug ARM", "xloc": [ "default-mobile.handlebars->11->19", - "default.handlebars->41->26" + "default.handlebars->45->26" ] }, { @@ -47643,7 +47788,7 @@ "zh-cht": "政策", "xloc": [ "default-mobile.handlebars->11->134", - "default.handlebars->41->1814" + "default.handlebars->45->1829" ] }, { @@ -47668,13 +47813,13 @@ "zh-chs": "波兰文", "zh-cht": "波蘭文", "xloc": [ - "default.handlebars->41->1664" + "default.handlebars->45->1679" ] }, { "cs": "Mapování portů", "da": "Port Mapping", - "de": "Port-Mapping", + "de": "Port-Zuordnung", "en": "Port Mapping", "es": "Mapeo de Puertos", "fi": "Portin kartoitus", @@ -47730,7 +47875,7 @@ "ru": "Синхронизация имени порта", "tr": "Bağlantı Noktası Adı Senkronizasyonu", "xloc": [ - "default.handlebars->41->1869" + "default.handlebars->45->1884" ] }, { @@ -47751,7 +47896,7 @@ "tr": "Port numarası", "xloc": [ "default-mobile.handlebars->11->280", - "default.handlebars->41->791" + "default.handlebars->45->799" ] }, { @@ -47772,7 +47917,7 @@ "tr": "Bağlantı Noktası Türü", "xloc": [ "default-mobile.handlebars->11->281", - "default.handlebars->41->792" + "default.handlebars->45->800" ] }, { @@ -47839,7 +47984,7 @@ "zh-chs": "葡萄牙文", "zh-cht": "葡萄牙文", "xloc": [ - "default.handlebars->41->1665" + "default.handlebars->45->1680" ] }, { @@ -47864,7 +48009,7 @@ "zh-chs": "葡萄牙文(巴西)", "zh-cht": "葡萄牙文(巴西)", "xloc": [ - "default.handlebars->41->1666" + "default.handlebars->45->1681" ] }, { @@ -47937,8 +48082,8 @@ "xloc": [ "default-mobile.handlebars->11->346", "default-mobile.handlebars->11->348", - "default.handlebars->41->981", - "default.handlebars->41->983" + "default.handlebars->45->995", + "default.handlebars->45->997" ] }, { @@ -47988,7 +48133,7 @@ "zh-chs": "电源状态", "zh-cht": "電源狀態", "xloc": [ - "default.handlebars->41->2139", + "default.handlebars->45->2154", "default.handlebars->container->column_l->p21->p21main->1->1->meshPowerChartDiv->1" ] }, @@ -48016,8 +48161,8 @@ "xloc": [ "default-mobile.handlebars->11->235", "default-mobile.handlebars->11->367", - "default.handlebars->41->1099", - "default.handlebars->41->6" + "default.handlebars->45->1114", + "default.handlebars->45->6" ] }, { @@ -48042,7 +48187,7 @@ "zh-chs": "关闭设备", "zh-cht": "關閉裝置", "xloc": [ - "default.handlebars->41->647" + "default.handlebars->45->650" ] }, { @@ -48062,7 +48207,7 @@ "ru": "Выключатель питания готов к использованию.", "tr": "Güç anahtarı kullanıma hazırdır.", "xloc": [ - "default.handlebars->41->623" + "default.handlebars->45->626" ] }, { @@ -48089,8 +48234,8 @@ "xloc": [ "default-mobile.handlebars->11->230", "default-mobile.handlebars->11->238", - "default.handlebars->41->1", - "default.handlebars->41->600" + "default.handlebars->45->1", + "default.handlebars->45->603" ] }, { @@ -48115,7 +48260,7 @@ "zh-chs": "预激活", "zh-cht": "預激活", "xloc": [ - "default.handlebars->41->1448" + "default.handlebars->45->1462" ] }, { @@ -48142,8 +48287,8 @@ "xloc": [ "default-mobile.handlebars->11->236", "default-mobile.handlebars->11->244", - "default.handlebars->41->612", - "default.handlebars->41->7" + "default.handlebars->45->615", + "default.handlebars->45->7" ] }, { @@ -48168,7 +48313,7 @@ "zh-chs": "存在于服务器上", "zh-cht": "存在於伺服器上", "xloc": [ - "default.handlebars->41->2759" + "default.handlebars->45->2774" ] }, { @@ -48271,7 +48416,7 @@ "zh-chs": "现在按下按键。", "zh-cht": "現在按下按鍵。", "xloc": [ - "default.handlebars->41->233" + "default.handlebars->45->234" ] }, { @@ -48297,10 +48442,10 @@ "xloc": [ "default-mobile.handlebars->11->86", "default-mobile.handlebars->11->87", - "default.handlebars->41->1503", - "default.handlebars->41->2661", - "default.handlebars->41->2687", - "default.handlebars->41->310" + "default.handlebars->45->1518", + "default.handlebars->45->2676", + "default.handlebars->45->2702", + "default.handlebars->45->311" ] }, { @@ -48325,7 +48470,7 @@ "zh-chs": "打印屏幕", "xloc": [ "default-mobile.handlebars->11->418", - "default.handlebars->41->1240" + "default.handlebars->45->1255" ] }, { @@ -48349,7 +48494,7 @@ "tr": "Öncelik Artışı", "zh-chs": "优先提升", "xloc": [ - "default.handlebars->41->119" + "default.handlebars->45->120" ] }, { @@ -48399,7 +48544,7 @@ "zh-chs": "隐私栏", "zh-cht": "隱私欄", "xloc": [ - "default.handlebars->41->284" + "default.handlebars->45->285" ] }, { @@ -48444,7 +48589,7 @@ "tr": "Özel Bellek", "zh-chs": "私人内存", "xloc": [ - "default.handlebars->41->132" + "default.handlebars->45->133" ] }, { @@ -48468,7 +48613,7 @@ "tr": "Ayrıcalıklı İşlemci Süresi", "zh-chs": "特权处理器时间", "xloc": [ - "default.handlebars->41->124" + "default.handlebars->45->125" ] }, { @@ -48493,7 +48638,7 @@ "zh-chs": "进程控制", "zh-cht": "進程控制", "xloc": [ - "default.handlebars->41->1300" + "default.handlebars->45->1315" ] }, { @@ -48517,7 +48662,7 @@ "tr": "İşlem Ayrıntıları, #{0}", "zh-chs": "流程详情,#{0}", "xloc": [ - "default.handlebars->41->1275" + "default.handlebars->45->1290" ] }, { @@ -48541,7 +48686,7 @@ "tr": "İşlem adı", "zh-chs": "进程名称", "xloc": [ - "default.handlebars->41->112" + "default.handlebars->45->113" ] }, { @@ -48591,7 +48736,7 @@ "zh-chs": "处理控制台命令:“{0}”", "zh-cht": "處理控制台命令:“{0}”", "xloc": [ - "default.handlebars->41->2213" + "default.handlebars->45->2228" ] }, { @@ -48616,7 +48761,7 @@ "zh-chs": "提示", "zh-cht": "提示", "xloc": [ - "default.handlebars->41->283" + "default.handlebars->45->284" ] }, { @@ -48641,7 +48786,7 @@ "zh-chs": "用户同意提示", "zh-cht": "用戶同意提示", "xloc": [ - "default.handlebars->41->1085" + "default.handlebars->45->1100" ] }, { @@ -48666,9 +48811,9 @@ "zh-chs": "用户同意提示", "zh-cht": "用戶同意提示", "xloc": [ - "default.handlebars->41->2000", - "default.handlebars->41->2004", - "default.handlebars->41->2007" + "default.handlebars->45->2015", + "default.handlebars->45->2019", + "default.handlebars->45->2022" ] }, { @@ -48693,16 +48838,18 @@ "zh-chs": "协议", "zh-cht": "協議", "xloc": [ - "default.handlebars->41->2757", + "default.handlebars->45->2772", "player.handlebars->3->32" ] }, { "en": "Protocol negotiation failed ({0})", "nl": "Protocolonderhandeling mislukt ({0})", + "pl": "Niepowodzenie negocjacji protokołu ({0})", "ru": "Ошибка согласования протокола ({0})", + "fr": "Échec de la négociation du protocol ({0})", "xloc": [ - "default.handlebars->41->1203" + "default.handlebars->45->1218" ] }, { @@ -48749,8 +48896,8 @@ "zh-chs": "配置状态", "zh-cht": "配置狀態", "xloc": [ - "default-mobile.handlebars->11->570", - "default.handlebars->41->1452" + "default-mobile.handlebars->11->569", + "default.handlebars->45->1466" ] }, { @@ -48797,7 +48944,7 @@ "zh-cht": "公開鏈結", "xloc": [ "default-mobile.handlebars->11->146", - "default.handlebars->41->2174" + "default.handlebars->45->2189" ] }, { @@ -48843,7 +48990,7 @@ "zh-chs": "旁遮普文", "zh-cht": "旁遮普文", "xloc": [ - "default.handlebars->41->1667" + "default.handlebars->45->1682" ] }, { @@ -48868,7 +49015,7 @@ "zh-chs": "旁遮普(印度)", "zh-cht": "旁遮普(印度)", "xloc": [ - "default.handlebars->41->1668" + "default.handlebars->45->1683" ] }, { @@ -48893,7 +49040,7 @@ "zh-chs": "旁遮普(巴基斯坦)", "zh-cht": "旁遮普(巴基斯坦)", "xloc": [ - "default.handlebars->41->1669" + "default.handlebars->45->1684" ] }, { @@ -48927,8 +49074,9 @@ "pl": "Powiadomianie Push", "pt-br": "Notificação de Push", "ru": "Push уведомление", + "fr": "Notifications", "xloc": [ - "default.handlebars->41->2836" + "default.handlebars->45->2851" ] }, { @@ -49048,7 +49196,7 @@ "zh-chs": "盖丘亚族", "zh-cht": "蓋丘亞族", "xloc": [ - "default.handlebars->41->1670" + "default.handlebars->45->1685" ] }, { @@ -49150,10 +49298,10 @@ "xloc": [ "default-mobile.handlebars->11->325", "default-mobile.handlebars->11->329", - "default.handlebars->41->391", - "default.handlebars->41->884", - "default.handlebars->41->888", - "default.handlebars->41->924", + "default.handlebars->45->394", + "default.handlebars->45->892", + "default.handlebars->45->896", + "default.handlebars->45->934", "default.handlebars->container->dialog->dialogBody->dialog7->1->td7rdpkvm" ] }, @@ -49162,6 +49310,7 @@ "nl": "RDP verbinden", "pl": "Połącz (protokół RDP)", "ru": "Подключиться по RDP", + "fr": "Connexion RDP", "xloc": [ "default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1rspan" ] @@ -49188,7 +49337,7 @@ "zh-chs": "RDP连接", "zh-cht": "RDP連接", "xloc": [ - "default.handlebars->41->740" + "default.handlebars->45->744" ] }, { @@ -49196,8 +49345,9 @@ "nl": "RDP inloggegevens", "pl": "Poświadczenia RDP", "ru": "Учетные данные RDP", + "fr": "Informations d'identification RDP", "xloc": [ - "default.handlebars->41->1222" + "default.handlebars->45->1237" ] }, { @@ -49243,7 +49393,7 @@ "zh-chs": "RDP远程连接端口:", "zh-cht": "RDP遠程連接介面:", "xloc": [ - "default.handlebars->41->739" + "default.handlebars->45->743" ] }, { @@ -49344,7 +49494,7 @@ "zh-chs": "RSS", "zh-cht": "RSS", "xloc": [ - "default.handlebars->41->2950" + "default.handlebars->45->2965" ] }, { @@ -49394,7 +49544,7 @@ "zh-chs": "随机密码", "zh-cht": "隨機密碼", "xloc": [ - "default.handlebars->41->1963" + "default.handlebars->45->1978" ] }, { @@ -49419,7 +49569,7 @@ "zh-chs": "随机密码。", "zh-cht": "隨機密碼。", "xloc": [ - "default.handlebars->41->2463" + "default.handlebars->45->2478" ] }, { @@ -49438,7 +49588,7 @@ "ru": "Raritan Dominion KX III", "tr": "Raritan Dominion KX III", "xloc": [ - "default.handlebars->41->1803" + "default.handlebars->45->1818" ] }, { @@ -49529,9 +49679,9 @@ "zh-chs": "真正的名字", "zh-cht": "真正的名字", "xloc": [ - "default.handlebars->41->2594", - "default.handlebars->41->2596", - "default.handlebars->41->2680" + "default.handlebars->45->2609", + "default.handlebars->45->2611", + "default.handlebars->45->2695" ] }, { @@ -49556,7 +49706,7 @@ "zh-chs": "境界", "zh-cht": "境界", "xloc": [ - "default.handlebars->41->2472" + "default.handlebars->45->2487" ] }, { @@ -49582,7 +49732,7 @@ "zh-cht": "收到無效的網絡數據", "xloc": [ "default-mobile.handlebars->11->410", - "default.handlebars->41->1201", + "default.handlebars->45->1216", "sharing.handlebars->11->10", "sharing.handlebars->11->32" ] @@ -49609,9 +49759,9 @@ "zh-chs": "记录会议", "zh-cht": "記錄會議", "xloc": [ - "default.handlebars->41->1871", - "default.handlebars->41->2521", - "default.handlebars->41->2599" + "default.handlebars->45->1886", + "default.handlebars->45->2536", + "default.handlebars->45->2614" ] }, { @@ -49661,9 +49811,9 @@ "zh-chs": "记录会议", "zh-cht": "記錄會議", "xloc": [ - "default.handlebars->41->2008", - "default.handlebars->41->2559", - "default.handlebars->41->2668" + "default.handlebars->45->2023", + "default.handlebars->45->2574", + "default.handlebars->45->2683" ] }, { @@ -49688,7 +49838,7 @@ "zh-chs": "记录细节", "zh-cht": "記錄細節", "xloc": [ - "default.handlebars->41->2771" + "default.handlebars->45->2786" ] }, { @@ -49733,8 +49883,8 @@ "ru": "Повторяющийся", "tr": "yinelenen", "xloc": [ - "default.handlebars->41->278", - "default.handlebars->41->280" + "default.handlebars->45->279", + "default.handlebars->45->281" ] }, { @@ -49754,7 +49904,7 @@ "ru": "Ежедневно", "tr": "Günlük yinelenen", "xloc": [ - "default.handlebars->41->1076" + "default.handlebars->45->1091" ] }, { @@ -49774,7 +49924,7 @@ "ru": "Еженедельно", "tr": "Haftalık yinelenen", "xloc": [ - "default.handlebars->41->1077" + "default.handlebars->45->1092" ] }, { @@ -49822,11 +49972,20 @@ "xloc": [ "default-mobile.handlebars->11->152", "default-mobile.handlebars->11->481", - "default.handlebars->41->1359", - "default.handlebars->41->2181", + "default.handlebars->45->1374", + "default.handlebars->45->2196", "sharing.handlebars->11->60" ] }, + { + "en": "Redirection port or KVM feature is disabled", + "nl": "Omleidingspoort of KVM functie is uitgeschakeld", + "pl": "Pzekierowania portu lub funkcja KVM są wyłączone", + "xloc": [ + "default.handlebars->container->column_l->p11->p11warning->3", + "default.handlebars->container->column_l->p12->p12warning->3" + ] + }, { "cs": "Šíření dál a použití ve formě zdrojových kódů nebo zkompilované binární podobě, ať už tak jak je, nebo s úpravami, je povoleno za předpokladu, že jsou splněny následující podmínky:", "da": "Omfordeling og brug i kilde- og binære former, med eller uden ændringer, er tilladt, forudsat at følgende betingelser er opfyldt:", @@ -49879,7 +50038,7 @@ "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->3", "default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->3", - "default.handlebars->41->759", + "default.handlebars->45->767", "default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsAreaTop->DeskToolsRefreshButton", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p40->3->3", @@ -49960,10 +50119,10 @@ "zh-cht": "中繼", "xloc": [ "default-mobile.handlebars->11->259", - "default.handlebars->41->2932", - "default.handlebars->41->382", - "default.handlebars->41->386", - "default.handlebars->41->634" + "default.handlebars->45->2947", + "default.handlebars->45->383", + "default.handlebars->45->387", + "default.handlebars->45->637" ] }, { @@ -49988,13 +50147,13 @@ "zh-chs": "中继数量", "zh-cht": "中繼數量", "xloc": [ - "default.handlebars->41->2917" + "default.handlebars->45->2932" ] }, { "cs": "Reléové zařízení", "da": "Relay enhed", - "de": "Relaisgerät", + "de": "Relay-Gerät", "en": "Relay Device", "es": "Dispositivo de Retransmisión", "fi": "Relelaite", @@ -50014,9 +50173,9 @@ "xloc": [ "default-mobile.handlebars->11->632", "default-mobile.handlebars->11->648", - "default.handlebars->41->1800", - "default.handlebars->41->1862", - "default.handlebars->41->1989" + "default.handlebars->45->1815", + "default.handlebars->45->1877", + "default.handlebars->45->2004" ] }, { @@ -50041,13 +50200,13 @@ "zh-chs": "中继错误", "zh-cht": "中繼錯誤", "xloc": [ - "default.handlebars->41->2910" + "default.handlebars->45->2925" ] }, { "cs": "Reléové mapování", "da": "Relay Mapping", - "de": "Relaiszuordnung", + "de": "Relay-Zuordnung", "en": "Relay Mapping", "es": "Mapeo de Relés", "fi": "Relekartoitus", @@ -50087,8 +50246,8 @@ "zh-chs": "中继连接", "zh-cht": "中繼連接", "xloc": [ - "default.handlebars->41->2916", - "default.handlebars->41->2944" + "default.handlebars->45->2931", + "default.handlebars->45->2959" ] }, { @@ -50096,8 +50255,9 @@ "nl": "Doorstuur apparaat", "pl": "Bramka przekierowująca", "ru": "Устройство-ретранслятор", + "fr": "Appareil relais", "xloc": [ - "default.handlebars->41->2356" + "default.handlebars->45->2371" ] }, { @@ -50105,8 +50265,9 @@ "nl": "Relay voor", "pl": "Przekierowuje dla", "ru": "Ретранслятор для", + "fr": "Relais pour", "xloc": [ - "default.handlebars->41->891" + "default.handlebars->45->899" ] }, { @@ -50137,8 +50298,9 @@ "pl": "Pamiętaj Urządzenie", "pt-br": "Lembrar dispositivo", "ru": "Запомнить устройство", + "fr": "Se souvenir de l'appareil", "xloc": [ - "default.handlebars->41->2838" + "default.handlebars->45->2853" ] }, { @@ -50163,8 +50325,8 @@ "zh-chs": "记住凭据", "xloc": [ "default-mobile.handlebars->11->456", - "default.handlebars->41->1219", - "default.handlebars->41->1316", + "default.handlebars->45->1234", + "default.handlebars->45->1331", "mstsc.handlebars->main->1->3->1->rowremember->3->0", "ssh.handlebars->3->14" ] @@ -50174,9 +50336,10 @@ "nl": "Onthoud wachtwoord", "pl": "Zapamiętaj hasło", "ru": "Запомнить пароль", + "fr": "Se souvenir du mot de passe", "xloc": [ "default-mobile.handlebars->11->461", - "default.handlebars->41->1321", + "default.handlebars->45->1336", "ssh.handlebars->3->19" ] }, @@ -50256,9 +50419,10 @@ "nl": "Onthoud gebruikeruser & sleutel", "pl": "Zapamiętaj użytkownika i klucz", "ru": "Запомнить пользователя и ключ", + "fr": "Se souvenir de l'utilisateur et de la clé", "xloc": [ "default-mobile.handlebars->11->460", - "default.handlebars->41->1320", + "default.handlebars->45->1335", "ssh.handlebars->3->18" ] }, @@ -50381,7 +50545,7 @@ "zh-chs": "远程剪贴板", "zh-cht": "遠程剪貼板", "xloc": [ - "default.handlebars->41->1273" + "default.handlebars->45->1288" ] }, { @@ -50407,7 +50571,7 @@ "zh-cht": "遠程命令", "xloc": [ "default-mobile.handlebars->11->674", - "default.handlebars->41->2048" + "default.handlebars->45->2063" ] }, { @@ -50436,10 +50600,10 @@ "default-mobile.handlebars->11->338", "default-mobile.handlebars->11->661", "default-mobile.handlebars->11->681", - "default.handlebars->41->2033", - "default.handlebars->41->2071", - "default.handlebars->41->909", - "default.handlebars->41->910" + "default.handlebars->45->2048", + "default.handlebars->45->2086", + "default.handlebars->45->917", + "default.handlebars->45->918" ] }, { @@ -50466,8 +50630,8 @@ "xloc": [ "default-mobile.handlebars->11->201", "default-mobile.handlebars->11->208", - "default.handlebars->41->397", - "default.handlebars->41->404" + "default.handlebars->45->400", + "default.handlebars->45->407" ] }, { @@ -50491,7 +50655,7 @@ "tr": "Uzak Masaüstü + Dosya Bağlantısı", "zh-chs": "远程桌面 + 文件链接", "xloc": [ - "default.handlebars->41->292" + "default.handlebars->45->293" ] }, { @@ -50515,7 +50679,7 @@ "tr": "Uzak Masaüstü + Terminal + Dosya Bağlantısı", "zh-chs": "远程桌面 + 终端 + 文件链接", "xloc": [ - "default.handlebars->41->293" + "default.handlebars->45->294" ] }, { @@ -50539,7 +50703,7 @@ "tr": "Uzak Masaüstü + Terminal Bağlantısı", "zh-chs": "远程桌面+终端链接", "xloc": [ - "default.handlebars->41->289" + "default.handlebars->45->290" ] }, { @@ -50564,8 +50728,8 @@ "zh-chs": "远程桌面连接栏已激活/更新", "zh-cht": "遠程桌面連接欄已激活/更新", "xloc": [ - "default.handlebars->41->2227", - "default.handlebars->41->2233" + "default.handlebars->45->2242", + "default.handlebars->45->2248" ] }, { @@ -50590,7 +50754,7 @@ "zh-chs": "远程桌面连接栏失败或不受支持", "zh-cht": "遠程桌面連接欄失敗或不受支持", "xloc": [ - "default.handlebars->41->2228" + "default.handlebars->45->2243" ] }, { @@ -50615,7 +50779,7 @@ "zh-chs": "远程桌面连接栏失败或不受支持", "zh-cht": "遠程桌面連接欄失敗或不受支持", "xloc": [ - "default.handlebars->41->2234" + "default.handlebars->45->2249" ] }, { @@ -50640,9 +50804,9 @@ "zh-chs": "本地用户强行关闭了远程桌面连接", "zh-cht": "本地用戶強行關閉了遠程桌面連接", "xloc": [ - "default.handlebars->41->2225", - "default.handlebars->41->2229", - "default.handlebars->41->2235" + "default.handlebars->45->2240", + "default.handlebars->45->2244", + "default.handlebars->45->2250" ] }, { @@ -50688,7 +50852,7 @@ "zh-chs": "远程桌面连结", "zh-cht": "遠程桌面鏈結", "xloc": [ - "default.handlebars->41->288" + "default.handlebars->45->289" ] }, { @@ -50714,8 +50878,8 @@ "zh-cht": "遠程桌面設置", "xloc": [ "default-mobile.handlebars->11->412", - "default.handlebars->41->1231", - "default.handlebars->41->432", + "default.handlebars->45->1246", + "default.handlebars->45->435", "sharing.handlebars->11->20" ] }, @@ -50824,7 +50988,7 @@ "tr": "Uzak Dosya Bağlantısı", "zh-chs": "远程文件链接", "xloc": [ - "default.handlebars->41->290" + "default.handlebars->45->291" ] }, { @@ -50890,7 +51054,7 @@ "tr": "Uzaktan Giriş Kilidi", "zh-chs": "远程输入锁定", "xloc": [ - "default.handlebars->41->1041" + "default.handlebars->45->1056" ] }, { @@ -50915,7 +51079,7 @@ "zh-chs": "远程键盘输入", "zh-cht": "遠程鍵盤輸入", "xloc": [ - "default.handlebars->41->1269", + "default.handlebars->45->1284", "sharing.handlebars->11->22" ] }, @@ -50986,7 +51150,7 @@ "tr": "Uzak Oturumlar", "zh-chs": "远程会话", "xloc": [ - "default.handlebars->41->2773" + "default.handlebars->45->2788" ] }, { @@ -51052,7 +51216,7 @@ "tr": "Uzak Terminal + Dosya Bağlantısı", "zh-chs": "远程终端 + 文件链接", "xloc": [ - "default.handlebars->41->291" + "default.handlebars->45->292" ] }, { @@ -51077,7 +51241,7 @@ "zh-chs": "远程终端链接", "zh-cht": "遠程終端鏈接", "xloc": [ - "default.handlebars->41->287" + "default.handlebars->45->288" ] }, { @@ -51126,9 +51290,9 @@ "xloc": [ "default-mobile.handlebars->11->662", "default-mobile.handlebars->11->686", - "default.handlebars->41->2034", - "default.handlebars->41->2076", - "default.handlebars->41->2671" + "default.handlebars->45->2049", + "default.handlebars->45->2091", + "default.handlebars->45->2686" ] }, { @@ -51153,7 +51317,7 @@ "zh-chs": "远程剪贴板的有效期为60秒。", "zh-cht": "遠程剪貼板的有效期為60秒。", "xloc": [ - "default.handlebars->41->1272" + "default.handlebars->45->1287" ] }, { @@ -51274,7 +51438,7 @@ "zh-chs": "删除", "zh-cht": "删除", "xloc": [ - "default.handlebars->41->222" + "default.handlebars->45->223" ] }, { @@ -51320,7 +51484,7 @@ "zh-chs": "删除配置", "zh-cht": "刪除配置", "xloc": [ - "default.handlebars->41->1835" + "default.handlebars->45->1850" ] }, { @@ -51389,8 +51553,8 @@ "zh-chs": "删除设备组权限", "zh-cht": "刪除裝置群權限", "xloc": [ - "default.handlebars->41->2563", - "default.handlebars->41->2732" + "default.handlebars->45->2578", + "default.handlebars->45->2747" ] }, { @@ -51415,8 +51579,8 @@ "zh-chs": "删除设备权限", "zh-cht": "刪除裝置權限", "xloc": [ - "default.handlebars->41->2561", - "default.handlebars->41->2719" + "default.handlebars->45->2576", + "default.handlebars->45->2734" ] }, { @@ -51441,7 +51605,7 @@ "zh-chs": "删除设备共享", "zh-cht": "刪除設備共享", "xloc": [ - "default.handlebars->41->2717" + "default.handlebars->45->2732" ] }, { @@ -51465,7 +51629,7 @@ "tr": "Giriş Simgesini Kaldır", "zh-chs": "删除登录令牌", "xloc": [ - "default.handlebars->41->1827" + "default.handlebars->45->1842" ] }, { @@ -51512,7 +51676,7 @@ "zh-chs": "删除用户组成员身份", "zh-cht": "刪除用戶群成員身份", "xloc": [ - "default.handlebars->41->2728" + "default.handlebars->45->2743" ] }, { @@ -51537,8 +51701,8 @@ "zh-chs": "删除用户组权限", "zh-cht": "刪除用戶群權限", "xloc": [ - "default.handlebars->41->2097", - "default.handlebars->41->2724" + "default.handlebars->45->2112", + "default.handlebars->45->2739" ] }, { @@ -51563,7 +51727,7 @@ "zh-chs": "删除用户成员资格", "zh-cht": "刪除用戶成員資格", "xloc": [ - "default.handlebars->41->2571" + "default.handlebars->45->2586" ] }, { @@ -51588,8 +51752,8 @@ "zh-chs": "删除用户权限", "zh-cht": "刪除用戶權限", "xloc": [ - "default.handlebars->41->2095", - "default.handlebars->41->2721" + "default.handlebars->45->2110", + "default.handlebars->45->2736" ] }, { @@ -51614,7 +51778,7 @@ "zh-chs": "删除所有两因素认证。", "zh-cht": "刪除所有二因子鑑別。", "xloc": [ - "default.handlebars->41->2694" + "default.handlebars->45->2709" ] }, { @@ -51639,7 +51803,7 @@ "zh-chs": "删除此用户标识的所有先前事件。", "zh-cht": "刪除此用戶標識的所有先前事件。", "xloc": [ - "default.handlebars->41->2464" + "default.handlebars->45->2479" ] }, { @@ -51664,7 +51828,7 @@ "zh-chs": "断开连接后移除设备", "zh-cht": "斷開連接後删除裝置", "xloc": [ - "default.handlebars->41->2011" + "default.handlebars->45->2026" ] }, { @@ -51689,8 +51853,8 @@ "zh-chs": "删除设备共享", "zh-cht": "刪除設備共享", "xloc": [ - "default.handlebars->41->1923", - "default.handlebars->41->963" + "default.handlebars->45->1938", + "default.handlebars->45->977" ] }, { @@ -51714,7 +51878,7 @@ "tr": "Etkin olmayanı kaldır", "zh-chs": "移除不活跃", "xloc": [ - "default.handlebars->41->1872" + "default.handlebars->45->1887" ] }, { @@ -51738,7 +51902,7 @@ "tr": "Giriş anahtarını kaldır", "zh-chs": "删除登录令牌", "xloc": [ - "default.handlebars->41->1822" + "default.handlebars->45->1837" ] }, { @@ -51763,7 +51927,7 @@ "zh-chs": "删除节点位置", "zh-cht": "刪除節點位置", "xloc": [ - "default.handlebars->41->751" + "default.handlebars->45->759" ] }, { @@ -51789,7 +51953,7 @@ "zh-cht": "刪除電話號碼", "xloc": [ "default-mobile.handlebars->11->95", - "default.handlebars->41->1507" + "default.handlebars->45->1522" ] }, { @@ -51814,7 +51978,7 @@ "zh-chs": "移除标签", "zh-cht": "删除標籤", "xloc": [ - "default.handlebars->41->679" + "default.handlebars->45->682" ] }, { @@ -51839,7 +52003,7 @@ "zh-chs": "删除此设备", "zh-cht": "刪除此裝置", "xloc": [ - "default.handlebars->41->913" + "default.handlebars->45->921" ] }, { @@ -51864,7 +52028,7 @@ "zh-chs": "删除此用户", "zh-cht": "刪除此用戶", "xloc": [ - "default.handlebars->41->2656" + "default.handlebars->45->2671" ] }, { @@ -51889,7 +52053,7 @@ "zh-chs": "删除用户组成员身份", "zh-cht": "刪除用戶群成員身份", "xloc": [ - "default.handlebars->41->2708" + "default.handlebars->45->2723" ] }, { @@ -51914,7 +52078,7 @@ "zh-chs": "删除此设备的用户组权限", "zh-cht": "刪除此裝置的用戶群權限", "xloc": [ - "default.handlebars->41->2555" + "default.handlebars->45->2570" ] }, { @@ -51939,8 +52103,8 @@ "zh-chs": "删除此设备组的用户组权限", "zh-cht": "刪除此裝置群的用戶群權限", "xloc": [ - "default.handlebars->41->2549", - "default.handlebars->41->956" + "default.handlebars->45->2564", + "default.handlebars->45->970" ] }, { @@ -51965,11 +52129,11 @@ "zh-chs": "删除此设备组的用户权限", "zh-cht": "刪除此裝置群的用戶權限", "xloc": [ - "default.handlebars->41->1919", - "default.handlebars->41->2543", - "default.handlebars->41->2702", - "default.handlebars->41->2714", - "default.handlebars->41->957" + "default.handlebars->45->1934", + "default.handlebars->45->2558", + "default.handlebars->45->2717", + "default.handlebars->45->2729", + "default.handlebars->45->971" ] }, { @@ -52010,7 +52174,7 @@ "ru": "Удалено отображаемое имя учетной записи.", "tr": "Hesabın görünen adı kaldırıldı.", "xloc": [ - "default.handlebars->41->2325" + "default.handlebars->45->2340" ] }, { @@ -52035,7 +52199,7 @@ "zh-chs": "删除身份验证应用程序", "zh-cht": "刪除身份驗證應用程序", "xloc": [ - "default.handlebars->41->2287" + "default.handlebars->45->2302" ] }, { @@ -52060,7 +52224,7 @@ "zh-chs": "删除的设备共享{0}", "zh-cht": "刪除的設備共享{0}", "xloc": [ - "default.handlebars->41->2298" + "default.handlebars->45->2313" ] }, { @@ -52085,7 +52249,7 @@ "zh-chs": "从设备组{1}中删除了设备{0}", "zh-cht": "從設備組{1}中刪除了設備{0}", "xloc": [ - "default.handlebars->41->2283" + "default.handlebars->45->2298" ] }, { @@ -52109,7 +52273,7 @@ "tr": "Kaldırılan giriş belirteci", "zh-chs": "删除了登录令牌", "xloc": [ - "default.handlebars->41->2312" + "default.handlebars->45->2327" ] }, { @@ -52134,7 +52298,7 @@ "zh-chs": "已删除用户{0}的电话号码", "zh-cht": "已刪除用戶{0}的電話號碼", "xloc": [ - "default.handlebars->41->2293" + "default.handlebars->45->2308" ] }, { @@ -52158,7 +52322,7 @@ "tr": "Anında iletme bildirimi kimlik doğrulama cihazı kaldırıldı", "zh-chs": "删除了推送通知身份验证设备", "xloc": [ - "default.handlebars->41->2310" + "default.handlebars->45->2325" ] }, { @@ -52183,7 +52347,7 @@ "zh-chs": "移除安全密钥", "zh-cht": "移除安全密鑰", "xloc": [ - "default.handlebars->41->2290" + "default.handlebars->45->2305" ] }, { @@ -52208,9 +52372,9 @@ "zh-chs": "删除了{0}的用户设备权限", "zh-cht": "刪除了{0}的用戶設備權限", "xloc": [ - "default.handlebars->41->2256", - "default.handlebars->41->2277", - "default.handlebars->41->2282" + "default.handlebars->45->2271", + "default.handlebars->45->2292", + "default.handlebars->45->2297" ] }, { @@ -52235,7 +52399,7 @@ "zh-chs": "从设备组{1}中删除了用户组{0}", "zh-cht": "從設備組{1}中刪除了用戶組{0}", "xloc": [ - "default.handlebars->41->2266" + "default.handlebars->45->2281" ] }, { @@ -52260,7 +52424,7 @@ "zh-chs": "从设备组{1}中删除了用户{0}", "zh-cht": "已從設備組{1}中刪除用戶{0}", "xloc": [ - "default.handlebars->41->2279" + "default.handlebars->45->2294" ] }, { @@ -52285,8 +52449,8 @@ "zh-chs": "从用户组{1}中删除了用户{0}", "zh-cht": "從用戶組{1}中刪除了用戶{0}", "xloc": [ - "default.handlebars->41->2258", - "default.handlebars->41->2268" + "default.handlebars->45->2273", + "default.handlebars->45->2283" ] }, { @@ -52315,9 +52479,9 @@ "default-mobile.handlebars->11->485", "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->1", "default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->1", - "default.handlebars->41->1363", - "default.handlebars->41->2185", - "default.handlebars->41->745", + "default.handlebars->45->1378", + "default.handlebars->45->2200", + "default.handlebars->45->753", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3", "default.handlebars->filesContextMenu->1", @@ -52368,7 +52532,7 @@ "zh-chs": "重命名:“{0}”为“{1}”", "zh-cht": "重命名:“{0}”為“{1}”", "xloc": [ - "default.handlebars->41->2244" + "default.handlebars->45->2259" ] }, { @@ -52393,7 +52557,7 @@ "zh-chs": "报告日", "zh-cht": "報告日", "xloc": [ - "default.handlebars->41->2365" + "default.handlebars->45->2380" ] }, { @@ -52418,7 +52582,7 @@ "zh-chs": "报告类型", "zh-cht": "報告類型", "xloc": [ - "default.handlebars->41->2360" + "default.handlebars->45->2375" ] }, { @@ -52438,7 +52602,7 @@ "ru": "Отчет не вернул данных", "tr": "Rapor hiçbir bütün döndürmedi.", "xloc": [ - "default.handlebars->41->2809" + "default.handlebars->45->2824" ] }, { @@ -52460,7 +52624,7 @@ "sv": "Report.csv", "tr": "Report.csv", "xloc": [ - "default.handlebars->41->2851" + "default.handlebars->45->2866" ] }, { @@ -52594,7 +52758,7 @@ "tr": "Ayrıntılar isteniyor...", "zh-chs": "查询详情...", "xloc": [ - "default.handlebars->41->1276" + "default.handlebars->45->1291" ] }, { @@ -52619,7 +52783,7 @@ "zh-chs": "要求:", "zh-cht": "要求:", "xloc": [ - "default.handlebars->41->1783" + "default.handlebars->45->1798" ] }, { @@ -52645,8 +52809,8 @@ "zh-cht": "要求:{0}。", "xloc": [ "default-mobile.handlebars->11->120", - "default.handlebars->41->2469", - "default.handlebars->41->2692" + "default.handlebars->45->2484", + "default.handlebars->45->2707" ] }, { @@ -52671,7 +52835,7 @@ "zh-chs": "需要安装MeshCentral路由器", "zh-cht": "需要安裝MeshCentral路由器", "xloc": [ - "default.handlebars->41->923" + "default.handlebars->45->933" ] }, { @@ -52696,9 +52860,9 @@ "zh-chs": "需要安装MeshCentral Router。", "zh-cht": "需要安裝MeshCentral Router。", "xloc": [ - "default.handlebars->41->925", - "default.handlebars->41->927", - "default.handlebars->41->929" + "default.handlebars->45->935", + "default.handlebars->45->937", + "default.handlebars->45->939" ] }, { @@ -52751,7 +52915,7 @@ "zh-cht": "重設", "xloc": [ "default-mobile.handlebars->11->366", - "default.handlebars->41->1098", + "default.handlebars->45->1113", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devMapToolbar" ] }, @@ -52778,7 +52942,7 @@ "zh-cht": "重置/關閉電源", "xloc": [ "default-mobile.handlebars->11->675", - "default.handlebars->41->2049" + "default.handlebars->45->2064" ] }, { @@ -52884,7 +53048,7 @@ "zh-chs": "重置设备", "zh-cht": "重置裝置", "xloc": [ - "default.handlebars->41->646" + "default.handlebars->45->649" ] }, { @@ -52935,9 +53099,9 @@ "zh-cht": "重置/關閉", "xloc": [ "default-mobile.handlebars->11->695", - "default.handlebars->41->1010", - "default.handlebars->41->1032", - "default.handlebars->41->2086" + "default.handlebars->45->1024", + "default.handlebars->45->1046", + "default.handlebars->45->2101" ] }, { @@ -52962,7 +53126,7 @@ "zh-chs": "重新启动", "zh-cht": "重新啟動", "xloc": [ - "default.handlebars->41->1294", + "default.handlebars->45->1309", "player.handlebars->p11->deskarea0->deskarea4->3" ] }, @@ -52988,7 +53152,7 @@ "zh-chs": "还原服务器", "zh-cht": "還原伺服器", "xloc": [ - "default.handlebars->41->1840" + "default.handlebars->45->1855" ] }, { @@ -53038,7 +53202,7 @@ "zh-chs": "使用备份还原服务器,这将删除现有服务器数据。仅当您知道自己在做什么时才这样做。", "zh-cht": "使用備份還原伺服器,這將刪除現有伺服器數據。僅當你知道自己在做什麼時才這樣做。", "xloc": [ - "default.handlebars->41->1837" + "default.handlebars->45->1852" ] }, { @@ -53064,8 +53228,8 @@ "zh-cht": "受限制的", "xloc": [ "default-mobile.handlebars->11->288", - "default.handlebars->41->799", - "default.handlebars->41->939" + "default.handlebars->45->807", + "default.handlebars->45->949" ] }, { @@ -53090,7 +53254,17 @@ "zh-chs": "限制条件", "zh-cht": "限制條件", "xloc": [ - "default.handlebars->41->2583" + "default.handlebars->45->2598" + ] + }, + { + "en": "Reverse Mouse Wheel", + "nl": "Muiswiel actie omgekeerd", + "pl": "Odwróć Zachowanie Rolki Myszy", + "xloc": [ + "default.handlebars->container->dialog->dialogBody->dialog7->d7amtkvm->5->d7otherset->7", + "default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->d7desktopOtherSettings->d7otherset2->3", + "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->21" ] }, { @@ -53115,7 +53289,7 @@ "zh-chs": "雷托-罗曼语", "zh-cht": "雷托-羅曼語", "xloc": [ - "default.handlebars->41->1671" + "default.handlebars->45->1686" ] }, { @@ -53140,7 +53314,7 @@ "zh-chs": "正确的", "xloc": [ "default-mobile.handlebars->11->427", - "default.handlebars->41->1249" + "default.handlebars->45->1264" ] }, { @@ -53165,7 +53339,7 @@ "zh-chs": "罗马尼亚文", "zh-cht": "羅馬尼亞文", "xloc": [ - "default.handlebars->41->1672" + "default.handlebars->45->1687" ] }, { @@ -53190,7 +53364,7 @@ "zh-chs": "罗马尼亚文(摩尔达维亚)", "zh-cht": "羅馬尼亞文(摩爾達維亞)", "xloc": [ - "default.handlebars->41->1673" + "default.handlebars->45->1688" ] }, { @@ -53217,8 +53391,8 @@ "xloc": [ "default-mobile.handlebars->11->138", "default-mobile.handlebars->11->474", - "default.handlebars->41->1347", - "default.handlebars->41->2153", + "default.handlebars->45->1362", + "default.handlebars->45->2168", "sharing.handlebars->11->49" ] }, @@ -53366,7 +53540,7 @@ "zh-chs": "路由器", "zh-cht": "路由器", "xloc": [ - "default.handlebars->41->360" + "default.handlebars->45->361" ] }, { @@ -53433,9 +53607,9 @@ "zh-chs": "运行命令", "zh-cht": "運行命令", "xloc": [ - "default.handlebars->41->1096", - "default.handlebars->41->1116", - "default.handlebars->41->674" + "default.handlebars->45->1111", + "default.handlebars->45->1131", + "default.handlebars->45->677" ] }, { @@ -53460,7 +53634,7 @@ "zh-chs": "运行MeshCentral Router,然后单击“安装”以使其可从浏览器启动。", "zh-cht": "運行MeshCentral Router,然後單擊“安裝”以使其可從瀏覽器啟動。", "xloc": [ - "default.handlebars->41->1158" + "default.handlebars->45->1173" ] }, { @@ -53485,8 +53659,8 @@ "zh-chs": "以代理身份运行", "zh-cht": "以代理身份運行", "xloc": [ - "default.handlebars->41->1113", - "default.handlebars->41->671" + "default.handlebars->45->1128", + "default.handlebars->45->674" ] }, { @@ -53511,8 +53685,8 @@ "zh-chs": "以用户身份运行,如果没有用户,则运行代理", "zh-cht": "以用戶身份運行,如果沒有用戶,則運行代理", "xloc": [ - "default.handlebars->41->1114", - "default.handlebars->41->672" + "default.handlebars->45->1129", + "default.handlebars->45->675" ] }, { @@ -53537,7 +53711,7 @@ "zh-chs": "运行命令", "zh-cht": "運行命令", "xloc": [ - "default.handlebars->41->648" + "default.handlebars->45->651" ] }, { @@ -53562,8 +53736,8 @@ "zh-chs": "在所选设备上运行命令。", "zh-cht": "在所選裝置上運行命令。", "xloc": [ - "default.handlebars->41->1109", - "default.handlebars->41->667" + "default.handlebars->45->1124", + "default.handlebars->45->670" ] }, { @@ -53605,8 +53779,8 @@ "ru": "Запущен", "tr": "Koşma", "xloc": [ - "default.handlebars->41->1278", - "default.handlebars->41->1282" + "default.handlebars->45->1293", + "default.handlebars->45->1297" ] }, { @@ -53631,7 +53805,7 @@ "zh-chs": "运行命令", "zh-cht": "運行命令", "xloc": [ - "default.handlebars->41->2220" + "default.handlebars->45->2235" ] }, { @@ -53656,7 +53830,7 @@ "zh-chs": "以用户身份运行命令", "zh-cht": "以用戶身份運行命令", "xloc": [ - "default.handlebars->41->2295" + "default.handlebars->45->2310" ] }, { @@ -53681,7 +53855,7 @@ "zh-chs": "如果可能,以用户身份运行命令", "zh-cht": "如果可能,以用戶身份運行命令", "xloc": [ - "default.handlebars->41->2296" + "default.handlebars->45->2311" ] }, { @@ -53706,7 +53880,7 @@ "zh-chs": "俄文", "zh-cht": "俄文", "xloc": [ - "default.handlebars->41->1674" + "default.handlebars->45->1689" ] }, { @@ -53731,13 +53905,13 @@ "zh-chs": "俄文(摩尔达维亚)", "zh-cht": "俄文(摩爾達維亞)", "xloc": [ - "default.handlebars->41->1675" + "default.handlebars->45->1690" ] }, { "cs": "S & ettings ...", "da": "S&ettings...", - "de": "Die Einstellungen...", + "de": "Einstellungen...", "en": "S&ettings...", "es": "A&justes...", "fi": "Asetukset...", @@ -53797,8 +53971,8 @@ "tr": "SCP", "zh-chs": "SCP", "xloc": [ - "default.handlebars->41->393", - "default.handlebars->41->928" + "default.handlebars->45->396", + "default.handlebars->45->938" ] }, { @@ -53816,6 +53990,7 @@ "nl": "SFTP verbinding", "pl": "Połącz z SFTP", "ru": "Подключиться по SFTP", + "fr": "Connexion SFTP", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->0->1->3", "default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3" @@ -53843,8 +54018,8 @@ "zh-chs": "短信", "zh-cht": "短信", "xloc": [ - "default.handlebars->41->2643", - "default.handlebars->41->2648", + "default.handlebars->45->2658", + "default.handlebars->45->2663", "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->tokenpanel->1->7->1->4->1->3", "login.handlebars->container->column_l->centralTable->1->0->logincell->resettokenpanel->1->5->1->2->1->3", "login.handlebars->container->column_l->centralTable->1->0->logincell->tokenpanel->1->7->1->4->1->3", @@ -53874,7 +54049,7 @@ "zh-chs": "此用户的短信功能电话号码。", "zh-cht": "此用戶的短信功能電話號碼。", "xloc": [ - "default.handlebars->41->2664" + "default.handlebars->45->2679" ] }, { @@ -53899,7 +54074,7 @@ "zh-chs": "短信错误", "xloc": [ "default-mobile.handlebars->11->741", - "default.handlebars->41->2889" + "default.handlebars->45->2904" ] }, { @@ -53924,7 +54099,7 @@ "zh-chs": "短信错误:{0}", "xloc": [ "default-mobile.handlebars->11->742", - "default.handlebars->41->2890" + "default.handlebars->45->2905" ] }, { @@ -53944,7 +54119,7 @@ "ru": "SMS-шлюз имеет ограниченное применение в LAN режиме.", "tr": "SMS ağ geçidinin LAN modunda sınırlı kullanımı vardır.", "xloc": [ - "default.handlebars->41->101" + "default.handlebars->45->101" ] }, { @@ -53969,7 +54144,7 @@ "zh-chs": "短信网关未启用", "xloc": [ "default-mobile.handlebars->11->736", - "default.handlebars->41->2884" + "default.handlebars->45->2899" ] }, { @@ -53978,8 +54153,9 @@ "pl": "Wiadomość SMS", "pt-br": "Mensagem SMS", "ru": "SMS-сообщение", + "fr": "Message SMS", "xloc": [ - "default.handlebars->41->2834" + "default.handlebars->45->2849" ] }, { @@ -54052,7 +54228,7 @@ "zh-chs": "短信发送成功。", "xloc": [ "default-mobile.handlebars->11->740", - "default.handlebars->41->2888" + "default.handlebars->45->2903" ] }, { @@ -54072,7 +54248,7 @@ "ru": "SMTP-сервер имеет ограниченное применение в LAN режиме.", "tr": "SMTP sunucusunun LAN modunda sınırlı kullanımı vardır.", "xloc": [ - "default.handlebars->41->100" + "default.handlebars->45->100" ] }, { @@ -54096,8 +54272,8 @@ "tr": "SSH", "zh-chs": "SSH", "xloc": [ - "default.handlebars->41->392", - "default.handlebars->41->926" + "default.handlebars->45->395", + "default.handlebars->45->936" ] }, { @@ -54105,6 +54281,7 @@ "nl": "SSH verbinding", "pl": "Połącz z SSH", "ru": "Подключиться по SSH", + "fr": "Connexion SSH", "xloc": [ "default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea1->1->3->connectbutton2sspan", "default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->connectbutton2sspan" @@ -54132,7 +54309,7 @@ "zh-chs": "SSH 连接", "xloc": [ "default-mobile.handlebars->11->445", - "default.handlebars->41->742" + "default.handlebars->45->746" ] }, { @@ -54158,8 +54335,8 @@ "xloc": [ "default-mobile.handlebars->11->443", "default-mobile.handlebars->11->479", - "default.handlebars->41->1302", - "default.handlebars->41->1357" + "default.handlebars->45->1317", + "default.handlebars->45->1372" ] }, { @@ -54205,7 +54382,7 @@ "zh-chs": "SSH远程连接端口:", "xloc": [ "default-mobile.handlebars->11->444", - "default.handlebars->41->741" + "default.handlebars->45->745" ] }, { @@ -54234,11 +54411,12 @@ "nl": "SSH-gebruiker+sleutel", "pl": "SSH-Uużytkownik+Klucz", "ru": "SSH-Пользователь+Ключ", + "fr": "SSH-Utilisateur+Clé", "xloc": [ "default-mobile.handlebars->11->324", "default-mobile.handlebars->11->328", - "default.handlebars->41->883", - "default.handlebars->41->887" + "default.handlebars->45->891", + "default.handlebars->45->895" ] }, { @@ -54246,11 +54424,12 @@ "nl": "SSH-gebruiker+sleutel+wachtwoord", "pl": "SSH-Uużytkownik+Klucz+Hasło", "ru": "SSH-Пользователь+Ключ+Пароль", + "fr": "SSH-Utlisateur+Clé+Mot de passe", "xloc": [ "default-mobile.handlebars->11->323", "default-mobile.handlebars->11->327", - "default.handlebars->41->882", - "default.handlebars->41->886" + "default.handlebars->45->890", + "default.handlebars->45->894" ] }, { @@ -54258,43 +54437,52 @@ "nl": "SSH-gebruiker+wachtwoord", "pl": "SSH-Uużytkownik+Hasło", "ru": "SSH-Пользователь+Пароль", + "fr": "SSH - Utilisateur + Mot de passe", "xloc": [ "default-mobile.handlebars->11->322", "default-mobile.handlebars->11->326", - "default.handlebars->41->881", - "default.handlebars->41->885" + "default.handlebars->45->889", + "default.handlebars->45->893" ] }, { "en": "SSL certificate not on server", "nl": "SSL certificaat niet op de server", + "pl": "Certyfikat SSL nie znajduje się na serwerze", "ru": "SSL-сертификат не на сервере", + "fr": "Le certificat SSL n'est pas sur le serveur", "xloc": [ - "default.handlebars->41->1207" + "default.handlebars->45->1222" ] }, { "en": "SSL not allowed by server", "nl": "SSL certificaat niet toegestaan door de server", + "pl": "Certyfikat SSL niedozwolony na serwerze", "ru": "SSL не разрешен сервером", + "fr": "SSL n'est pas autorisé par le serveur", "xloc": [ - "default.handlebars->41->1206" + "default.handlebars->45->1221" ] }, { "en": "SSL required by server", "nl": "SSL vereist door server", + "pl": "Certyfikat SSL wymagany przez serwer", "ru": "SSL требуется сервером", + "fr": "SSL est requis par le serveur", "xloc": [ - "default.handlebars->41->1205" + "default.handlebars->45->1220" ] }, { "en": "SSL with user auth required by server", "nl": "SSL met gebruikersverificatie vereist door de server", + "pl": "Certyfikat SSL z autoryzacją użytkownika wymagane przez serwer", "ru": "SSL с аутентификацией пользователя, требуется сервером", + "fr": "SSL avec une authentification de l'utilisateur est requise par le serveur", "xloc": [ - "default.handlebars->41->1210" + "default.handlebars->45->1225" ] }, { @@ -54319,8 +54507,8 @@ "zh-chs": "与设备名称相同", "zh-cht": "與裝置名稱相同", "xloc": [ - "default.handlebars->41->448", - "default.handlebars->41->457" + "default.handlebars->45->451", + "default.handlebars->45->460" ] }, { @@ -54345,7 +54533,7 @@ "zh-chs": "萨米(拉普兰)", "zh-cht": "薩米(拉普蘭)", "xloc": [ - "default.handlebars->41->1676" + "default.handlebars->45->1691" ] }, { @@ -54370,9 +54558,9 @@ "zh-chs": "IP范围值样本", "zh-cht": "IP範圍值樣本", "xloc": [ - "default.handlebars->41->252", - "default.handlebars->41->256", - "default.handlebars->41->484" + "default.handlebars->45->253", + "default.handlebars->45->257", + "default.handlebars->45->487" ] }, { @@ -54419,7 +54607,7 @@ "zh-chs": "三乡", "zh-cht": "三鄉", "xloc": [ - "default.handlebars->41->1677" + "default.handlebars->45->1692" ] }, { @@ -54444,7 +54632,7 @@ "zh-chs": "梵文", "zh-cht": "梵文", "xloc": [ - "default.handlebars->41->1678" + "default.handlebars->45->1693" ] }, { @@ -54469,7 +54657,7 @@ "zh-chs": "撒丁岛", "zh-cht": "撒丁島", "xloc": [ - "default.handlebars->41->1679" + "default.handlebars->45->1694" ] }, { @@ -54545,7 +54733,7 @@ "zh-chs": "保存节点位置", "zh-cht": "保存節點位置", "xloc": [ - "default.handlebars->41->752" + "default.handlebars->45->760" ] }, { @@ -54619,8 +54807,8 @@ "zh-chs": "扫瞄", "zh-cht": "掃瞄", "xloc": [ - "default.handlebars->41->478", - "default.handlebars->41->480" + "default.handlebars->45->481", + "default.handlebars->45->483" ] }, { @@ -54645,7 +54833,7 @@ "zh-chs": "扫描网络", "zh-cht": "掃描網絡", "xloc": [ - "default.handlebars->41->436" + "default.handlebars->45->439" ] }, { @@ -54670,7 +54858,7 @@ "zh-chs": "扫描英特尔®AMT设备", "zh-cht": "掃描Intel® AMT裝置", "xloc": [ - "default.handlebars->41->483" + "default.handlebars->45->486" ] }, { @@ -54695,7 +54883,7 @@ "zh-chs": "扫描未有任何结果。", "zh-cht": "掃描未有任何結果。", "xloc": [ - "default.handlebars->41->255" + "default.handlebars->45->256" ] }, { @@ -54720,7 +54908,7 @@ "zh-chs": "扫描...", "zh-cht": "掃描...", "xloc": [ - "default.handlebars->41->485" + "default.handlebars->45->488" ] }, { @@ -54778,6 +54966,7 @@ "nl": "Scherm grootte", "pl": "Jak Całego Ekranu", "ru": "Размер экрана", + "fr": "Taille de l'écran", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize->5" ] @@ -54829,8 +55018,8 @@ "zh-chs": "搜寻", "zh-cht": "搜尋", "xloc": [ - "default.handlebars->41->1351", - "default.handlebars->41->765", + "default.handlebars->45->1366", + "default.handlebars->45->773", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devMapToolbar", "sharing.handlebars->11->53" ] @@ -54902,7 +55091,7 @@ "ru": "Ключ", "tr": "Gizli", "xloc": [ - "default.handlebars->41->202" + "default.handlebars->45->203" ] }, { @@ -54957,8 +55146,8 @@ "zh-chs": "已使用TLS保安", "zh-cht": "已使用TLS保安", "xloc": [ - "default-mobile.handlebars->11->573", - "default.handlebars->41->1455" + "default-mobile.handlebars->11->572", + "default.handlebars->45->1469" ] }, { @@ -54984,12 +55173,12 @@ "zh-cht": "安全", "xloc": [ "default-mobile.handlebars->11->388", - "default-mobile.handlebars->11->572", - "default.handlebars->41->1130", - "default.handlebars->41->1454", - "default.handlebars->41->2151", - "default.handlebars->41->2644", - "default.handlebars->41->461", + "default-mobile.handlebars->11->571", + "default.handlebars->45->1145", + "default.handlebars->45->1468", + "default.handlebars->45->2166", + "default.handlebars->45->2659", + "default.handlebars->45->464", "default.handlebars->container->column_l->p21->p21main->1->1->meshSecurityChartDiv->1" ] }, @@ -55015,7 +55204,7 @@ "zh-chs": "安全密钥", "zh-cht": "安全密鑰", "xloc": [ - "default.handlebars->41->2639" + "default.handlebars->45->2654" ] }, { @@ -55040,7 +55229,7 @@ "zh-chs": "安全警告", "xloc": [ "default-mobile.handlebars->11->710", - "default.handlebars->41->2858" + "default.handlebars->45->2873" ] }, { @@ -55111,13 +55300,13 @@ "zh-chs": "全选", "zh-cht": "全選", "xloc": [ - "default.handlebars->41->1354", - "default.handlebars->41->1356", - "default.handlebars->41->2177", - "default.handlebars->41->2411", - "default.handlebars->41->2497", - "default.handlebars->41->482", - "default.handlebars->41->639", + "default.handlebars->45->1369", + "default.handlebars->45->1371", + "default.handlebars->45->2192", + "default.handlebars->45->2426", + "default.handlebars->45->2512", + "default.handlebars->45->485", + "default.handlebars->45->642", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p4->3->1->0->3->3", @@ -55146,9 +55335,9 @@ "ru": "Выберите дату и время...", "tr": "Tarih ve Saati Seçin...", "xloc": [ - "default.handlebars->41->1080", - "default.handlebars->41->1082", - "default.handlebars->41->2792" + "default.handlebars->45->1095", + "default.handlebars->45->1097", + "default.handlebars->45->2807" ] }, { @@ -55173,11 +55362,11 @@ "zh-chs": "选择无", "zh-cht": "選擇無", "xloc": [ - "default.handlebars->41->1355", - "default.handlebars->41->2176", - "default.handlebars->41->2410", - "default.handlebars->41->2496", - "default.handlebars->41->638", + "default.handlebars->45->1370", + "default.handlebars->45->2191", + "default.handlebars->45->2425", + "default.handlebars->45->2511", + "default.handlebars->45->641", "default.handlebars->meshContextMenu->cxselectnone", "sharing.handlebars->11->57" ] @@ -55203,7 +55392,7 @@ "tr": "Anında iletme bildirimi kimlik doğrulaması için kaydedilecek bir cihaz seçin. Seçildikten sonra, cihaz onay isteyecektir.", "zh-chs": "选择要注册推送通知身份验证的设备。选择后,设备将提示确认。", "xloc": [ - "default.handlebars->41->1523" + "default.handlebars->45->1538" ] }, { @@ -55228,7 +55417,7 @@ "zh-chs": "为所选设备选择一个新组", "zh-cht": "為所選裝置選擇一個新群", "xloc": [ - "default.handlebars->41->1144" + "default.handlebars->45->1159" ] }, { @@ -55253,7 +55442,7 @@ "zh-chs": "选择此设备的新组", "zh-cht": "選擇此裝置的新群", "xloc": [ - "default.handlebars->41->1143" + "default.handlebars->45->1158" ] }, { @@ -55278,7 +55467,7 @@ "zh-chs": "选择要放置的节点", "zh-cht": "選擇要放置的節點", "xloc": [ - "default.handlebars->41->768" + "default.handlebars->45->776" ] }, { @@ -55303,7 +55492,7 @@ "zh-chs": "选择要在所有选定设备上执行的操作。仅在拥有适当权限的情况下才能执行操作。", "zh-cht": "選擇要在所有選定裝置上執行的操作。僅在擁有適當權限的情況下才能執行操作。", "xloc": [ - "default.handlebars->41->656" + "default.handlebars->45->659" ] }, { @@ -55328,8 +55517,8 @@ "zh-chs": "选择要对所有选定用户执行的操作。", "zh-cht": "選擇要對所有選定用戶執行的操作。", "xloc": [ - "default.handlebars->41->2414", - "default.handlebars->41->2498" + "default.handlebars->45->2429", + "default.handlebars->45->2513" ] }, { @@ -55355,7 +55544,7 @@ "zh-cht": "選擇要在此裝置上執行的操作。", "xloc": [ "default-mobile.handlebars->11->357", - "default.handlebars->41->1088" + "default.handlebars->45->1103" ] }, { @@ -55380,7 +55569,7 @@ "zh-chs": "选择新密码", "zh-cht": "選擇新密碼", "xloc": [ - "default.handlebars->41->1964" + "default.handlebars->45->1979" ] }, { @@ -55432,7 +55621,7 @@ "zh-cht": "僅自我事件", "xloc": [ "default-mobile.handlebars->11->691", - "default.handlebars->41->2082" + "default.handlebars->45->2097" ] }, { @@ -55507,7 +55696,7 @@ "zh-chs": "发电邮", "zh-cht": "發電郵", "xloc": [ - "default.handlebars->41->2425" + "default.handlebars->45->2440" ] }, { @@ -55532,8 +55721,8 @@ "zh-chs": "发送MQTT消息", "zh-cht": "發送MQTT消息", "xloc": [ - "default.handlebars->41->1100", - "default.handlebars->41->640" + "default.handlebars->45->1115", + "default.handlebars->45->643" ] }, { @@ -55558,7 +55747,7 @@ "zh-chs": "发送MQTT消息", "zh-cht": "發送MQTT消息", "xloc": [ - "default.handlebars->41->1136" + "default.handlebars->45->1151" ] }, { @@ -55583,7 +55772,7 @@ "zh-chs": "发送短信", "zh-cht": "發送簡訊", "xloc": [ - "default.handlebars->41->2423" + "default.handlebars->45->2438" ] }, { @@ -55608,7 +55797,7 @@ "zh-chs": "发送短信给该用户", "zh-cht": "發送短信給該用戶", "xloc": [ - "default.handlebars->41->2649" + "default.handlebars->45->2664" ] }, { @@ -55633,7 +55822,7 @@ "zh-chs": "发送电邮给该用户", "zh-cht": "發送電郵給該用戶", "xloc": [ - "default.handlebars->41->2651" + "default.handlebars->45->2666" ] }, { @@ -55658,7 +55847,7 @@ "zh-chs": "向该组中的所有用户发送通知。", "zh-cht": "向該群中的所有用戶發送通知。", "xloc": [ - "default.handlebars->41->2540" + "default.handlebars->45->2555" ] }, { @@ -55683,7 +55872,7 @@ "zh-chs": "向该用户发送文本通知。", "zh-cht": "向該用戶發送文本通知。", "xloc": [ - "default.handlebars->41->2426" + "default.handlebars->45->2441" ] }, { @@ -55708,7 +55897,7 @@ "zh-chs": "发送电邮给用户", "zh-cht": "發送電郵給用戶", "xloc": [ - "default.handlebars->41->2406" + "default.handlebars->45->2421" ] }, { @@ -55733,7 +55922,7 @@ "zh-chs": "发送安装连结", "zh-cht": "發送安裝鏈結", "xloc": [ - "default.handlebars->41->494" + "default.handlebars->45->497" ] }, { @@ -55758,7 +55947,7 @@ "zh-chs": "发送邀请电邮。", "zh-cht": "發送邀請電郵。", "xloc": [ - "default.handlebars->41->2468" + "default.handlebars->45->2483" ] }, { @@ -55911,7 +56100,7 @@ "zh-chs": "发送用户通知", "zh-cht": "發送用戶通知", "xloc": [ - "default.handlebars->41->2653" + "default.handlebars->45->2668" ] }, { @@ -55931,7 +56120,7 @@ "ru": "Сервер SendGrid имеет ограниченное применение в LAN режиме.", "tr": "SendGrid sunucusunun LAN modunda sınırlı kullanımı vardır.", "xloc": [ - "default.handlebars->41->99" + "default.handlebars->45->99" ] }, { @@ -56004,7 +56193,7 @@ "zh-chs": "塞尔维亚", "zh-cht": "塞爾維亞", "xloc": [ - "default.handlebars->41->1682" + "default.handlebars->45->1697" ] }, { @@ -56030,7 +56219,7 @@ "zh-cht": "序列號", "xloc": [ "default-mobile.handlebars->11->584", - "default.handlebars->41->1466" + "default.handlebars->45->1481" ] }, { @@ -56076,7 +56265,7 @@ "zh-chs": "服务器备份", "zh-cht": "伺服器備份", "xloc": [ - "default.handlebars->41->2478" + "default.handlebars->45->2493" ] }, { @@ -56101,7 +56290,7 @@ "zh-chs": "服务器证书", "zh-cht": "伺服器憑證", "xloc": [ - "default.handlebars->41->2965" + "default.handlebars->45->2980" ] }, { @@ -56125,7 +56314,7 @@ "tr": "Sunucu Bağlantısı", "zh-chs": "服务器连接", "xloc": [ - "default.handlebars->41->327" + "default.handlebars->45->328" ] }, { @@ -56150,7 +56339,7 @@ "zh-chs": "服务器数据库", "zh-cht": "伺服器數據庫", "xloc": [ - "default.handlebars->41->2966" + "default.handlebars->45->2981" ] }, { @@ -56177,11 +56366,11 @@ "xloc": [ "default-mobile.handlebars->11->668", "default-mobile.handlebars->11->683", - "default.handlebars->41->1003", - "default.handlebars->41->1025", - "default.handlebars->41->2042", - "default.handlebars->41->2073", - "default.handlebars->41->2475" + "default.handlebars->45->1017", + "default.handlebars->45->1039", + "default.handlebars->45->2057", + "default.handlebars->45->2088", + "default.handlebars->45->2490" ] }, { @@ -56231,7 +56420,7 @@ "zh-chs": "服务器限制", "xloc": [ "default-mobile.handlebars->11->709", - "default.handlebars->41->2857" + "default.handlebars->45->2872" ] }, { @@ -56280,8 +56469,8 @@ "zh-chs": "服务器权限", "zh-cht": "伺服器權限", "xloc": [ - "default.handlebars->41->2398", - "default.handlebars->41->2490" + "default.handlebars->45->2413", + "default.handlebars->45->2505" ] }, { @@ -56306,7 +56495,7 @@ "zh-chs": "服务器配额", "zh-cht": "伺服器配額", "xloc": [ - "default.handlebars->41->2613" + "default.handlebars->45->2628" ] }, { @@ -56331,7 +56520,7 @@ "zh-chs": "服务器还原", "zh-cht": "伺服器還原", "xloc": [ - "default.handlebars->41->2479" + "default.handlebars->45->2494" ] }, { @@ -56356,7 +56545,7 @@ "zh-chs": "服务器权限", "zh-cht": "伺服器權限", "xloc": [ - "default.handlebars->41->2612" + "default.handlebars->45->2627" ] }, { @@ -56381,7 +56570,7 @@ "zh-chs": "服务器状态", "zh-cht": "伺服器狀態", "xloc": [ - "default.handlebars->41->2896" + "default.handlebars->45->2911" ] }, { @@ -56431,7 +56620,7 @@ "zh-chs": "服务器跟踪", "zh-cht": "伺服器追蹤", "xloc": [ - "default.handlebars->41->2978" + "default.handlebars->45->2993" ] }, { @@ -56455,7 +56644,7 @@ "tr": "Sunucu İzleme Etkinliği", "zh-chs": "服务器跟踪事件", "xloc": [ - "default.handlebars->41->2957" + "default.handlebars->45->2972" ] }, { @@ -56531,7 +56720,7 @@ "zh-chs": "服务器更新", "zh-cht": "伺服器更新", "xloc": [ - "default.handlebars->41->2480" + "default.handlebars->45->2495" ] }, { @@ -56657,7 +56846,7 @@ "zh-chs": "服务器没有错误日志。", "zh-cht": "伺服器沒有錯誤日誌。", "xloc": [ - "default.handlebars->41->190" + "default.handlebars->45->191" ] }, { @@ -56781,7 +56970,7 @@ "zh-chs": "ServerStats.csv", "zh-cht": "ServerStats.csv", "xloc": [ - "default.handlebars->41->2956" + "default.handlebars->45->2971" ] }, { @@ -56806,7 +56995,7 @@ "zh-chs": "服务详情", "zh-cht": "服務詳情", "xloc": [ - "default.handlebars->41->1295" + "default.handlebars->45->1310" ] }, { @@ -56856,8 +57045,8 @@ "zh-chs": "会话", "zh-cht": "節", "xloc": [ - "default.handlebars->41->2739", - "default.handlebars->41->2797", + "default.handlebars->45->2754", + "default.handlebars->45->2812", "ssh.handlebars->3->24", "ssh.handlebars->3->26" ] @@ -56883,7 +57072,7 @@ "tr": "Oturum kimliği", "zh-chs": "会话 ID", "xloc": [ - "default.handlebars->41->122" + "default.handlebars->45->123" ] }, { @@ -56908,7 +57097,7 @@ "zh-chs": "会话信息", "zh-cht": "會議訊息", "xloc": [ - "default.handlebars->41->1227", + "default.handlebars->45->1242", "sharing.handlebars->11->18" ] }, @@ -56935,8 +57124,8 @@ "xloc": [ "default-mobile.handlebars->11->465", "default-mobile.handlebars->11->472", - "default.handlebars->41->1326", - "default.handlebars->41->1342" + "default.handlebars->45->1341", + "default.handlebars->45->1357" ] }, { @@ -57014,8 +57203,8 @@ "xloc": [ "default-mobile.handlebars->11->466", "default-mobile.handlebars->11->473", - "default.handlebars->41->1327", - "default.handlebars->41->1343" + "default.handlebars->45->1342", + "default.handlebars->45->1358" ] }, { @@ -57086,7 +57275,7 @@ "zh-cht": "節", "xloc": [ "default-mobile.handlebars->11->228", - "default.handlebars->41->424", + "default.handlebars->45->427", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->devListToolbar->DevFilterSelect->7" ] }, @@ -57107,7 +57296,7 @@ "ru": "Установить буфер", "tr": "Panoyu Ayarla", "xloc": [ - "default.handlebars->41->1271" + "default.handlebars->45->1286" ] }, { @@ -57177,7 +57366,7 @@ "zh-chs": "设置标签", "zh-cht": "設置標籤", "xloc": [ - "default.handlebars->41->678" + "default.handlebars->45->681" ] }, { @@ -57202,7 +57391,7 @@ "zh-chs": "设置剪贴板内容,{0}个字节", "zh-cht": "設置剪貼板內容,{0}個字節", "xloc": [ - "default.handlebars->41->2218" + "default.handlebars->45->2233" ] }, { @@ -57253,7 +57442,7 @@ "zh-chs": "设定档案", "zh-cht": "設定檔案", "xloc": [ - "default.handlebars->41->562" + "default.handlebars->45->565" ] }, { @@ -57305,8 +57494,8 @@ "zh-cht": "設定", "xloc": [ "agent-translations.json", - "default.handlebars->41->1909", - "default.handlebars->41->438" + "default.handlebars->45->1924", + "default.handlebars->45->441" ] }, { @@ -57375,7 +57564,7 @@ "zh-chs": "将此服务器设置为自动将备份上传到Google云端硬盘。首先为您的帐户创建并输入Google Drive ClientID和ClientSecret。", "zh-cht": "將此服務器設置為自動將備份上傳到Google雲端硬盤。首先為您的帳戶創建並輸入Google Drive ClientID和ClientSecret。", "xloc": [ - "default.handlebars->41->1828" + "default.handlebars->45->1843" ] }, { @@ -57401,10 +57590,10 @@ "zh-cht": "設定...", "xloc": [ "default-mobile.handlebars->11->3", - "default.handlebars->41->10", - "default.handlebars->41->363", - "default.handlebars->41->366", - "default.handlebars->41->431", + "default.handlebars->45->10", + "default.handlebars->45->364", + "default.handlebars->45->367", + "default.handlebars->45->434", "sharing.handlebars->11->3", "ssh.handlebars->3->3", "xterm.handlebars->9->3" @@ -57432,7 +57621,7 @@ "zh-chs": "共享", "zh-cht": "共享", "xloc": [ - "default.handlebars->41->903" + "default.handlebars->45->911" ] }, { @@ -57457,8 +57646,8 @@ "zh-chs": "共享设备", "zh-cht": "共享裝置", "xloc": [ - "default.handlebars->41->1087", - "default.handlebars->41->295" + "default.handlebars->45->1102", + "default.handlebars->45->296" ] }, { @@ -57528,7 +57717,7 @@ "zh-chs": "共享过程", "zh-cht": "共享過程", "xloc": [ - "default.handlebars->41->1289" + "default.handlebars->45->1304" ] }, { @@ -57552,7 +57741,7 @@ "tr": "Paylaşım", "zh-chs": "分享", "xloc": [ - "default.handlebars->41->2087" + "default.handlebars->45->2102" ] }, { @@ -57650,8 +57839,8 @@ "xloc": [ "default-mobile.handlebars->11->430", "default-mobile.handlebars->11->434", - "default.handlebars->41->1252", - "default.handlebars->41->1256" + "default.handlebars->45->1267", + "default.handlebars->45->1271" ] }, { @@ -57959,7 +58148,7 @@ "zh-cht": "只顯示自己的事件", "xloc": [ "default-mobile.handlebars->11->671", - "default.handlebars->41->2045" + "default.handlebars->45->2060" ] }, { @@ -58000,7 +58189,7 @@ "ru": "Показать трафик", "tr": "Trafiği Göster", "xloc": [ - "default.handlebars->41->2793" + "default.handlebars->45->2808" ] }, { @@ -58025,7 +58214,7 @@ "zh-chs": "显示连接工具栏", "zh-cht": "顯示連接工具欄", "xloc": [ - "default.handlebars->41->2001" + "default.handlebars->45->2016" ] }, { @@ -58075,7 +58264,7 @@ "zh-chs": "显示设备位置信息", "zh-cht": "顯示裝置位置訊息", "xloc": [ - "default.handlebars->41->917" + "default.handlebars->45->925" ] }, { @@ -58100,7 +58289,7 @@ "zh-chs": "显示设备网络接口信息", "zh-cht": "顯示裝置網絡介面訊息", "xloc": [ - "default.handlebars->41->915" + "default.handlebars->45->923" ] }, { @@ -58150,8 +58339,8 @@ "zh-chs": "显示1分钟", "zh-cht": "顯示1分鐘", "xloc": [ - "default.handlebars->41->2429", - "default.handlebars->41->2454" + "default.handlebars->45->2444", + "default.handlebars->45->2469" ] }, { @@ -58176,8 +58365,8 @@ "zh-chs": "显示10秒", "zh-cht": "顯示10秒", "xloc": [ - "default.handlebars->41->2428", - "default.handlebars->41->2453" + "default.handlebars->45->2443", + "default.handlebars->45->2468" ] }, { @@ -58202,8 +58391,8 @@ "zh-chs": "显示5分钟", "zh-cht": "顯示5分鐘", "xloc": [ - "default.handlebars->41->2430", - "default.handlebars->41->2455" + "default.handlebars->45->2445", + "default.handlebars->45->2470" ] }, { @@ -58228,8 +58417,8 @@ "zh-chs": "显示消息,直到被用户拒绝", "zh-cht": "顯示消息,直到被用戶拒絕", "xloc": [ - "default.handlebars->41->2427", - "default.handlebars->41->2452" + "default.handlebars->45->2442", + "default.handlebars->45->2467" ] }, { @@ -58418,6 +58607,7 @@ "nl": "Aanmelden met OpenID Connect", "pl": "Zaloguj używając OpenID Connect", "ru": "Войти с помощью OpenID Connect", + "fr": "Authentification avec OpenID", "xloc": [ "login-mobile.handlebars->container->page_content->column_l->1->1->0->1->loginpanel->1->authStrategies->auth-oidc", "login.handlebars->container->column_l->centralTable->1->0->logincell->loginpanel->1->authStrategies->auth-oidc", @@ -58500,8 +58690,8 @@ "zh-chs": "简单管理员控制模式(ACM)", "zh-cht": "簡單管理員控制模式(ACM)", "xloc": [ - "default.handlebars->41->1900", - "default.handlebars->41->1954" + "default.handlebars->45->1915", + "default.handlebars->45->1969" ] }, { @@ -58526,8 +58716,8 @@ "zh-chs": "简单客户端控制模式(CCM)", "zh-cht": "簡單客戶端控制模式(CCM)", "xloc": [ - "default.handlebars->41->1898", - "default.handlebars->41->1958" + "default.handlebars->45->1913", + "default.handlebars->45->1973" ] }, { @@ -58552,7 +58742,7 @@ "zh-chs": "信地", "zh-cht": "信地", "xloc": [ - "default.handlebars->41->1680" + "default.handlebars->45->1695" ] }, { @@ -58577,7 +58767,7 @@ "zh-chs": "僧伽罗文", "zh-cht": "僧伽羅文", "xloc": [ - "default.handlebars->41->1681" + "default.handlebars->45->1696" ] }, { @@ -58613,8 +58803,9 @@ "pl": "Pojedyncze Logowanie", "pt-br": "Single Sign-on (Login único)", "ru": "Единая точка входа", + "fr": "Authentification unique", "xloc": [ - "default.handlebars->41->2841" + "default.handlebars->45->2856" ] }, { @@ -58660,8 +58851,8 @@ "zh-chs": "尺寸", "zh-cht": "尺寸", "xloc": [ - "default.handlebars->41->2742", - "default.handlebars->41->2763", + "default.handlebars->45->2757", + "default.handlebars->45->2778", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSize" ] }, @@ -58687,7 +58878,7 @@ "zh-chs": "缩放:100%", "zh-cht": "縮放:100%", "xloc": [ - "default.handlebars->41->1384", + "default.handlebars->45->1399", "sharing.handlebars->11->85" ] }, @@ -58713,7 +58904,7 @@ "zh-chs": "缩放:125%", "zh-cht": "縮放:125%", "xloc": [ - "default.handlebars->41->1385", + "default.handlebars->45->1400", "sharing.handlebars->11->86" ] }, @@ -58739,7 +58930,7 @@ "zh-chs": "缩放:150%", "zh-cht": "縮放:150%", "xloc": [ - "default.handlebars->41->1386", + "default.handlebars->45->1401", "sharing.handlebars->11->87" ] }, @@ -58765,7 +58956,7 @@ "zh-chs": "缩放:200%", "zh-cht": "縮放:200%", "xloc": [ - "default.handlebars->41->1387", + "default.handlebars->45->1402", "sharing.handlebars->11->88" ] }, @@ -58795,10 +58986,10 @@ "default-mobile.handlebars->11->232", "default-mobile.handlebars->11->233", "default-mobile.handlebars->11->365", - "default.handlebars->41->1097", - "default.handlebars->41->2", - "default.handlebars->41->3", - "default.handlebars->41->4" + "default.handlebars->45->1112", + "default.handlebars->45->2", + "default.handlebars->45->3", + "default.handlebars->45->4" ] }, { @@ -58823,7 +59014,7 @@ "zh-chs": "把装置休眠", "zh-cht": "把裝置休眠", "xloc": [ - "default.handlebars->41->645" + "default.handlebars->45->648" ] }, { @@ -58850,8 +59041,8 @@ "xloc": [ "default-mobile.handlebars->11->239", "default-mobile.handlebars->11->240", - "default.handlebars->41->602", - "default.handlebars->41->604" + "default.handlebars->45->605", + "default.handlebars->45->607" ] }, { @@ -58876,7 +59067,7 @@ "zh-chs": "斯洛伐克文", "zh-cht": "斯洛伐克文", "xloc": [ - "default.handlebars->41->1683" + "default.handlebars->45->1698" ] }, { @@ -58901,7 +59092,7 @@ "zh-chs": "斯洛文尼亞文", "zh-cht": "斯洛文尼亞文", "xloc": [ - "default.handlebars->41->1684" + "default.handlebars->45->1699" ] }, { @@ -58979,7 +59170,7 @@ "zh-chs": "小焦点", "zh-cht": "小焦點", "xloc": [ - "default.handlebars->41->1234" + "default.handlebars->45->1249" ] }, { @@ -59005,7 +59196,7 @@ "zh-cht": "軟斷開代理", "xloc": [ "default-mobile.handlebars->11->617", - "default.handlebars->41->1500" + "default.handlebars->45->1515" ] }, { @@ -59031,7 +59222,7 @@ "zh-cht": "軟關機", "xloc": [ "default-mobile.handlebars->11->243", - "default.handlebars->41->610" + "default.handlebars->45->613" ] }, { @@ -59081,7 +59272,7 @@ "zh-chs": "索马尼", "zh-cht": "索馬尼", "xloc": [ - "default.handlebars->41->1685" + "default.handlebars->45->1700" ] }, { @@ -59106,7 +59297,7 @@ "zh-chs": "索比亚文", "zh-cht": "索比亞文", "xloc": [ - "default.handlebars->41->1686" + "default.handlebars->45->1701" ] }, { @@ -59337,7 +59528,7 @@ "zh-chs": "西班牙文", "zh-cht": "西班牙文", "xloc": [ - "default.handlebars->41->1687" + "default.handlebars->45->1702" ] }, { @@ -59362,7 +59553,7 @@ "zh-chs": "西班牙文(阿根廷)", "zh-cht": "西班牙文(阿根廷)", "xloc": [ - "default.handlebars->41->1688" + "default.handlebars->45->1703" ] }, { @@ -59387,7 +59578,7 @@ "zh-chs": "西班牙文(玻利维亚)", "zh-cht": "西班牙文(玻利維亞)", "xloc": [ - "default.handlebars->41->1689" + "default.handlebars->45->1704" ] }, { @@ -59412,7 +59603,7 @@ "zh-chs": "西班牙文(智利)", "zh-cht": "西班牙文(智利)", "xloc": [ - "default.handlebars->41->1690" + "default.handlebars->45->1705" ] }, { @@ -59437,7 +59628,7 @@ "zh-chs": "西班牙文(哥伦比亚)", "zh-cht": "西班牙文(哥倫比亞)", "xloc": [ - "default.handlebars->41->1691" + "default.handlebars->45->1706" ] }, { @@ -59462,7 +59653,7 @@ "zh-chs": "西班牙文(哥斯达黎加)", "zh-cht": "西班牙文(哥斯達黎加)", "xloc": [ - "default.handlebars->41->1692" + "default.handlebars->45->1707" ] }, { @@ -59487,7 +59678,7 @@ "zh-chs": "西班牙文(多米尼加共和国)", "zh-cht": "西班牙文(多米尼加共和國)", "xloc": [ - "default.handlebars->41->1693" + "default.handlebars->45->1708" ] }, { @@ -59512,7 +59703,7 @@ "zh-chs": "西班牙文(厄瓜多尔)", "zh-cht": "西班牙文(厄瓜多爾)", "xloc": [ - "default.handlebars->41->1694" + "default.handlebars->45->1709" ] }, { @@ -59537,7 +59728,7 @@ "zh-chs": "西班牙文(萨尔瓦多)", "zh-cht": "西班牙文(薩爾瓦多)", "xloc": [ - "default.handlebars->41->1695" + "default.handlebars->45->1710" ] }, { @@ -59562,7 +59753,7 @@ "zh-chs": "西班牙文(危地马拉)", "zh-cht": "西班牙文(危地馬拉)", "xloc": [ - "default.handlebars->41->1696" + "default.handlebars->45->1711" ] }, { @@ -59587,7 +59778,7 @@ "zh-chs": "西班牙文(洪都拉斯)", "zh-cht": "西班牙文(洪都拉斯)", "xloc": [ - "default.handlebars->41->1697" + "default.handlebars->45->1712" ] }, { @@ -59612,7 +59803,7 @@ "zh-chs": "西班牙文(墨西哥)", "zh-cht": "西班牙文(墨西哥)", "xloc": [ - "default.handlebars->41->1698" + "default.handlebars->45->1713" ] }, { @@ -59637,7 +59828,7 @@ "zh-chs": "西班牙文(尼加拉瓜)", "zh-cht": "西班牙文(尼加拉瓜)", "xloc": [ - "default.handlebars->41->1699" + "default.handlebars->45->1714" ] }, { @@ -59662,7 +59853,7 @@ "zh-chs": "西班牙文(巴拿马)", "zh-cht": "西班牙文(巴拿馬)", "xloc": [ - "default.handlebars->41->1700" + "default.handlebars->45->1715" ] }, { @@ -59687,7 +59878,7 @@ "zh-chs": "西班牙文(巴拉圭)", "zh-cht": "西班牙文(巴拉圭)", "xloc": [ - "default.handlebars->41->1701" + "default.handlebars->45->1716" ] }, { @@ -59712,7 +59903,7 @@ "zh-chs": "西班牙文(秘鲁)", "zh-cht": "西班牙文(秘魯)", "xloc": [ - "default.handlebars->41->1702" + "default.handlebars->45->1717" ] }, { @@ -59737,7 +59928,7 @@ "zh-chs": "西班牙文(波多黎各)", "zh-cht": "西班牙文(波多黎各)", "xloc": [ - "default.handlebars->41->1703" + "default.handlebars->45->1718" ] }, { @@ -59762,7 +59953,7 @@ "zh-chs": "西班牙文(西班牙)", "zh-cht": "西班牙文(西班牙)", "xloc": [ - "default.handlebars->41->1704" + "default.handlebars->45->1719" ] }, { @@ -59787,7 +59978,7 @@ "zh-chs": "西班牙文(乌拉圭)", "zh-cht": "西班牙文(烏拉圭)", "xloc": [ - "default.handlebars->41->1705" + "default.handlebars->45->1720" ] }, { @@ -59812,7 +60003,7 @@ "zh-chs": "西班牙文(委内瑞拉)", "zh-cht": "西班牙文(委內瑞拉)", "xloc": [ - "default.handlebars->41->1706" + "default.handlebars->45->1721" ] }, { @@ -59862,7 +60053,7 @@ "zh-chs": "稳定版", "zh-cht": "穩定版", "xloc": [ - "default.handlebars->41->183" + "default.handlebars->45->184" ] }, { @@ -59912,7 +60103,7 @@ "zh-chs": "开始", "zh-cht": "開始", "xloc": [ - "default.handlebars->41->1292" + "default.handlebars->45->1307" ] }, { @@ -59959,13 +60150,13 @@ "zh-chs": "开始时间", "zh-cht": "開始時間", "xloc": [ - "default.handlebars->41->1081", - "default.handlebars->41->118", - "default.handlebars->41->1224", - "default.handlebars->41->271", - "default.handlebars->41->2740", - "default.handlebars->41->276", - "default.handlebars->41->2765", + "default.handlebars->45->1096", + "default.handlebars->45->119", + "default.handlebars->45->1239", + "default.handlebars->45->272", + "default.handlebars->45->2755", + "default.handlebars->45->277", + "default.handlebars->45->2780", "sharing.handlebars->11->14" ] }, @@ -59991,7 +60182,7 @@ "zh-chs": "首先输入新旧MBEx密码。", "zh-cht": "首先輸入新舊MBEx密碼。", "xloc": [ - "default.handlebars->41->469" + "default.handlebars->45->472" ] }, { @@ -60026,7 +60217,7 @@ "pt-br": "Sessão Web-RDP \\\"{0}\\\" iniciada.", "ru": "Начат сеанс Web-RDP \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->2346" + "default.handlebars->45->2361" ] }, { @@ -60037,7 +60228,7 @@ "pt-br": "Sessão Web-SFTP \\\"{0}\\\" iniciada", "ru": "Начат сеанс Web-SFTP \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->2345" + "default.handlebars->45->2360" ] }, { @@ -60048,7 +60239,7 @@ "pt-br": "Sessão Web-SSH \\\"{0}\\\" iniciada", "ru": "Начат сеанс Web-SSH \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->2344" + "default.handlebars->45->2359" ] }, { @@ -60059,7 +60250,7 @@ "pt-br": "Sessão Web-VNC \\\"{0}\\\" iniciada", "ru": "Начат сеанс Web-VNC \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->2347" + "default.handlebars->45->2362" ] }, { @@ -60084,7 +60275,7 @@ "zh-chs": "开始桌面多重会话", "zh-cht": "啟動桌面多路復用會話", "xloc": [ - "default.handlebars->41->2202" + "default.handlebars->45->2217" ] }, { @@ -60095,7 +60286,7 @@ "pt-br": "Sessão de área de trabalho multiplex \\\"{0}\\\" iniciada", "ru": "Начался сеанс мультиплексирования рабочего стола \\\"{0}\\\"", "xloc": [ - "default.handlebars->41->2341" + "default.handlebars->45->2356" ] }, { @@ -60120,7 +60311,7 @@ "zh-chs": "从{1}到{2}开始了桌面会话“{0}”", "zh-cht": "從{1}到{2}開始了桌面會話“{0}”", "xloc": [ - "default.handlebars->41->2211" + "default.handlebars->45->2226" ] }, { @@ -60145,7 +60336,7 @@ "zh-chs": "从{1}到{2}开始文件管理会话“{0}”", "zh-cht": "從{1}到{2}開始文件管理會話“{0}”", "xloc": [ - "default.handlebars->41->2212" + "default.handlebars->45->2227" ] }, { @@ -60169,13 +60360,13 @@ "tr": "Yerel geçiş oturumu \\\"{0}\\\", {1} - {2} protokolü başlatıldı", "zh-chs": "已启动本地中继会话 \\\"{0}\\\",协议 {1} 到 {2}", "xloc": [ - "default.handlebars->41->2316" + "default.handlebars->45->2331" ] }, { "cs": "Zahájena relace přenosu „{0}“ z {1} na {2}", "da": "Startede relay session \\\"{0}\\\" fra {1} til {2}", - "de": "Relaissitzung \\\"{0}\\\" von {1} bis {2} gestartet", + "de": "Relay-Sitzung \\\"{0}\\\" von {1} bis {2} gestartet", "en": "Started relay session \\\"{0}\\\" from {1} to {2}", "es": "Sesión de retransmisión iniciada \\\"{0}\\\" de {1} a {2}", "fi": "Aloitti välitysistunnon \\\"{0}\\\" välillä {1} - {2}", @@ -60194,7 +60385,7 @@ "zh-chs": "从{1}到{2}开始中继会话“{0}”", "zh-cht": "從{1}到{2}開始中繼會話“{0}”", "xloc": [ - "default.handlebars->41->2209" + "default.handlebars->45->2224" ] }, { @@ -60219,7 +60410,7 @@ "zh-chs": "使用Toast通知启动远程桌面", "zh-cht": "使用Toast通知啟動遠程桌面", "xloc": [ - "default.handlebars->41->2231" + "default.handlebars->45->2246" ] }, { @@ -60244,7 +60435,7 @@ "zh-chs": "启动远程桌面,而无需通知", "zh-cht": "啟動遠程桌面,而無需通知", "xloc": [ - "default.handlebars->41->2232" + "default.handlebars->45->2247" ] }, { @@ -60269,7 +60460,7 @@ "zh-chs": "启动带有Toast通知的远程文件", "zh-cht": "啟動帶有Toast通知的遠程文件", "xloc": [ - "default.handlebars->41->2238" + "default.handlebars->45->2253" ] }, { @@ -60294,7 +60485,7 @@ "zh-chs": "已启动的远程文件,恕不另行通知", "zh-cht": "已啟動的遠程文件,恕不另行通知", "xloc": [ - "default.handlebars->41->2239" + "default.handlebars->45->2254" ] }, { @@ -60319,7 +60510,7 @@ "zh-chs": "从{1}到{2}开始了终端会话“{0}”", "zh-cht": "從{1}到{2}開始了終端會話“{0}”", "xloc": [ - "default.handlebars->41->2210" + "default.handlebars->45->2225" ] }, { @@ -60344,7 +60535,7 @@ "zh-chs": "现在开始", "zh-cht": "現在開始", "xloc": [ - "default.handlebars->41->1074" + "default.handlebars->45->1089" ] }, { @@ -60369,7 +60560,7 @@ "zh-chs": "接受本地用户后启动远程桌面", "zh-cht": "接受本地用戶後啟動遠程桌面", "xloc": [ - "default.handlebars->41->2226" + "default.handlebars->45->2241" ] }, { @@ -60394,7 +60585,7 @@ "zh-chs": "本地用户接受后启动远程文件", "zh-cht": "本地用戶接受後啟動遠程文件", "xloc": [ - "default.handlebars->41->2236" + "default.handlebars->45->2251" ] }, { @@ -60440,7 +60631,7 @@ "zh-chs": "状况", "zh-cht": "狀態", "xloc": [ - "default.handlebars->41->1283", + "default.handlebars->45->1298", "default.handlebars->container->column_l->p11->deskarea0->deskarea3x->DeskTools->deskToolsArea->DeskToolsServiceTab->deskToolsServiceHeader->1" ] }, @@ -60512,8 +60703,8 @@ "zh-chs": "状况", "zh-cht": "狀態", "xloc": [ - "default.handlebars->41->2683", - "default.handlebars->41->2758", + "default.handlebars->45->2698", + "default.handlebars->45->2773", "default.handlebars->container->column_l->p42->p42tbl->1->0->7" ] }, @@ -60539,7 +60730,7 @@ "zh-chs": "停止", "zh-cht": "停止", "xloc": [ - "default.handlebars->41->1293" + "default.handlebars->45->1308" ] }, { @@ -60564,7 +60755,7 @@ "zh-chs": "停止进程", "zh-cht": "停止進程", "xloc": [ - "default.handlebars->41->1274" + "default.handlebars->45->1289" ] }, { @@ -60588,7 +60779,7 @@ "tr": "#{0} \\\"{1}\\\" işlemi durdurulsun mu?", "zh-chs": "停止进程 #{0} \\\"{1}\\\"?", "xloc": [ - "default.handlebars->41->1301" + "default.handlebars->45->1316" ] }, { @@ -60634,8 +60825,8 @@ "tr": "durduruldu", "zh-chs": "停止", "xloc": [ - "default.handlebars->41->1277", - "default.handlebars->41->1281" + "default.handlebars->45->1292", + "default.handlebars->45->1296" ] }, { @@ -60682,7 +60873,7 @@ "zh-cht": "儲存", "xloc": [ "default-mobile.handlebars->11->600", - "default.handlebars->41->1482" + "default.handlebars->45->1497" ] }, { @@ -60732,7 +60923,7 @@ "zh-chs": "超出储存空间", "zh-cht": "超出儲存空間", "xloc": [ - "default.handlebars->41->2157" + "default.handlebars->45->2172" ] }, { @@ -60740,9 +60931,10 @@ "nl": "Opgeslagen sleutel", "pl": "Przechowywany Klucz", "ru": "Сохраненный ключ", + "fr": "Clé enregistrée", "xloc": [ "default-mobile.handlebars->11->448", - "default.handlebars->41->1308", + "default.handlebars->45->1323", "ssh.handlebars->3->6" ] }, @@ -60768,7 +60960,7 @@ "zh-chs": "强", "zh-cht": "強", "xloc": [ - "default.handlebars->41->1811" + "default.handlebars->45->1826" ] }, { @@ -60823,7 +61015,7 @@ "zh-chs": "主题", "zh-cht": "主題", "xloc": [ - "default.handlebars->41->2424" + "default.handlebars->45->2439" ] }, { @@ -60859,8 +61051,8 @@ "pt-br": "Login realizado com sucesso", "ru": "Успешный вход", "xloc": [ - "default.handlebars->41->2827", - "default.handlebars->41->2847" + "default.handlebars->45->2842", + "default.handlebars->45->2862" ] }, { @@ -60885,7 +61077,7 @@ "zh-chs": "成功", "zh-cht": "成功", "xloc": [ - "default.handlebars->41->110" + "default.handlebars->45->111" ] }, { @@ -60960,7 +61152,7 @@ "zh-chs": "苏图", "zh-cht": "蘇圖", "xloc": [ - "default.handlebars->41->1707" + "default.handlebars->45->1722" ] }, { @@ -60985,7 +61177,7 @@ "zh-chs": "斯瓦希里文", "zh-cht": "斯瓦希里文", "xloc": [ - "default.handlebars->41->1708" + "default.handlebars->45->1723" ] }, { @@ -61037,7 +61229,7 @@ "zh-chs": "瑞典文", "zh-cht": "瑞典文", "xloc": [ - "default.handlebars->41->1709" + "default.handlebars->45->1724" ] }, { @@ -61062,7 +61254,7 @@ "zh-chs": "瑞典文(芬兰)", "zh-cht": "瑞典文(芬蘭)", "xloc": [ - "default.handlebars->41->1710" + "default.handlebars->45->1725" ] }, { @@ -61087,7 +61279,7 @@ "zh-chs": "瑞典文(瑞典)", "zh-cht": "瑞典文(瑞典)", "xloc": [ - "default.handlebars->41->1711" + "default.handlebars->45->1726" ] }, { @@ -61109,8 +61301,8 @@ "default-mobile.handlebars->11->254", "default-mobile.handlebars->11->311", "default-mobile.handlebars->11->340", - "default.handlebars->41->372", - "default.handlebars->41->624" + "default.handlebars->45->373", + "default.handlebars->45->627" ] }, { @@ -61135,7 +61327,7 @@ "zh-chs": "将英特尔AMT切换到管理员控制模式(ACM)。", "zh-cht": "將英特爾AMT切換到管理員控制模式(ACM)。", "xloc": [ - "default.handlebars->41->1916" + "default.handlebars->45->1931" ] }, { @@ -61155,8 +61347,8 @@ "ru": "Порт свитча подключен", "tr": "Bağlantı noktasını değiştir", "xloc": [ - "default.handlebars->41->940", - "default.handlebars->41->941" + "default.handlebars->45->950", + "default.handlebars->45->951" ] }, { @@ -61176,7 +61368,7 @@ "ru": "Порт свитча готов к использованию.", "tr": "Anahtar portu kullanıma hazırdır.", "xloc": [ - "default.handlebars->41->371" + "default.handlebars->45->372" ] }, { @@ -61201,7 +61393,7 @@ "zh-chs": "将服务器设备名称同步到主机名称", "zh-cht": "將伺服器裝置名稱同步到主機名稱", "xloc": [ - "default.handlebars->41->2010" + "default.handlebars->45->2025" ] }, { @@ -61221,7 +61413,7 @@ "ru": "Синхронизировать имя устройства сервера с именем порта", "tr": "Sunucu cihaz adını bağlantı noktası adıyla senkronize et", "xloc": [ - "default.handlebars->41->2009" + "default.handlebars->45->2024" ] }, { @@ -61245,7 +61437,7 @@ "tr": "Sistem Tepsisi, Her zaman bağlı", "zh-chs": "系统托盘,始终连接", "xloc": [ - "default.handlebars->41->551" + "default.handlebars->45->554" ] }, { @@ -61269,7 +61461,7 @@ "tr": "Sistem Tepsisi, Kullanıcı isteği üzerine bağlanın", "zh-chs": "系统托盘,根据用户要求连接", "xloc": [ - "default.handlebars->41->550" + "default.handlebars->45->553" ] }, { @@ -61293,7 +61485,7 @@ "tr": "Sistem Tepsisi, Yalnızca Monitör", "zh-chs": "系统托盘,仅显示器", "xloc": [ - "default.handlebars->41->552" + "default.handlebars->45->555" ] }, { @@ -61318,7 +61510,7 @@ "zh-chs": "系统类型", "zh-cht": "系統類型", "xloc": [ - "default.handlebars->41->542" + "default.handlebars->45->545" ] }, { @@ -61387,13 +61579,13 @@ "zh-cht": "TCP路由", "xloc": [ "default-mobile.handlebars->11->220", - "default.handlebars->41->416" + "default.handlebars->45->419" ] }, { "cs": "TCP relé", "da": "TCP-relay", - "de": "TCP-Relais", + "de": "TCP-Relay", "en": "TCP relay", "es": "Relé TCP", "fi": "TCP -rele", @@ -61516,7 +61708,7 @@ "zh-cht": "TLS", "xloc": [ "default-mobile.handlebars->11->299", - "default.handlebars->41->812" + "default.handlebars->45->820" ] }, { @@ -61541,8 +61733,8 @@ "zh-chs": "未设置TLS", "zh-cht": "未設置TLS", "xloc": [ - "default-mobile.handlebars->11->574", - "default.handlebars->41->1456" + "default-mobile.handlebars->11->573", + "default.handlebars->45->1470" ] }, { @@ -61568,8 +61760,8 @@ "zh-cht": "需要TLS加密", "xloc": [ "default-mobile.handlebars->11->390", - "default.handlebars->41->1132", - "default.handlebars->41->463" + "default.handlebars->45->1147", + "default.handlebars->45->466" ] }, { @@ -61596,7 +61788,7 @@ "xloc": [ "default-mobile.handlebars->11->415", "default-mobile.handlebars->dialog->3->dialog3->deskkeys->3", - "default.handlebars->41->1237" + "default.handlebars->45->1252" ] }, { @@ -61621,8 +61813,8 @@ "zh-chs": "标签1,标签2,标签3", "zh-cht": "標籤1,標籤2,標籤3", "xloc": [ - "default.handlebars->41->1195", - "default.handlebars->41->681" + "default.handlebars->45->1210", + "default.handlebars->45->684" ] }, { @@ -61675,10 +61867,10 @@ "default-mobile.handlebars->11->320", "default-mobile.handlebars->11->321", "default-mobile.handlebars->11->403", - "default.handlebars->41->1194", - "default.handlebars->41->680", - "default.handlebars->41->879", - "default.handlebars->41->880", + "default.handlebars->45->1209", + "default.handlebars->45->683", + "default.handlebars->45->887", + "default.handlebars->45->888", "default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSort->sortselect->7" ] }, @@ -61703,7 +61895,7 @@ "tr": "Bu kullanıcı adı ve şifreyi not alın, şifre tekrar gösterilemez.", "zh-chs": "记下这个用户名和密码,密码不能再次显示。", "xloc": [ - "default.handlebars->41->312" + "default.handlebars->45->313" ] }, { @@ -61728,7 +61920,7 @@ "zh-chs": "泰米尔文", "zh-cht": "泰米爾文", "xloc": [ - "default.handlebars->41->1712" + "default.handlebars->45->1727" ] }, { @@ -61753,7 +61945,7 @@ "zh-chs": "塔塔尔族", "zh-cht": "塔塔爾族", "xloc": [ - "default.handlebars->41->1713" + "default.handlebars->45->1728" ] }, { @@ -61778,7 +61970,7 @@ "zh-chs": "泰卢加", "zh-cht": "泰盧加", "xloc": [ - "default.handlebars->41->1714" + "default.handlebars->45->1729" ] }, { @@ -61805,16 +61997,16 @@ "xloc": [ "default-mobile.handlebars->11->212", "default-mobile.handlebars->11->353", - "default.handlebars->41->1050", - "default.handlebars->41->1924", - "default.handlebars->41->2002", - "default.handlebars->41->2752", - "default.handlebars->41->2811", - "default.handlebars->41->2842", - "default.handlebars->41->2933", - "default.handlebars->41->408", - "default.handlebars->41->755", - "default.handlebars->41->964", + "default.handlebars->45->1065", + "default.handlebars->45->1939", + "default.handlebars->45->2017", + "default.handlebars->45->2767", + "default.handlebars->45->2826", + "default.handlebars->45->2857", + "default.handlebars->45->2948", + "default.handlebars->45->411", + "default.handlebars->45->763", + "default.handlebars->45->978", "default.handlebars->container->topbar->1->1->MainSubMenuSpan->MainSubMenu->1->0->MainDevTerminal", "default.handlebars->contextMenu->cxterminal", "sharing.handlebars->LeftSideToolBar" @@ -61841,9 +62033,9 @@ "tr": "Terminal + Dosyalar", "zh-chs": "终端 + 文件", "xloc": [ - "default.handlebars->41->1053", - "default.handlebars->41->1928", - "default.handlebars->41->968" + "default.handlebars->45->1068", + "default.handlebars->45->1943", + "default.handlebars->45->982" ] }, { @@ -61893,10 +62085,10 @@ "zh-chs": "终端通知", "zh-cht": "終端機通知", "xloc": [ - "default.handlebars->41->1880", - "default.handlebars->41->2529", - "default.handlebars->41->2631", - "default.handlebars->41->853" + "default.handlebars->45->1895", + "default.handlebars->45->2544", + "default.handlebars->45->2646", + "default.handlebars->45->861" ] }, { @@ -61921,10 +62113,10 @@ "zh-chs": "终端提示", "zh-cht": "終端機提示", "xloc": [ - "default.handlebars->41->1879", - "default.handlebars->41->2528", - "default.handlebars->41->2630", - "default.handlebars->41->852" + "default.handlebars->45->1894", + "default.handlebars->45->2543", + "default.handlebars->45->2645", + "default.handlebars->45->860" ] }, { @@ -61948,7 +62140,7 @@ "tr": "Terminal Oturumu", "zh-chs": "终端会话", "xloc": [ - "default.handlebars->41->2745" + "default.handlebars->45->2760" ] }, { @@ -62082,7 +62274,7 @@ "zh-chs": "泰国", "zh-cht": "泰國", "xloc": [ - "default.handlebars->41->1715" + "default.handlebars->45->1730" ] }, { @@ -62103,7 +62295,7 @@ "tr": "Cihaz kapalı", "xloc": [ "default-mobile.handlebars->11->253", - "default.handlebars->41->622" + "default.handlebars->45->625" ] }, { @@ -62239,7 +62431,7 @@ "zh-chs": "此计算机所属的设备组的名称", "zh-cht": "此電腦所屬的裝置群的名稱", "xloc": [ - "default.handlebars->41->782" + "default.handlebars->45->790" ] }, { @@ -62264,7 +62456,7 @@ "zh-chs": "此计算机所属的设备组的名称。", "zh-cht": "此電腦所屬的裝置群的名稱。", "xloc": [ - "default.handlebars->41->780" + "default.handlebars->45->788" ] }, { @@ -62289,8 +62481,8 @@ "zh-chs": "此计算机的在操作系统中已设置的名称", "zh-cht": "此電腦在操作系統中已設置的的名稱", "xloc": [ - "default.handlebars->41->783", - "default.handlebars->41->785" + "default.handlebars->45->791", + "default.handlebars->45->793" ] }, { @@ -62316,7 +62508,7 @@ "zh-cht": "目前沒有任何通知", "xloc": [ "default-mobile.handlebars->11->704", - "default.handlebars->41->2852" + "default.handlebars->45->2867" ] }, { @@ -62341,7 +62533,7 @@ "zh-chs": "自上次登录以来,此帐户已有 {0} 次登录尝试失败。", "xloc": [ "default-mobile.handlebars->11->725", - "default.handlebars->41->2873" + "default.handlebars->45->2888" ] }, { @@ -62391,7 +62583,7 @@ "zh-chs": "这些设置可用于连接该设备的MQTT。", "zh-cht": "這些設置可用於連接該裝置的MQTT。", "xloc": [ - "default.handlebars->41->296" + "default.handlebars->45->297" ] }, { @@ -62438,7 +62630,7 @@ "zh-cht": "此帳戶無權建立新的裝置群。", "xloc": [ "default-mobile.handlebars->11->123", - "default.handlebars->41->1786" + "default.handlebars->45->1801" ] }, { @@ -62462,7 +62654,7 @@ "tr": "Bu aracının eski bir sertifika doğrulama mekanizması var, güncellemeyi düşünün.", "zh-chs": "此代理具有过时的证书验证机制,请考虑更新。", "xloc": [ - "default.handlebars->41->2314" + "default.handlebars->45->2329" ] }, { @@ -62486,7 +62678,7 @@ "tr": "Bu aracı güvenli olmayan tüneller kullanıyor, güncellemeyi düşünün.", "zh-chs": "此代理正在使用不安全的隧道,请考虑更新。", "xloc": [ - "default.handlebars->41->2315" + "default.handlebars->45->2330" ] }, { @@ -62511,7 +62703,7 @@ "zh-chs": "这是OS图形用户界面上的可执行档案。您需要'chmod + x meshagent'并运行此档案。", "zh-cht": "這是OS圖形用戶界面上的可執行檔案。你需要'chmod + x meshagent'並運行此檔案。", "xloc": [ - "default.handlebars->41->590" + "default.handlebars->45->593" ] }, { @@ -62557,10 +62749,10 @@ "tr": "Bu bir misafir paylaşım oturumu", "zh-chs": "这是嘉宾分享环节", "xloc": [ - "default.handlebars->41->1395", - "default.handlebars->41->2358", - "default.handlebars->41->2734", - "default.handlebars->41->2735" + "default.handlebars->45->1410", + "default.handlebars->45->2373", + "default.handlebars->45->2749", + "default.handlebars->45->2750" ] }, { @@ -62609,7 +62801,7 @@ "tr": "Bu eski bir aracı sürümüdür, güncellemeyi düşünün.", "zh-chs": "这是一个旧的代理版本,考虑更新。", "xloc": [ - "default.handlebars->41->2313" + "default.handlebars->45->2328" ] }, { @@ -62656,7 +62848,7 @@ "zh-chs": "这是推荐的策略。英特尔®AMT激活和管理是完全自动化的,服务器将尝试最大程度地利用硬件管理。", "zh-cht": "這是推薦的策略。英特爾®AMT激活和管理是完全自動化的,服務器將嘗試最大程度地利用硬件管理。", "xloc": [ - "default.handlebars->41->1983" + "default.handlebars->45->1998" ] }, { @@ -62707,7 +62899,7 @@ "zh-chs": "此政策不会影响采用ACM模式的英特尔®AMT的设备。", "zh-cht": "此政策不會影響採用ACM模式的Intel® AMT的裝置。", "xloc": [ - "default.handlebars->41->1980" + "default.handlebars->45->1995" ] }, { @@ -62831,7 +63023,7 @@ "zh-chs": "这会在此设备的事件日志中添加一个条目。", "zh-cht": "這會在此裝置的事件日誌中增加一個記錄。", "xloc": [ - "default.handlebars->41->1035" + "default.handlebars->45->1049" ] }, { @@ -62878,7 +63070,7 @@ "zh-chs": "这不会从服务器上删除该设备,但是该设备将不再能够连接到服务器。该设备的所有远程访问都将丢失。该设备必须连线,此命令才能起作用。", "zh-cht": "這不會從伺服器上刪除該裝置,但是該裝置將不再能夠連接到伺服器。該裝置的所有遠程訪問都將丟失。該設備必須連線,此命令才能起作用。", "xloc": [ - "default.handlebars->41->1139" + "default.handlebars->45->1154" ] }, { @@ -62903,7 +63095,7 @@ "zh-chs": "这不会从服务器上删除该设备,但是该设备将不再能够连接到服务器。该设备的所有远程访问都将丢失。该设备必须连线,此命令才能起作用。", "zh-cht": "這不會從伺服器上刪除該裝置,但是該裝置將不再能夠連接到伺服器。該裝置的所有遠程訪問都將丟失。該設備必須連線,此命令才能起作用。", "xloc": [ - "default.handlebars->41->1140" + "default.handlebars->45->1155" ] }, { @@ -62928,7 +63120,7 @@ "zh-chs": "蒂格雷", "zh-cht": "蒂格雷", "xloc": [ - "default.handlebars->41->1716" + "default.handlebars->45->1731" ] }, { @@ -62954,9 +63146,9 @@ "zh-cht": "時間", "xloc": [ "default-mobile.handlebars->11->360", - "default.handlebars->41->1091", - "default.handlebars->41->2790", - "default.handlebars->41->2795", + "default.handlebars->45->1106", + "default.handlebars->45->2805", + "default.handlebars->45->2810", "player.handlebars->3->17" ] }, @@ -62982,8 +63174,8 @@ "zh-chs": "时间范围", "zh-cht": "時間範圍", "xloc": [ - "default.handlebars->41->1079", - "default.handlebars->41->2791" + "default.handlebars->45->1094", + "default.handlebars->45->2806" ] }, { @@ -63008,7 +63200,7 @@ "zh-chs": "时间跨度", "zh-cht": "時間跨度", "xloc": [ - "default.handlebars->41->2362" + "default.handlebars->45->2377" ] }, { @@ -63033,8 +63225,8 @@ "zh-chs": "时间范围", "zh-cht": "時間範圍", "xloc": [ - "default.handlebars->41->1075", - "default.handlebars->41->2789" + "default.handlebars->45->1090", + "default.handlebars->45->2804" ] }, { @@ -63060,7 +63252,7 @@ "zh-cht": "超時", "xloc": [ "default-mobile.handlebars->11->409", - "default.handlebars->41->1200", + "default.handlebars->45->1215", "sharing.handlebars->11->31", "sharing.handlebars->11->9" ] @@ -63087,7 +63279,7 @@ "zh-chs": "标题", "zh-cht": "標題", "xloc": [ - "default.handlebars->41->686" + "default.handlebars->45->689" ] }, { @@ -63112,7 +63304,7 @@ "zh-chs": "要将计算机添加到\\\"{0}\\\",请运行以下命令。命令需要root凭证。", "zh-cht": "要將電腦新增到\\\"{0}\\\",請運行以下命令。命令需要root憑據。", "xloc": [ - "default.handlebars->41->564" + "default.handlebars->45->567" ] }, { @@ -63136,7 +63328,7 @@ "tr": "\\\"{0}\\\" grubuna bir mobil cihaz eklemek için MeshAgent uygulamasını indirin ve bu QR kodunu tarayın.", "zh-chs": "要将移动设备添加到组“{0}”,请下载 MeshAgent 应用程序并扫描此二维码。", "xloc": [ - "default.handlebars->41->572" + "default.handlebars->45->575" ] }, { @@ -63227,7 +63419,7 @@ "zh-chs": "要将新计算机添加到设备组“ {0} ”,请下载网状代理并安装该计算机以进行管理。这代理中已嵌入了服务器和设备组信息。", "zh-cht": "要將新電腦新增到裝置群“ {0} ”,請下載mesh agent並安裝該電腦以進行管理。這agent中已嵌入了伺服器和裝置群訊息。", "xloc": [ - "default.handlebars->41->553" + "default.handlebars->45->556" ] }, { @@ -63252,7 +63444,7 @@ "zh-chs": "要将新计算机添加到设备组“ {0} ”,请下载网状代理并安装该计算机以进行管理。该代理安装程序中已嵌入了服务器和设备组讯息。", "zh-cht": "要將新電腦新增到裝置群“ {0} ”,請下載mesh agent並安裝該電腦以進行管理。該代理安裝程序中已嵌入了伺服器和裝置群訊息。", "xloc": [ - "default.handlebars->41->568" + "default.handlebars->45->571" ] }, { @@ -63277,7 +63469,7 @@ "zh-chs": "要删除此帐户,请在下面的两个框中键入帐户密码,然后单击确定。", "zh-cht": "要刪除此帳戶,請在下面的兩個框中鍵入帳戶密碼,然後單擊確定。", "xloc": [ - "default.handlebars->41->1773" + "default.handlebars->45->1788" ] }, { @@ -63402,7 +63594,7 @@ "zh-chs": "要删除网格代理,请下载以下档案,运行并单击“卸载”。", "zh-cht": "要刪除mash agent,請下載以下檔案,運行該檔案,然後單擊“卸載”。", "xloc": [ - "default.handlebars->41->581" + "default.handlebars->45->584" ] }, { @@ -63427,7 +63619,7 @@ "zh-chs": "要删除网格代理,请运行以下命令。需要根凭证。", "zh-cht": "要刪除網格代理,請運行以下命令。需要root憑據。", "xloc": [ - "default.handlebars->41->588" + "default.handlebars->45->591" ] }, { @@ -63517,7 +63709,7 @@ "zh-chs": "吐司通知", "zh-cht": "吐司通知", "xloc": [ - "default.handlebars->41->684" + "default.handlebars->45->687" ] }, { @@ -63603,6 +63795,7 @@ "nl": "geavanceerde opties inschakelen", "pl": "Przełącz ustawienia zaawansowane", "ru": "Переключить дополнительные параметры", + "fr": "Afficher les options avancées", "xloc": [ "default.handlebars->container->dialog->idx_dlgButtonBar->idx_dlgMoreButtons", "default.handlebars->container->dialog->idx_dlgButtonBar->idx_dlgMoreButtons" @@ -63861,7 +64054,7 @@ { "cs": "Žeton", "da": "Token", - "de": "Zeichen", + "de": "Token", "en": "Token", "es": "Token", "fi": "Tunnus", @@ -63907,7 +64100,7 @@ "tr": "Anahtar Adı", "zh-chs": "代币名称", "xloc": [ - "default.handlebars->41->1759" + "default.handlebars->45->1774" ] }, { @@ -63931,7 +64124,7 @@ "tr": "Simge: {0}", "zh-chs": "令牌:{0}", "xloc": [ - "default.handlebars->41->306" + "default.handlebars->45->307" ] }, { @@ -64011,7 +64204,7 @@ "zh-chs": "主题", "zh-cht": "主題", "xloc": [ - "default.handlebars->41->1134" + "default.handlebars->45->1149" ] }, { @@ -64035,7 +64228,7 @@ "tr": "Toplam İşlemci Süresi", "zh-chs": "总处理器时间", "xloc": [ - "default.handlebars->41->126" + "default.handlebars->45->127" ] }, { @@ -64110,7 +64303,7 @@ "zh-chs": "用于通过此服务器连接到设备的流量路由器", "zh-cht": "用於通過此伺服器連接到裝置的流量路由器", "xloc": [ - "default.handlebars->41->919" + "default.handlebars->45->927" ] }, { @@ -64177,7 +64370,7 @@ "zh-chs": "再试一次。", "zh-cht": "再試一次。", "xloc": [ - "default.handlebars->41->213" + "default.handlebars->45->214" ] }, { @@ -64227,7 +64420,7 @@ "zh-chs": "尝试凭据", "xloc": [ "default-mobile.handlebars->11->304", - "default.handlebars->41->817" + "default.handlebars->45->825" ] }, { @@ -64252,7 +64445,7 @@ "zh-chs": "特松加", "zh-cht": "特松加", "xloc": [ - "default.handlebars->41->1717" + "default.handlebars->45->1732" ] }, { @@ -64277,7 +64470,7 @@ "zh-chs": "茨瓦纳", "zh-cht": "茨瓦納", "xloc": [ - "default.handlebars->41->1718" + "default.handlebars->45->1733" ] }, { @@ -64323,7 +64516,7 @@ "zh-chs": "土耳其", "zh-cht": "土耳其", "xloc": [ - "default.handlebars->41->1719" + "default.handlebars->45->1734" ] }, { @@ -64348,7 +64541,7 @@ "zh-chs": "土库曼文", "zh-cht": "土庫曼文", "xloc": [ - "default.handlebars->41->1720" + "default.handlebars->45->1735" ] }, { @@ -64370,8 +64563,8 @@ "xloc": [ "default-mobile.handlebars->11->333", "default-mobile.handlebars->11->334", - "default.handlebars->41->905", - "default.handlebars->41->906" + "default.handlebars->45->913", + "default.handlebars->45->914" ] }, { @@ -64391,7 +64584,7 @@ "ru": "Выключить.", "tr": "Kapat.", "xloc": [ - "default.handlebars->41->2329" + "default.handlebars->45->2344" ] }, { @@ -64413,8 +64606,8 @@ "xloc": [ "default-mobile.handlebars->11->335", "default-mobile.handlebars->11->336", - "default.handlebars->41->907", - "default.handlebars->41->908" + "default.handlebars->45->915", + "default.handlebars->45->916" ] }, { @@ -64434,7 +64627,7 @@ "ru": "Включить.", "tr": "Aç.", "xloc": [ - "default.handlebars->41->2328" + "default.handlebars->45->2343" ] }, { @@ -64459,7 +64652,7 @@ "zh-chs": "两因素身份验证", "zh-cht": "二因子身份驗證", "xloc": [ - "default.handlebars->41->69" + "default.handlebars->45->69" ] }, { @@ -64507,13 +64700,13 @@ "xloc": [ "default-mobile.handlebars->11->129", "default-mobile.handlebars->11->630", - "default.handlebars->41->1056", - "default.handlebars->41->1290", - "default.handlebars->41->1797", - "default.handlebars->41->1860", - "default.handlebars->41->1955", - "default.handlebars->41->2776", - "default.handlebars->41->449", + "default.handlebars->45->1071", + "default.handlebars->45->1305", + "default.handlebars->45->1812", + "default.handlebars->45->1875", + "default.handlebars->45->1970", + "default.handlebars->45->2791", + "default.handlebars->45->452", "default.handlebars->container->column_l->p11->deskarea0->deskarea4->5", "sharing.handlebars->p11->deskarea0->deskarea4->3" ] @@ -64540,7 +64733,7 @@ "zh-chs": "输入密钥名称,选择OTP框,然后按YubiKey™上的按钮。", "zh-cht": "輸入密鑰名稱,選擇OTP框,然後按YubiKey™上的按鈕。", "xloc": [ - "default.handlebars->41->1529" + "default.handlebars->45->1544" ] }, { @@ -64565,7 +64758,7 @@ "zh-chs": "输入要添加的密钥的名称。", "zh-cht": "輸入要新增的密鑰的名稱。", "xloc": [ - "default.handlebars->41->1526" + "default.handlebars->45->1541" ] }, { @@ -64612,13 +64805,13 @@ "zh-cht": "UDP路由", "xloc": [ "default-mobile.handlebars->11->224", - "default.handlebars->41->420" + "default.handlebars->45->423" ] }, { "cs": "UDP relé", "da": "UDP-relay", - "de": "UDP-Relais", + "de": "UDP-Relay", "en": "UDP relay", "es": "Relé UDP", "fi": "UDP -rele", @@ -64658,7 +64851,7 @@ "zh-chs": "UTF8终端", "zh-cht": "UTF8終端", "xloc": [ - "default.handlebars->41->1328", + "default.handlebars->45->1343", "sharing.handlebars->11->33" ] }, @@ -64684,7 +64877,7 @@ "zh-chs": "乌克兰", "zh-cht": "烏克蘭", "xloc": [ - "default.handlebars->41->1721" + "default.handlebars->45->1736" ] }, { @@ -64805,8 +64998,8 @@ "zh-chs": "在验证电子邮件地址之前,无法访问此功能。这是密码恢复所必需的。转到“我的帐户”标签以更改和验证电子邮件地址。", "zh-cht": "在驗證電子郵件地址之前,無法訪問此功能。這是密碼恢復所必需的。轉到“我的帳戶”標籤以更改和驗證電子郵件地址。", "xloc": [ - "default.handlebars->41->1788", - "default.handlebars->41->771" + "default.handlebars->45->1803", + "default.handlebars->45->779" ] }, { @@ -64831,9 +65024,9 @@ "zh-chs": "在启用两因素身份验证之前,无法访问此功能。这是额外的安全性所必需的。转到“我的帐户”标签,然后查看“帐户安全性”部分。", "zh-cht": "在啟用兩因素身份驗證之前,無法訪問此功能。這是額外的安全性所必需的。轉到“我的帳戶”標籤,然後查看“帳戶安全性”部分。", "xloc": [ - "default.handlebars->41->1790", - "default.handlebars->41->2984", - "default.handlebars->41->773" + "default.handlebars->45->1805", + "default.handlebars->45->2999", + "default.handlebars->45->781" ] }, { @@ -64858,7 +65051,7 @@ "zh-chs": "无法在此模式下添加用户", "xloc": [ "default-mobile.handlebars->11->721", - "default.handlebars->41->2869" + "default.handlebars->45->2884" ] }, { @@ -64927,7 +65120,7 @@ "tr": "Ekran yakalanamadı", "zh-chs": "无法捕捉显示", "xloc": [ - "default.handlebars->41->1202" + "default.handlebars->45->1217" ] }, { @@ -64974,7 +65167,7 @@ "zh-cht": "無法連接網絡插座", "xloc": [ "default-mobile.handlebars->11->50", - "default.handlebars->41->67" + "default.handlebars->45->67" ] }, { @@ -65025,7 +65218,7 @@ "tr": "Herhangi bir cihaz içe aktarılamıyor.", "zh-chs": "无法导入任何设备。", "xloc": [ - "default.handlebars->41->1951" + "default.handlebars->45->1966" ] }, { @@ -65045,7 +65238,7 @@ "ru": "Не удалось загрузить список IPv6 адресов доверенных прокси-серверов CloudFlare.", "tr": "CloudFlare güvenilir proxy IPv6 adres listesi yüklenemiyor.", "xloc": [ - "default.handlebars->41->98" + "default.handlebars->45->98" ] }, { @@ -65065,7 +65258,7 @@ "ru": "Не удалось загрузить корневой сертификат Intel AMT TLS для домена по умолчанию.", "tr": "Varsayılan etki alanı için Intel AMT TLS kök sertifikası yüklenemiyor.", "xloc": [ - "default.handlebars->41->87" + "default.handlebars->45->87" ] }, { @@ -65085,7 +65278,7 @@ "ru": "Не удалось загрузить корневой сертификат Intel AMT TLS для домена {0}.", "tr": "{0} alanı için Intel AMT TLS kök sertifikası yüklenemiyor.", "xloc": [ - "default.handlebars->41->88" + "default.handlebars->45->88" ] }, { @@ -65093,9 +65286,10 @@ "nl": "Kan OTPLIB niet laden", "pl": "Nie mogę załadować OTPLIB", "ru": "Не удалось загрузить OTPLIB", + "fr": "Impossible de charger la librairie OTPLIB", "xloc": [ "default-mobile.handlebars->11->65", - "default.handlebars->41->199" + "default.handlebars->45->200" ] }, { @@ -65142,7 +65336,7 @@ "zh-cht": "無法執行身份驗證", "xloc": [ "default-mobile.handlebars->11->49", - "default.handlebars->41->66" + "default.handlebars->45->66" ] }, { @@ -65167,7 +65361,7 @@ "zh-chs": "无法扫描该地址范围。", "zh-cht": "無法掃描該地址範圍。", "xloc": [ - "default.handlebars->41->251" + "default.handlebars->45->252" ] }, { @@ -65238,7 +65432,7 @@ "ru": "Не удалось настроить модуль Let's Encrypt.", "tr": "Let's Encrypt modülü kurulamıyor.", "xloc": [ - "default.handlebars->41->95" + "default.handlebars->45->95" ] }, { @@ -65286,9 +65480,9 @@ "xloc": [ "agent-translations.json", "default-mobile.handlebars->11->693", - "default.handlebars->41->1008", - "default.handlebars->41->1030", - "default.handlebars->41->2084" + "default.handlebars->45->1022", + "default.handlebars->45->1044", + "default.handlebars->45->2099" ] }, { @@ -65314,8 +65508,8 @@ "zh-cht": "卸載代理", "xloc": [ "default-mobile.handlebars->11->673", - "default.handlebars->41->1105", - "default.handlebars->41->643" + "default.handlebars->45->1120", + "default.handlebars->45->646" ] }, { @@ -65340,7 +65534,7 @@ "zh-chs": "卸载代理/删除设备", "zh-cht": "卸載代理/刪除設備", "xloc": [ - "default.handlebars->41->2047" + "default.handlebars->45->2062" ] }, { @@ -65365,7 +65559,7 @@ "zh-chs": "卸载代理", "zh-cht": "卸載代理", "xloc": [ - "default.handlebars->41->1142" + "default.handlebars->45->1157" ] }, { @@ -65394,34 +65588,34 @@ "default-mobile.handlebars->11->37", "default-mobile.handlebars->11->44", "default-mobile.handlebars->11->45", - "default-mobile.handlebars->11->564", - "default-mobile.handlebars->11->571", + "default-mobile.handlebars->11->563", + "default-mobile.handlebars->11->570", "default-mobile.handlebars->11->6", "default-mobile.handlebars->11->631", - "default.handlebars->41->13", - "default.handlebars->41->1446", - "default.handlebars->41->1453", - "default.handlebars->41->178", - "default.handlebars->41->179", - "default.handlebars->41->180", - "default.handlebars->41->182", - "default.handlebars->41->184", - "default.handlebars->41->1843", - "default.handlebars->41->1844", - "default.handlebars->41->1861", - "default.handlebars->41->2727", - "default.handlebars->41->2744", - "default.handlebars->41->2751", - "default.handlebars->41->2821", - "default.handlebars->41->2822", - "default.handlebars->41->2823", - "default.handlebars->41->2824", - "default.handlebars->41->2825", - "default.handlebars->41->2845", - "default.handlebars->41->44", - "default.handlebars->41->51", - "default.handlebars->41->52", - "default.handlebars->41->637" + "default.handlebars->45->13", + "default.handlebars->45->1460", + "default.handlebars->45->1467", + "default.handlebars->45->179", + "default.handlebars->45->180", + "default.handlebars->45->181", + "default.handlebars->45->183", + "default.handlebars->45->185", + "default.handlebars->45->1858", + "default.handlebars->45->1859", + "default.handlebars->45->1876", + "default.handlebars->45->2742", + "default.handlebars->45->2759", + "default.handlebars->45->2766", + "default.handlebars->45->2836", + "default.handlebars->45->2837", + "default.handlebars->45->2838", + "default.handlebars->45->2839", + "default.handlebars->45->2840", + "default.handlebars->45->2860", + "default.handlebars->45->44", + "default.handlebars->45->51", + "default.handlebars->45->52", + "default.handlebars->45->640" ] }, { @@ -65447,7 +65641,7 @@ "zh-cht": "未知#{0}", "xloc": [ "default-mobile.handlebars->11->620", - "default.handlebars->41->1850" + "default.handlebars->45->1865" ] }, { @@ -65472,7 +65666,7 @@ "zh-chs": "未知动作", "zh-cht": "未知動作", "xloc": [ - "default.handlebars->41->2902" + "default.handlebars->45->2917" ] }, { @@ -65497,8 +65691,8 @@ "zh-chs": "未知设备", "zh-cht": "未知裝置", "xloc": [ - "default.handlebars->41->2554", - "default.handlebars->41->2713" + "default.handlebars->45->2569", + "default.handlebars->45->2728" ] }, { @@ -65523,9 +65717,9 @@ "zh-chs": "未知设备组", "zh-cht": "未知裝置群", "xloc": [ - "default.handlebars->41->2548", - "default.handlebars->41->2701", - "default.handlebars->41->2906" + "default.handlebars->45->2563", + "default.handlebars->45->2716", + "default.handlebars->45->2921" ] }, { @@ -65550,7 +65744,7 @@ "zh-chs": "未知群组", "zh-cht": "未知群組", "xloc": [ - "default.handlebars->41->2898" + "default.handlebars->45->2913" ] }, { @@ -65576,7 +65770,7 @@ "zh-cht": "未知狀態", "xloc": [ "default-mobile.handlebars->11->293", - "default.handlebars->41->804" + "default.handlebars->45->812" ] }, { @@ -65596,8 +65790,8 @@ "ru": "Неизвестный пользователь", "tr": "Bilinmeyen kullanıcı", "xloc": [ - "default.handlebars->41->2826", - "default.handlebars->41->2846" + "default.handlebars->45->2841", + "default.handlebars->45->2861" ] }, { @@ -65622,7 +65816,7 @@ "zh-chs": "未知用户组", "zh-cht": "未知用戶群", "xloc": [ - "default.handlebars->41->2707" + "default.handlebars->45->2722" ] }, { @@ -65648,7 +65842,7 @@ "zh-cht": "未知版本和狀態", "xloc": [ "default-mobile.handlebars->11->295", - "default.handlebars->41->806" + "default.handlebars->45->814" ] }, { @@ -65673,7 +65867,7 @@ "zh-chs": "密码未知", "zh-cht": "密碼未知", "xloc": [ - "default.handlebars->41->1971" + "default.handlebars->45->1986" ] }, { @@ -65698,11 +65892,11 @@ "zh-chs": "无限制", "zh-cht": "無限", "xloc": [ - "default.handlebars->41->1072", - "default.handlebars->41->1742", - "default.handlebars->41->264", - "default.handlebars->41->506", - "default.handlebars->41->520" + "default.handlebars->45->1087", + "default.handlebars->45->1757", + "default.handlebars->45->265", + "default.handlebars->45->509", + "default.handlebars->45->523" ] }, { @@ -65727,7 +65921,7 @@ "zh-chs": "解锁帐户", "zh-cht": "解鎖帳戶", "xloc": [ - "default.handlebars->41->2417" + "default.handlebars->45->2432" ] }, { @@ -65751,7 +65945,7 @@ "tr": "Uzak kullanıcının fare ve klavyesinin kilidi açılsın mı?", "zh-chs": "解锁远程用户的鼠标和键盘?", "xloc": [ - "default.handlebars->41->1043" + "default.handlebars->45->1058" ] }, { @@ -65771,7 +65965,7 @@ "ru": "Неизвестный параметр конфигурации \\\"{0}\\\".", "tr": "Tanınmayan yapılandırma seçeneği \\\"{0}\\\".", "xloc": [ - "default.handlebars->41->85" + "default.handlebars->45->85" ] }, { @@ -65824,7 +66018,7 @@ "default-mobile.handlebars->11->426", "default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->2->1->1", "default-mobile.handlebars->container->page_content->column_l->p5->p5myfiles->p5toolbar->1->0->1->1", - "default.handlebars->41->1248", + "default.handlebars->45->1263", "default.handlebars->container->column_l->p13->p13toolbar->1->2->1->3", "default.handlebars->container->column_l->p5->p5toolbar->1->0->p5filehead->3", "default.handlebars->container->dialog->dialogBody->dialog3->d3servermode->d3serveraction", @@ -65853,7 +66047,7 @@ "zh-chs": "最新", "zh-cht": "最新", "xloc": [ - "default.handlebars->41->2989" + "default.handlebars->45->3004" ] }, { @@ -65881,8 +66075,8 @@ "agent-translations.json", "default-mobile.handlebars->11->520", "default-mobile.handlebars->11->522", - "default.handlebars->41->833", - "default.handlebars->41->835" + "default.handlebars->45->841", + "default.handlebars->45->843" ] }, { @@ -65962,11 +66156,11 @@ "default-mobile.handlebars->11->486", "default-mobile.handlebars->11->504", "default-mobile.handlebars->11->507", - "default.handlebars->41->1364", - "default.handlebars->41->1390", - "default.handlebars->41->1393", - "default.handlebars->41->2186", - "default.handlebars->41->2194", + "default.handlebars->45->1379", + "default.handlebars->45->1405", + "default.handlebars->45->1408", + "default.handlebars->45->2201", + "default.handlebars->45->2209", "default.handlebars->container->dialog->dialogBody->dialog3->d3localmode->1", "sharing.handlebars->11->65", "sharing.handlebars->11->89", @@ -65996,7 +66190,7 @@ "zh-cht": "上載mesh agent核心", "xloc": [ "default-mobile.handlebars->11->619", - "default.handlebars->41->1502" + "default.handlebars->45->1517" ] }, { @@ -66022,7 +66216,7 @@ "zh-cht": "上載核心檔案", "xloc": [ "default-mobile.handlebars->11->616", - "default.handlebars->41->1499" + "default.handlebars->45->1514" ] }, { @@ -66048,9 +66242,9 @@ "zh-cht": "上載默認伺服器核心", "xloc": [ "default-mobile.handlebars->11->612", - "default.handlebars->41->1495", - "default.handlebars->41->655", - "default.handlebars->41->699" + "default.handlebars->45->1510", + "default.handlebars->45->658", + "default.handlebars->45->702" ] }, { @@ -66074,7 +66268,7 @@ "tr": "Seçili cihazlara varsayılan sunucu çekirdeği yüklensin mi?", "zh-chs": "在所选设备上上传默认服务器核心?", "xloc": [ - "default.handlebars->41->698" + "default.handlebars->45->701" ] }, { @@ -66099,7 +66293,7 @@ "zh-chs": "上传文件", "zh-cht": "上傳文件", "xloc": [ - "default.handlebars->41->651" + "default.handlebars->45->654" ] }, { @@ -66150,7 +66344,7 @@ "zh-cht": "上傳恢復核心", "xloc": [ "default-mobile.handlebars->11->614", - "default.handlebars->41->1497" + "default.handlebars->45->1512" ] }, { @@ -66175,7 +66369,7 @@ "zh-chs": "将所选文件上传到所有所选设备", "zh-cht": "將所選文件上傳到所有所選設備", "xloc": [ - "default.handlebars->41->688" + "default.handlebars->45->691" ] }, { @@ -66200,7 +66394,7 @@ "zh-chs": "上传小核", "xloc": [ "default-mobile.handlebars->11->615", - "default.handlebars->41->1498" + "default.handlebars->45->1513" ] }, { @@ -66226,8 +66420,8 @@ "zh-cht": "上傳將覆蓋1個檔案。繼續?", "xloc": [ "default-mobile.handlebars->11->505", - "default.handlebars->41->1391", - "default.handlebars->41->2195", + "default.handlebars->45->1406", + "default.handlebars->45->2210", "sharing.handlebars->11->90" ] }, @@ -66254,8 +66448,8 @@ "zh-cht": "上傳將覆蓋{0}個檔案。繼續?", "xloc": [ "default-mobile.handlebars->11->506", - "default.handlebars->41->1392", - "default.handlebars->41->2196", + "default.handlebars->45->1407", + "default.handlebars->45->2211", "sharing.handlebars->11->91" ] }, @@ -66303,7 +66497,7 @@ "zh-chs": "上传:“{0}”", "zh-cht": "上傳:“{0}”", "xloc": [ - "default.handlebars->41->2246" + "default.handlebars->45->2261" ] }, { @@ -66327,7 +66521,7 @@ "tr": "Yükleme: \\\"{0}\\\", Boyut: {1}", "zh-chs": "上传:\\\"{0}\\\",大小:{1}", "xloc": [ - "default.handlebars->41->2301" + "default.handlebars->45->2316" ] }, { @@ -66352,7 +66546,7 @@ "zh-chs": "上索布族", "zh-cht": "上索布族", "xloc": [ - "default.handlebars->41->1722" + "default.handlebars->45->1737" ] }, { @@ -66377,7 +66571,7 @@ "zh-chs": "乌尔都文", "zh-cht": "烏爾都文", "xloc": [ - "default.handlebars->41->1723" + "default.handlebars->45->1738" ] }, { @@ -66401,7 +66595,7 @@ "tr": "kullanım", "zh-chs": "用法", "xloc": [ - "default.handlebars->41->2952" + "default.handlebars->45->2967" ] }, { @@ -66447,7 +66641,7 @@ "zh-chs": "使用远程键盘映射", "zh-cht": "使用遠程鍵盤映射", "xloc": [ - "default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->d7desktopOtherSettings->d7otherset2->3", + "default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->d7desktopOtherSettings->d7otherset2->5", "sharing.handlebars->dialog->dialogBody->dialog7->d7meshkvm->d7desktopOtherSettings->d7otherset2->3" ] }, @@ -66501,7 +66695,7 @@ "tr": "Çıplak metal LAN aktivasyonu için kullanın.", "zh-chs": "用于裸机 LAN 激活。", "xloc": [ - "default.handlebars->41->473" + "default.handlebars->45->476" ] }, { @@ -66525,7 +66719,7 @@ "tr": "Yeni kimlik bilgilerini kullan", "zh-chs": "使用新凭据", "xloc": [ - "default.handlebars->41->1215", + "default.handlebars->45->1230", "mstsc.handlebars->main->1->3->1->dropdowndomain->1->d3coreMode->1" ] }, @@ -66550,7 +66744,7 @@ "tr": "Sunucu kimlik bilgilerini kullan", "zh-chs": "使用服务器凭据", "xloc": [ - "default.handlebars->41->1214", + "default.handlebars->45->1229", "mstsc.handlebars->main->1->3->1->dropdowndomain->1->d3coreMode->0" ] }, @@ -66601,8 +66795,8 @@ "zh-chs": "用过的", "zh-cht": "用過的", "xloc": [ - "default.handlebars->41->2892", - "default.handlebars->41->2894" + "default.handlebars->45->2907", + "default.handlebars->45->2909" ] }, { @@ -66627,17 +66821,17 @@ "zh-chs": "用户", "zh-cht": "用戶", "xloc": [ - "default.handlebars->41->116", - "default.handlebars->41->1920", - "default.handlebars->41->2369", - "default.handlebars->41->2399", - "default.handlebars->41->2544", - "default.handlebars->41->2770", - "default.handlebars->41->2777", - "default.handlebars->41->2781", - "default.handlebars->41->2798", - "default.handlebars->41->350", - "default.handlebars->41->959" + "default.handlebars->45->117", + "default.handlebars->45->1935", + "default.handlebars->45->2384", + "default.handlebars->45->2414", + "default.handlebars->45->2559", + "default.handlebars->45->2785", + "default.handlebars->45->2792", + "default.handlebars->45->2796", + "default.handlebars->45->2813", + "default.handlebars->45->351", + "default.handlebars->45->973" ] }, { @@ -66662,7 +66856,7 @@ "zh-chs": "用户+档案", "zh-cht": "用戶+檔案", "xloc": [ - "default.handlebars->41->2400" + "default.handlebars->45->2415" ] }, { @@ -66687,11 +66881,11 @@ "zh-chs": "用户帐户导入", "zh-cht": "用戶帳戶導入", "xloc": [ - "default.handlebars->41->1950", - "default.handlebars->41->2435", - "default.handlebars->41->2436", - "default.handlebars->41->2438", - "default.handlebars->41->2440" + "default.handlebars->45->1965", + "default.handlebars->45->2450", + "default.handlebars->45->2451", + "default.handlebars->45->2453", + "default.handlebars->45->2455" ] }, { @@ -66716,7 +66910,7 @@ "zh-chs": "用户帐户", "zh-cht": "用戶帳戶", "xloc": [ - "default.handlebars->41->2911" + "default.handlebars->45->2926" ] }, { @@ -66742,8 +66936,8 @@ "zh-cht": "用戶授權", "xloc": [ "default-mobile.handlebars->11->638", - "default.handlebars->41->1918", - "default.handlebars->41->955" + "default.handlebars->45->1933", + "default.handlebars->45->969" ] }, { @@ -66768,12 +66962,12 @@ "zh-chs": "用户同意", "zh-cht": "用戶同意", "xloc": [ - "default.handlebars->41->1084", - "default.handlebars->41->1886", - "default.handlebars->41->2535", - "default.handlebars->41->2637", - "default.handlebars->41->286", - "default.handlebars->41->859" + "default.handlebars->45->1099", + "default.handlebars->45->1901", + "default.handlebars->45->2550", + "default.handlebars->45->2652", + "default.handlebars->45->287", + "default.handlebars->45->867" ] }, { @@ -66798,12 +66992,12 @@ "zh-chs": "用户组", "zh-cht": "用戶群", "xloc": [ - "default.handlebars->41->2022", - "default.handlebars->41->2023", - "default.handlebars->41->2505", - "default.handlebars->41->2709", - "default.handlebars->41->2730", - "default.handlebars->41->958" + "default.handlebars->45->2037", + "default.handlebars->45->2038", + "default.handlebars->45->2520", + "default.handlebars->45->2724", + "default.handlebars->45->2745", + "default.handlebars->45->972" ] }, { @@ -66853,7 +67047,7 @@ "zh-chs": "用户组成员", "zh-cht": "用戶群成員", "xloc": [ - "default.handlebars->41->2706" + "default.handlebars->45->2721" ] }, { @@ -66903,9 +67097,9 @@ "zh-chs": "用户识别码", "zh-cht": "用戶識別碼", "xloc": [ - "default.handlebars->41->2091", - "default.handlebars->41->2591", - "default.handlebars->41->2592" + "default.handlebars->45->2106", + "default.handlebars->45->2606", + "default.handlebars->45->2607" ] }, { @@ -66930,8 +67124,8 @@ "zh-chs": "用户标识符", "zh-cht": "用戶標識符", "xloc": [ - "default.handlebars->41->2020", - "default.handlebars->41->2575" + "default.handlebars->45->2035", + "default.handlebars->45->2590" ] }, { @@ -66955,7 +67149,7 @@ "tr": "Kullanıcı Girişi", "zh-chs": "用户输入", "xloc": [ - "default.handlebars->41->268" + "default.handlebars->45->269" ] }, { @@ -66980,7 +67174,7 @@ "zh-chs": "用户列表输出", "zh-cht": "用戶列表輸出", "xloc": [ - "default.handlebars->41->2447" + "default.handlebars->45->2462" ] }, { @@ -66991,7 +67185,7 @@ "pt-br": "Logins de usuários", "ru": "Входы пользователей", "xloc": [ - "default.handlebars->41->2775" + "default.handlebars->45->2790" ] }, { @@ -67017,7 +67211,7 @@ "zh-cht": "用戶名", "xloc": [ "default-mobile.handlebars->11->697", - "default.handlebars->41->2090" + "default.handlebars->45->2105" ] }, { @@ -67112,7 +67306,7 @@ "tr": "Kullanıcı İşlemci Süresi", "zh-chs": "用户处理器时间", "xloc": [ - "default.handlebars->41->128" + "default.handlebars->45->129" ] }, { @@ -67137,7 +67331,7 @@ "zh-chs": "用户节", "zh-cht": "用戶節", "xloc": [ - "default.handlebars->41->2943" + "default.handlebars->45->2958" ] }, { @@ -67186,7 +67380,7 @@ "ru": "Расход трафика пользователями", "tr": "Kullanıcı Trafiği Kullanımı", "xloc": [ - "default.handlebars->41->2774" + "default.handlebars->45->2789" ] }, { @@ -67286,7 +67480,7 @@ "zh-chs": "用户已存在", "xloc": [ "default-mobile.handlebars->11->720", - "default.handlebars->41->2868" + "default.handlebars->45->2883" ] }, { @@ -67311,8 +67505,8 @@ "zh-chs": "用户浏览器值", "zh-cht": "用戶瀏覽器值", "xloc": [ - "default.handlebars->41->1734", - "default.handlebars->41->1736" + "default.handlebars->45->1749", + "default.handlebars->45->1751" ] }, { @@ -67337,7 +67531,7 @@ "zh-chs": "用户组已更改:{0}", "zh-cht": "用戶組已更改:{0}", "xloc": [ - "default.handlebars->41->2275" + "default.handlebars->45->2290" ] }, { @@ -67362,7 +67556,7 @@ "zh-chs": "已创建用户组:{0}", "zh-cht": "已創建用戶組:{0}", "xloc": [ - "default.handlebars->41->2265" + "default.handlebars->45->2280" ] }, { @@ -67387,7 +67581,7 @@ "zh-chs": "用户组成员身份已更改:{0}", "zh-cht": "用戶組成員身份已更改:{0}", "xloc": [ - "default.handlebars->41->2263" + "default.handlebars->45->2278" ] }, { @@ -67441,7 +67635,7 @@ "tr": "{0}, {1}, {2}'den kilitli hesapta kullanıcı oturum açma girişimi", "zh-chs": "来自 {0}、{1}、{2} 的锁定帐户的用户登录尝试", "xloc": [ - "default.handlebars->41->2305" + "default.handlebars->45->2320" ] }, { @@ -67465,7 +67659,7 @@ "tr": "{0}, {1}, {2}'den yanlış 2. faktörle kullanıcı oturum açma girişimi", "zh-chs": "来自 {0}、{1}、{2} 的第二个因素不正确的用户登录尝试", "xloc": [ - "default.handlebars->41->2304" + "default.handlebars->45->2319" ] }, { @@ -67485,7 +67679,7 @@ "ru": "Уведомления пользователей изменены", "tr": "Kullanıcı bildirimleri değişti", "xloc": [ - "default.handlebars->41->2326" + "default.handlebars->45->2341" ] }, { @@ -67510,7 +67704,7 @@ "zh-chs": "未找到用户 {0}。", "xloc": [ "default-mobile.handlebars->11->728", - "default.handlebars->41->2876" + "default.handlebars->45->2891" ] }, { @@ -67563,16 +67757,16 @@ "default-mobile.handlebars->11->386", "default-mobile.handlebars->11->454", "default-mobile.handlebars->11->634", - "default.handlebars->41->1128", - "default.handlebars->41->1217", - "default.handlebars->41->1314", - "default.handlebars->41->1806", - "default.handlebars->41->1821", - "default.handlebars->41->1826", - "default.handlebars->41->1864", - "default.handlebars->41->2459", - "default.handlebars->41->315", - "default.handlebars->41->458", + "default.handlebars->45->1143", + "default.handlebars->45->1232", + "default.handlebars->45->1329", + "default.handlebars->45->1821", + "default.handlebars->45->1836", + "default.handlebars->45->1841", + "default.handlebars->45->1879", + "default.handlebars->45->2474", + "default.handlebars->45->316", + "default.handlebars->45->461", "login2.handlebars->centralTable->1->0->logincell->loginpanel->loginpanelform->loginuserpassdiv->1->1->0->1", "login2.handlebars->centralTable->1->0->logincell->loginpanel->loginpanelform->loginuserpassdiv->1->1->0->1", "mstsc.handlebars->main->1->3->1->rowusername->1->0", @@ -67604,8 +67798,8 @@ "xloc": [ "default-mobile.handlebars->11->449", "default-mobile.handlebars->11->452", - "default.handlebars->41->1309", - "default.handlebars->41->1312", + "default.handlebars->45->1324", + "default.handlebars->45->1327", "ssh.handlebars->3->10", "ssh.handlebars->3->7" ] @@ -67660,8 +67854,8 @@ "xloc": [ "default-mobile.handlebars->11->450", "default-mobile.handlebars->11->453", - "default.handlebars->41->1310", - "default.handlebars->41->1313", + "default.handlebars->45->1325", + "default.handlebars->45->1328", "ssh.handlebars->3->11", "ssh.handlebars->3->8" ] @@ -67718,9 +67912,9 @@ "zh-chs": "用户", "zh-cht": "用戶", "xloc": [ - "default.handlebars->41->2493", - "default.handlebars->41->2536", - "default.handlebars->41->2942", + "default.handlebars->45->2508", + "default.handlebars->45->2551", + "default.handlebars->45->2957", "default.handlebars->container->topbar->1->1->UsersSubMenuSpan->UsersSubMenu->1->0->UsersGeneral" ] }, @@ -67746,7 +67940,7 @@ "zh-chs": "用户会话", "zh-cht": "用戶節", "xloc": [ - "default.handlebars->41->2915" + "default.handlebars->45->2930" ] }, { @@ -67770,7 +67964,7 @@ "tr": "Kullanıcılar Görünümü", "zh-chs": "用户视图", "xloc": [ - "default.handlebars->41->2433" + "default.handlebars->45->2448" ] }, { @@ -67795,7 +67989,7 @@ "zh-chs": "未找到用户 {0}。", "xloc": [ "default-mobile.handlebars->11->729", - "default.handlebars->41->2877" + "default.handlebars->45->2892" ] }, { @@ -67819,7 +68013,7 @@ "tr": "VNC Bağlantısı", "zh-chs": "VNC 连接", "xloc": [ - "default.handlebars->41->744" + "default.handlebars->45->748" ] }, { @@ -67843,7 +68037,7 @@ "tr": "VNC uzak bağlantı noktası:", "zh-chs": "VNC远程连接端口:", "xloc": [ - "default.handlebars->41->743" + "default.handlebars->45->747" ] }, { @@ -67868,7 +68062,7 @@ "zh-chs": "VT100 +(F10 = ESC + [OY)", "zh-cht": "VT100 +(F10 = ESC + [OY)", "xloc": [ - "default.handlebars->41->1333", + "default.handlebars->45->1348", "sharing.handlebars->11->38" ] }, @@ -67894,7 +68088,7 @@ "zh-chs": "有效登录", "xloc": [ "default-mobile.handlebars->11->82", - "default.handlebars->41->305" + "default.handlebars->45->306" ] }, { @@ -67919,7 +68113,7 @@ "zh-chs": "验证电邮", "zh-cht": "驗證電郵", "xloc": [ - "default.handlebars->41->2412" + "default.handlebars->45->2427" ] }, { @@ -67944,7 +68138,7 @@ "zh-chs": "验证异常", "xloc": [ "default-mobile.handlebars->11->722", - "default.handlebars->41->2870" + "default.handlebars->45->2885" ] }, { @@ -67969,7 +68163,7 @@ "zh-chs": "有效期", "zh-cht": "有效期", "xloc": [ - "default.handlebars->41->1073" + "default.handlebars->45->1088" ] }, { @@ -67993,7 +68187,7 @@ "tr": "Değer", "zh-chs": "价值", "xloc": [ - "default.handlebars->41->1264" + "default.handlebars->45->1279" ] }, { @@ -68018,7 +68212,7 @@ "zh-chs": "文达", "zh-cht": "文達", "xloc": [ - "default.handlebars->41->1724" + "default.handlebars->45->1739" ] }, { @@ -68045,8 +68239,8 @@ "xloc": [ "default-mobile.handlebars->11->579", "default-mobile.handlebars->11->582", - "default.handlebars->41->1461", - "default.handlebars->41->1464" + "default.handlebars->45->1476", + "default.handlebars->45->1479" ] }, { @@ -68072,7 +68266,7 @@ "zh-cht": "驗證碼:", "xloc": [ "default-mobile.handlebars->11->80", - "default.handlebars->41->239" + "default.handlebars->45->240" ] }, { @@ -68097,7 +68291,7 @@ "zh-chs": "已验证", "zh-cht": "已驗證", "xloc": [ - "default.handlebars->41->2685" + "default.handlebars->45->2700" ] }, { @@ -68149,8 +68343,8 @@ "zh-cht": "驗證電話號碼", "xloc": [ "default-mobile.handlebars->11->94", - "default.handlebars->41->1506", - "default.handlebars->41->2408" + "default.handlebars->45->1521", + "default.handlebars->45->2423" ] }, { @@ -68175,7 +68369,7 @@ "zh-chs": "用户{0}的已验证电话号码", "zh-cht": "用戶{0}的已驗證電話號碼", "xloc": [ - "default.handlebars->41->2292" + "default.handlebars->45->2307" ] }, { @@ -68252,13 +68446,13 @@ "zh-cht": "版", "xloc": [ "default-mobile.handlebars->11->510", - "default-mobile.handlebars->11->563", + "default-mobile.handlebars->11->562", "default-mobile.handlebars->11->580", "default-mobile.handlebars->11->585", - "default.handlebars->41->1399", - "default.handlebars->41->1445", - "default.handlebars->41->1462", - "default.handlebars->41->1467", + "default.handlebars->45->1414", + "default.handlebars->45->1459", + "default.handlebars->45->1477", + "default.handlebars->45->1482", "default.handlebars->container->column_l->p42->p42tbl->1->0->5" ] }, @@ -68284,7 +68478,7 @@ "zh-chs": "版本不兼容,请先升级您的MeshCentral", "zh-cht": "版本不兼容,請先升級你的MeshCentral", "xloc": [ - "default.handlebars->41->2985" + "default.handlebars->45->3000" ] }, { @@ -68357,7 +68551,7 @@ "zh-chs": "颤动", "xloc": [ "default-mobile.handlebars->11->359", - "default.handlebars->41->1090" + "default.handlebars->45->1105" ] }, { @@ -68382,7 +68576,7 @@ "zh-chs": "越南文", "zh-cht": "越南文", "xloc": [ - "default.handlebars->41->1725" + "default.handlebars->45->1740" ] }, { @@ -68432,7 +68626,7 @@ "zh-chs": "查看所有事件", "zh-cht": "查看所有事件", "xloc": [ - "default.handlebars->41->2484" + "default.handlebars->45->2499" ] }, { @@ -68478,8 +68672,8 @@ "zh-chs": "查看变更日志", "zh-cht": "查看變更日誌", "xloc": [ - "default.handlebars->41->2988", - "default.handlebars->41->2990" + "default.handlebars->45->3003", + "default.handlebars->45->3005" ] }, { @@ -68504,7 +68698,7 @@ "zh-chs": "查看有关此设备的注释", "zh-cht": "查看有關此裝置的註釋", "xloc": [ - "default.handlebars->41->896" + "default.handlebars->45->904" ] }, { @@ -68529,7 +68723,7 @@ "zh-chs": "查看有关此设备组的注释", "zh-cht": "查看有關此裝置群的註釋", "xloc": [ - "default.handlebars->41->1905" + "default.handlebars->45->1920" ] }, { @@ -68554,7 +68748,7 @@ "zh-chs": "查看有关此用户的注释", "zh-cht": "查看有關此用戶的註釋", "xloc": [ - "default.handlebars->41->2647" + "default.handlebars->45->2662" ] }, { @@ -68603,7 +68797,7 @@ "tr": "Bu kullanıcı için önceki girişleri görüntüle", "zh-chs": "查看此用户以前的登录", "xloc": [ - "default.handlebars->41->2660" + "default.handlebars->45->2675" ] }, { @@ -68627,7 +68821,7 @@ "tr": "Sanal bellek", "zh-chs": "虚拟内存", "xloc": [ - "default.handlebars->41->133" + "default.handlebars->45->134" ] }, { @@ -68652,7 +68846,7 @@ "zh-chs": "沃拉普克", "zh-cht": "沃拉普克", "xloc": [ - "default.handlebars->41->1726" + "default.handlebars->45->1741" ] }, { @@ -68698,9 +68892,9 @@ "zh-chs": "警告: ", "zh-cht": "警告: ", "xloc": [ - "default.handlebars->41->104", - "default.handlebars->41->105", - "default.handlebars->41->106" + "default.handlebars->45->105", + "default.handlebars->45->106", + "default.handlebars->45->107" ] }, { @@ -68727,8 +68921,8 @@ }, { "cs": "VYHRAJ + L", - "da": "WIN + L.", - "de": "GEWINNEN + L.", + "da": "WIN + L", + "de": "WIN + L", "en": "WIN + L", "es": "WIN + L", "fi": "VOIT + L", @@ -68749,8 +68943,8 @@ }, { "cs": "VYHRAJ + M", - "da": "WIN + M.", - "de": "GEWINNEN + M.", + "da": "WIN + M", + "de": "WIN + M", "en": "WIN + M", "es": "WIN + M", "fi": "VOIT + M", @@ -68772,7 +68966,7 @@ { "cs": "VYHRAJ + R", "da": "WIN + R", - "de": "WIN + R.", + "de": "WIN + R", "en": "WIN + R", "es": "WIN + R", "fi": "VOIT + R", @@ -68861,7 +69055,7 @@ "zh-cht": "正在等待用戶授予訪問權限...", "xloc": [ "default-mobile.handlebars->11->406", - "default.handlebars->41->1197", + "default.handlebars->45->1212", "sharing.handlebars->11->28", "sharing.handlebars->11->6" ] @@ -68888,8 +69082,8 @@ "zh-chs": "唤醒", "zh-cht": "喚醒", "xloc": [ - "default.handlebars->41->1004", - "default.handlebars->41->1026" + "default.handlebars->45->1018", + "default.handlebars->45->1040" ] }, { @@ -68916,8 +69110,8 @@ "xloc": [ "default-mobile.handlebars->11->669", "default-mobile.handlebars->11->684", - "default.handlebars->41->2043", - "default.handlebars->41->2074" + "default.handlebars->45->2058", + "default.handlebars->45->2089" ] }, { @@ -68943,7 +69137,7 @@ "zh-cht": "喚醒", "xloc": [ "default-mobile.handlebars->11->364", - "default.handlebars->41->1095" + "default.handlebars->45->1110" ] }, { @@ -68968,7 +69162,7 @@ "zh-chs": "唤醒设备", "zh-cht": "喚醒裝置", "xloc": [ - "default.handlebars->41->644" + "default.handlebars->45->647" ] }, { @@ -68993,7 +69187,7 @@ "zh-chs": "瓦隆", "zh-cht": "瓦隆", "xloc": [ - "default.handlebars->41->1727" + "default.handlebars->45->1742" ] }, { @@ -69018,7 +69212,7 @@ "zh-chs": "弱", "zh-cht": "弱", "xloc": [ - "default.handlebars->41->1813" + "default.handlebars->45->1828" ] }, { @@ -69068,8 +69262,8 @@ "ru": "Веб Push-уведомления", "tr": "Web Sayfası Bildirimleri", "xloc": [ - "default.handlebars->41->2120", - "default.handlebars->41->985" + "default.handlebars->45->2135", + "default.handlebars->45->999" ] }, { @@ -69088,7 +69282,7 @@ "ru": "Web Power Switch 7", "tr": "Web Güç Anahtarı 7", "xloc": [ - "default.handlebars->41->1804" + "default.handlebars->45->1819" ] }, { @@ -69113,8 +69307,8 @@ "zh-chs": "网络服务器", "zh-cht": "網絡伺服器", "xloc": [ - "default.handlebars->41->2968", - "default.handlebars->41->2969" + "default.handlebars->45->2983", + "default.handlebars->45->2984" ] }, { @@ -69138,7 +69332,7 @@ "tr": "Web Sunucusu HTTP Başlıkları", "zh-chs": "Web 服务器 HTTP 标头", "xloc": [ - "default.handlebars->41->2972" + "default.handlebars->45->2987" ] }, { @@ -69163,7 +69357,7 @@ "zh-chs": "Web服务器请求", "zh-cht": "Web伺服器請求", "xloc": [ - "default.handlebars->41->2970" + "default.handlebars->45->2985" ] }, { @@ -69188,7 +69382,7 @@ "zh-chs": "Web套接字中继", "zh-cht": "Web插座中繼", "xloc": [ - "default.handlebars->41->2971" + "default.handlebars->45->2986" ] }, { @@ -69213,8 +69407,8 @@ "zh-chs": "网络RDP", "zh-cht": "網絡RDP", "xloc": [ - "default.handlebars->41->2817", - "default.handlebars->41->933", + "default.handlebars->45->2832", + "default.handlebars->45->943", "default.handlebars->contextMenu->cxwebrdp" ] }, @@ -69234,7 +69428,7 @@ "ru": "Web-SFTP", "tr": "Web-SFTP", "xloc": [ - "default.handlebars->41->2819" + "default.handlebars->45->2834" ] }, { @@ -69258,8 +69452,8 @@ "tr": "Web-SSH", "zh-chs": "网络SSH", "xloc": [ - "default.handlebars->41->2818", - "default.handlebars->41->935", + "default.handlebars->45->2833", + "default.handlebars->45->945", "default.handlebars->contextMenu->cxwebssh" ] }, @@ -69284,8 +69478,8 @@ "tr": "Web-VNC", "zh-chs": "网络VNC", "xloc": [ - "default.handlebars->41->2820", - "default.handlebars->41->931", + "default.handlebars->45->2835", + "default.handlebars->45->941", "default.handlebars->contextMenu->cxwebvnc" ] }, @@ -69310,7 +69504,7 @@ "tr": "WebRDP", "zh-chs": "网络RDP", "xloc": [ - "default.handlebars->41->2936" + "default.handlebars->45->2951" ] }, { @@ -69334,7 +69528,7 @@ "tr": "WebSSH", "zh-chs": "网络SSH", "xloc": [ - "default.handlebars->41->2937" + "default.handlebars->45->2952" ] }, { @@ -69354,7 +69548,7 @@ "ru": "Сжатие WebSocket отключено, эта функция не работает в NodeJS v11..с 11 по 12 версию.15 и v13.2", "tr": "WebSocket sıkıştırması devre dışı, bu özellik NodeJS v11.11'den v12.15'e ve v13.2'de bozuk", "xloc": [ - "default.handlebars->41->86" + "default.handlebars->45->86" ] }, { @@ -69378,7 +69572,7 @@ "tr": "WebVNC", "zh-chs": "网络VNC", "xloc": [ - "default.handlebars->41->2938" + "default.handlebars->45->2953" ] }, { @@ -69398,7 +69592,7 @@ "ru": "Еженедельно", "tr": "Haftalık", "xloc": [ - "default.handlebars->41->281" + "default.handlebars->45->282" ] }, { @@ -69449,7 +69643,7 @@ "zh-chs": "欢迎{0}。", "zh-cht": "歡迎{0}。", "xloc": [ - "default.handlebars->41->58", + "default.handlebars->45->58", "terms.handlebars->3->1" ] }, @@ -69475,7 +69669,7 @@ "zh-chs": "威尔士文", "zh-cht": "威爾士文", "xloc": [ - "default.handlebars->41->1728" + "default.handlebars->45->1743" ] }, { @@ -69500,7 +69694,7 @@ "zh-chs": "启用后,任何人都可以使用邀请代码通过以下公共连结将设备加入该设备组:", "zh-cht": "啟用後,任何人都可以使用邀請代碼通過以下公共鏈結將裝置加入該裝置群:", "xloc": [ - "default.handlebars->41->2099" + "default.handlebars->45->2114" ] }, { @@ -69526,7 +69720,7 @@ "zh-cht": "啟用後,每次登入時,你都可以選擇向電郵帳戶接收登入保安編碼,以提高安全性。", "xloc": [ "default-mobile.handlebars->11->100", - "default.handlebars->41->1513" + "default.handlebars->45->1528" ] }, { @@ -69551,7 +69745,7 @@ "zh-chs": "选择此策略时,此服务器不管理英特尔®AMT。 仍然可以通过手动激活和配置Intel AMT来使用它。", "zh-cht": "選擇此策略時,此服務器不管理英特爾®AMT。 仍然可以通過手動激活和配置Intel AMT來使用它。", "xloc": [ - "default.handlebars->41->1981" + "default.handlebars->45->1996" ] }, { @@ -69598,7 +69792,7 @@ "zh-chs": "选择此策略后,将禁用处于客户端控制模式(CCM)的所有英特尔®AMT。 其他设备将清除CIRA,并且仍然可以手动进行管理。", "zh-cht": "選擇此策略後,將禁用處於客戶端控制模式(CCM)的所有英特爾®AMT。 其他設備將清除CIRA,並且仍然可以手動進行管理。", "xloc": [ - "default.handlebars->41->1982" + "default.handlebars->45->1997" ] }, { @@ -69623,7 +69817,7 @@ "zh-chs": "下次登录时将更改。", "zh-cht": "下次登入時將更改。", "xloc": [ - "default.handlebars->41->2617" + "default.handlebars->45->2632" ] }, { @@ -69651,8 +69845,8 @@ "default-mobile.handlebars->11->433", "default-mobile.handlebars->11->437", "default-mobile.handlebars->dialog->3->dialog3->deskkeys->5", - "default.handlebars->41->1255", - "default.handlebars->41->1259", + "default.handlebars->45->1270", + "default.handlebars->45->1274", "sharing.handlebars->p11->deskarea0->deskarea4->3->deskkeys->3" ] }, @@ -69858,7 +70052,7 @@ "zh-chs": "Win32可执行档案", "zh-cht": "Win32可執行檔案", "xloc": [ - "default.handlebars->41->1156" + "default.handlebars->45->1171" ] }, { @@ -69925,7 +70119,7 @@ "tr": "Pencere Başlığı", "zh-chs": "窗口标题", "xloc": [ - "default.handlebars->41->115" + "default.handlebars->45->116" ] }, { @@ -69951,9 +70145,9 @@ "zh-cht": "視窗", "xloc": [ "default-mobile.handlebars->11->283", - "default.handlebars->41->533", - "default.handlebars->41->55", - "default.handlebars->41->794" + "default.handlebars->45->536", + "default.handlebars->45->55", + "default.handlebars->45->802" ] }, { @@ -69978,8 +70172,8 @@ "zh-chs": "Windows(.exe)", "zh-cht": "Windows(.exe)", "xloc": [ - "default.handlebars->41->556", - "default.handlebars->41->584" + "default.handlebars->45->559", + "default.handlebars->45->587" ] }, { @@ -70004,7 +70198,7 @@ "zh-chs": "Windows(32位)", "zh-cht": "Windows(32位)", "xloc": [ - "default.handlebars->41->1162" + "default.handlebars->45->1177" ] }, { @@ -70029,7 +70223,7 @@ "zh-chs": "Windows(64位)", "zh-cht": "Windows(64位)", "xloc": [ - "default.handlebars->41->1161" + "default.handlebars->45->1176" ] }, { @@ -70053,7 +70247,7 @@ "tr": "Windows (RDP)", "zh-chs": "视窗 (RDP)", "xloc": [ - "default.handlebars->41->450" + "default.handlebars->45->453" ] }, { @@ -70078,7 +70272,7 @@ "zh-chs": "Windows(卸载)", "zh-cht": "Windows(卸載)", "xloc": [ - "default.handlebars->41->539" + "default.handlebars->45->542" ] }, { @@ -70129,7 +70323,7 @@ "zh-cht": "Windows 32位控制台", "xloc": [ "default-mobile.handlebars->11->7", - "default.handlebars->41->14" + "default.handlebars->45->14" ] }, { @@ -70155,7 +70349,7 @@ "zh-cht": "Windows 32位服務", "xloc": [ "default-mobile.handlebars->11->9", - "default.handlebars->41->16" + "default.handlebars->45->16" ] }, { @@ -70206,7 +70400,7 @@ "zh-cht": "Windows 64位控制台", "xloc": [ "default-mobile.handlebars->11->8", - "default.handlebars->41->15" + "default.handlebars->45->15" ] }, { @@ -70232,7 +70426,7 @@ "zh-cht": "Windows 64位服務", "xloc": [ "default-mobile.handlebars->11->10", - "default.handlebars->41->17" + "default.handlebars->45->17" ] }, { @@ -70257,8 +70451,8 @@ "zh-chs": "Windows命令提示", "zh-cht": "Windows命令提示", "xloc": [ - "default.handlebars->41->1110", - "default.handlebars->41->668" + "default.handlebars->45->1125", + "default.handlebars->45->671" ] }, { @@ -70269,8 +70463,8 @@ "pt-br": "MeshAgent Windows", "ru": "MeshAgent для Windows ", "xloc": [ - "default.handlebars->41->2104", - "default.handlebars->41->523" + "default.handlebars->45->2119", + "default.handlebars->45->526" ] }, { @@ -70296,7 +70490,7 @@ "zh-cht": "Windows MinCore控制台", "xloc": [ "default-mobile.handlebars->11->27", - "default.handlebars->41->34" + "default.handlebars->45->34" ] }, { @@ -70322,7 +70516,7 @@ "zh-cht": "Windows MinCore服務", "xloc": [ "default-mobile.handlebars->11->28", - "default.handlebars->41->35" + "default.handlebars->45->35" ] }, { @@ -70347,7 +70541,7 @@ "zh-chs": "Windows路径", "zh-cht": "Windows路徑", "xloc": [ - "default.handlebars->41->689" + "default.handlebars->45->692" ] }, { @@ -70372,8 +70566,8 @@ "zh-chs": "Windows PowerShell", "zh-cht": "Windows PowerShell", "xloc": [ - "default.handlebars->41->1111", - "default.handlebars->41->669" + "default.handlebars->45->1126", + "default.handlebars->45->672" ] }, { @@ -70398,7 +70592,7 @@ "zh-chs": "视窗安全", "xloc": [ "default-mobile.handlebars->11->528", - "default.handlebars->41->841" + "default.handlebars->45->849" ] }, { @@ -70423,7 +70617,7 @@ "zh-chs": "仅Windows", "zh-cht": "僅Windows", "xloc": [ - "default.handlebars->41->496" + "default.handlebars->45->499" ] }, { @@ -70448,8 +70642,8 @@ "zh-chs": "Windows x64(.exe)", "zh-cht": "Windows x64(.exe)", "xloc": [ - "default.handlebars->41->560", - "default.handlebars->41->587" + "default.handlebars->45->563", + "default.handlebars->45->590" ] }, { @@ -70457,8 +70651,9 @@ "nl": "Werkmap", "pl": "Folder Roboczy", "ru": "Рабочий каталог", + "fr": "Répertoire de travail", "xloc": [ - "default.handlebars->41->1221" + "default.handlebars->45->1236" ] }, { @@ -70482,7 +70677,7 @@ "tr": "Çalışma seti", "zh-chs": "工作集", "xloc": [ - "default.handlebars->41->134" + "default.handlebars->45->135" ] }, { @@ -70532,7 +70727,7 @@ "zh-chs": "换行:关", "zh-cht": "换行:關", "xloc": [ - "default.handlebars->41->1383", + "default.handlebars->45->1398", "sharing.handlebars->11->84" ] }, @@ -70558,7 +70753,7 @@ "zh-chs": "换行:开", "zh-cht": "换行:開", "xloc": [ - "default.handlebars->41->1382", + "default.handlebars->45->1397", "sharing.handlebars->11->83" ] }, @@ -70584,7 +70779,7 @@ "zh-chs": "为此设备写一个事件", "zh-cht": "為此裝置寫一個事件", "xloc": [ - "default.handlebars->41->898" + "default.handlebars->45->906" ] }, { @@ -70634,7 +70829,7 @@ "zh-cht": "XENx86", "xloc": [ "default-mobile.handlebars->11->14", - "default.handlebars->41->21" + "default.handlebars->45->21" ] }, { @@ -70659,7 +70854,7 @@ "zh-chs": "XTerm", "zh-cht": "XTerm", "xloc": [ - "default.handlebars->41->922" + "default.handlebars->45->930" ] }, { @@ -70684,7 +70879,7 @@ "zh-chs": "科萨", "zh-cht": "科薩", "xloc": [ - "default.handlebars->41->1729" + "default.handlebars->45->1744" ] }, { @@ -70709,7 +70904,7 @@ "zh-chs": "意第绪文", "zh-cht": "意第緒文", "xloc": [ - "default.handlebars->41->1730" + "default.handlebars->45->1745" ] }, { @@ -70734,7 +70929,7 @@ "zh-chs": "您可以随时重新激活此功能。", "zh-cht": "你可以隨時重新啟動此功能。", "xloc": [ - "default.handlebars->41->211" + "default.handlebars->45->212" ] }, { @@ -70831,7 +71026,7 @@ "zh-chs": "您现在需要一个有效的保安编码才能再次登录。", "zh-cht": "你現在需要一個有效的保安編碼才能再次登入。", "xloc": [ - "default.handlebars->41->206" + "default.handlebars->45->207" ] }, { @@ -70882,7 +71077,7 @@ "zh-chs": "YubiKey™ OTP", "zh-cht": "YubiKey™OTP", "xloc": [ - "default.handlebars->41->1532" + "default.handlebars->45->1547" ] }, { @@ -70933,7 +71128,7 @@ "zh-chs": "邮编档案名", "zh-cht": "郵編檔案名", "xloc": [ - "default.handlebars->41->1367", + "default.handlebars->45->1382", "sharing.handlebars->11->68" ] }, @@ -70959,7 +71154,7 @@ "zh-chs": "缩放至适合范围", "zh-cht": "縮放至適合範圍", "xloc": [ - "default.handlebars->41->760" + "default.handlebars->45->768" ] }, { @@ -70984,8 +71179,8 @@ "zh-chs": "放大到一定程度", "zh-cht": "放大到一定程度", "xloc": [ - "default.handlebars->41->757", - "default.handlebars->41->763" + "default.handlebars->45->765", + "default.handlebars->45->771" ] }, { @@ -71010,8 +71205,8 @@ "zh-chs": "缩小到一定程度", "zh-cht": "縮小到一定程度", "xloc": [ - "default.handlebars->41->758", - "default.handlebars->41->764" + "default.handlebars->45->766", + "default.handlebars->45->772" ] }, { @@ -71036,7 +71231,7 @@ "zh-chs": "祖鲁族", "zh-cht": "祖魯族", "xloc": [ - "default.handlebars->41->1731" + "default.handlebars->45->1746" ] }, { @@ -71061,7 +71256,7 @@ "zh-chs": "[KeyboardTyping]|类型", "zh-cht": "[KeyboardTyping]|類型", "xloc": [ - "default.handlebars->41->61" + "default.handlebars->45->61" ] }, { @@ -71454,7 +71649,7 @@ "zh-chs": "\\\\'", "zh-cht": "\\\\'", "xloc": [ - "default.handlebars->41->2986" + "default.handlebars->45->3001" ] }, { @@ -71481,8 +71676,8 @@ "xloc": [ "default-mobile.handlebars->11->180", "default-mobile.handlebars->11->181", - "default.handlebars->41->731", - "default.handlebars->41->732" + "default.handlebars->45->735", + "default.handlebars->45->736" ] }, { @@ -71507,9 +71702,9 @@ "zh-chs": "加一", "zh-cht": "加一", "xloc": [ - "default.handlebars->41->340", - "default.handlebars->41->342", - "default.handlebars->41->344" + "default.handlebars->45->341", + "default.handlebars->45->343", + "default.handlebars->45->345" ] }, { @@ -71534,7 +71729,7 @@ "zh-chs": "管理员", "zh-cht": "管理員", "xloc": [ - "default.handlebars->41->459" + "default.handlebars->45->462" ] }, { @@ -71560,8 +71755,8 @@ "xloc": [ "default-mobile.handlebars->11->184", "default-mobile.handlebars->11->185", - "default.handlebars->41->735", - "default.handlebars->41->736" + "default.handlebars->45->739", + "default.handlebars->45->740" ] }, { @@ -71585,7 +71780,7 @@ "tr": "ve", "zh-chs": "和", "xloc": [ - "default.handlebars->41->713" + "default.handlebars->45->717" ] }, { @@ -71663,8 +71858,8 @@ "xloc": [ "default-mobile.handlebars->11->178", "default-mobile.handlebars->11->179", - "default.handlebars->41->729", - "default.handlebars->41->730" + "default.handlebars->45->733", + "default.handlebars->45->734" ] }, { @@ -71672,6 +71867,7 @@ "nl": "browser", "pl": "przeglądarka", "ru": "browser", + "fr": "Navigateur", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize" ] @@ -71724,7 +71920,7 @@ "zh-chs": "取消帮助", "zh-cht": "取消幫助", "xloc": [ - "default.handlebars->41->396" + "default.handlebars->45->399" ] }, { @@ -71860,8 +72056,8 @@ "tr": "bilgisayar listesi.json", "zh-chs": "计算机列表.json", "xloc": [ - "default.handlebars->41->706", - "default.handlebars->41->711" + "default.handlebars->45->710", + "default.handlebars->45->715" ] }, { @@ -71887,7 +72083,7 @@ "zh-cht": "console.txt", "xloc": [ "default-mobile.handlebars->11->609", - "default.handlebars->41->1492" + "default.handlebars->45->1507" ] }, { @@ -71913,7 +72109,7 @@ "zh-cht": "複製", "xloc": [ "default-mobile.handlebars->11->161", - "default.handlebars->41->2191" + "default.handlebars->45->2206" ] }, { @@ -71962,8 +72158,8 @@ "tr": "açıklama:", "zh-chs": "描述:", "xloc": [ - "default.handlebars->41->737", - "default.handlebars->41->738" + "default.handlebars->45->741", + "default.handlebars->45->742" ] }, { @@ -71987,7 +72183,7 @@ "tr": "cihaz listesi", "zh-chs": "设备列表", "xloc": [ - "default.handlebars->41->311" + "default.handlebars->45->312" ] }, { @@ -72012,8 +72208,8 @@ "zh-chs": "devicelist.csv", "zh-cht": "devicelist.csv", "xloc": [ - "default.handlebars->41->702", - "default.handlebars->41->710" + "default.handlebars->45->706", + "default.handlebars->45->714" ] }, { @@ -72038,8 +72234,8 @@ "zh-chs": "devicelist.json", "zh-cht": "devicelist.json", "xloc": [ - "default.handlebars->41->704", - "default.handlebars->41->712" + "default.handlebars->45->708", + "default.handlebars->45->716" ] }, { @@ -72134,8 +72330,8 @@ "zh-chs": "eventslist.csv", "zh-cht": "eventslist.csv", "xloc": [ - "default.handlebars->41->2376", - "default.handlebars->41->2381" + "default.handlebars->45->2391", + "default.handlebars->45->2396" ] }, { @@ -72160,8 +72356,8 @@ "zh-chs": "eventslist.json", "zh-cht": "eventslist.json", "xloc": [ - "default.handlebars->41->2378", - "default.handlebars->41->2382" + "default.handlebars->45->2393", + "default.handlebars->45->2397" ] }, { @@ -72186,7 +72382,7 @@ "zh-chs": "example@email.com", "zh-cht": "example@email.com", "xloc": [ - "default.handlebars->41->492" + "default.handlebars->45->495" ] }, { @@ -72236,8 +72432,8 @@ "zh-chs": "免费", "zh-cht": "免費", "xloc": [ - "default.handlebars->41->2923", - "default.handlebars->41->2926" + "default.handlebars->45->2938", + "default.handlebars->45->2941" ] }, { @@ -72264,8 +72460,8 @@ "xloc": [ "default-mobile.handlebars->11->172", "default-mobile.handlebars->11->173", - "default.handlebars->41->723", - "default.handlebars->41->724" + "default.handlebars->45->727", + "default.handlebars->45->728" ] }, { @@ -72292,8 +72488,8 @@ "xloc": [ "default-mobile.handlebars->11->170", "default-mobile.handlebars->11->171", - "default.handlebars->41->721", - "default.handlebars->41->722" + "default.handlebars->45->725", + "default.handlebars->45->726" ] }, { @@ -72507,8 +72703,9 @@ "nl": "id, naam, email, aangemaakt, laaste login, groeps, authfactors, siteadmin, useradmin, geblokkeerd", "pl": "id, nazwa, e-mail, tworzenie, ostatnie logowanie, grupy, opcje autentykacji, administrator, uużytkownik, blokada", "ru": "id, name, email, creation, lastlogin, groups, authfactors, siteadmin, useradmin, locked", + "fr": "id, nom, email, creation, derniereconnexion, groupes, authentification, siteadmin, useradmin, verrouillé", "xloc": [ - "default.handlebars->41->2448" + "default.handlebars->45->2463" ] }, { @@ -72575,7 +72772,7 @@ "tr": "id, ad, rname, ana bilgisayar, simge, ip, osdesc, durum, grup adı, bağlantı, pwr, av, güncelleme, güvenlik duvarı, avdetails", "zh-chs": "id、名称、rname、主机、图标、ip、osdesc、状态、组名、conn、pwr、av、更新、防火墙、avdetails", "xloc": [ - "default.handlebars->41->709" + "default.handlebars->45->713" ] }, { @@ -72623,8 +72820,8 @@ "xloc": [ "default-mobile.handlebars->11->168", "default-mobile.handlebars->11->169", - "default.handlebars->41->719", - "default.handlebars->41->720" + "default.handlebars->45->723", + "default.handlebars->45->724" ] }, { @@ -72724,7 +72921,7 @@ "zh-chs": "k max,默认为空白", "zh-cht": "k max,默認為空白", "xloc": [ - "default.handlebars->41->2476" + "default.handlebars->45->2491" ] }, { @@ -72822,7 +73019,7 @@ "zh-cht": "macOS", "xloc": [ "default-mobile.handlebars->11->287", - "default.handlebars->41->798" + "default.handlebars->45->806" ] }, { @@ -72868,7 +73065,7 @@ "tr": "macOS (SSH/SCP/VNC)", "zh-chs": "macOS (SSH/SCP/VNC)", "xloc": [ - "default.handlebars->41->452" + "default.handlebars->45->455" ] }, { @@ -72937,7 +73134,7 @@ "zh-chs": "macOS ARM (64位)", "zh-cht": "macOS ARM (64位)", "xloc": [ - "default.handlebars->41->1166" + "default.handlebars->45->1181" ] }, { @@ -72962,7 +73159,7 @@ "zh-chs": "macOS x86 (64位)", "zh-cht": "macOS x86 (64位)", "xloc": [ - "default.handlebars->41->1165" + "default.handlebars->45->1180" ] }, { @@ -72988,7 +73185,7 @@ "zh-cht": "macOS x86-32位", "xloc": [ "default-mobile.handlebars->11->17", - "default.handlebars->41->24" + "default.handlebars->45->24" ] }, { @@ -73014,7 +73211,7 @@ "zh-cht": "macOS x86-64位", "xloc": [ "default-mobile.handlebars->11->22", - "default.handlebars->41->29" + "default.handlebars->45->29" ] }, { @@ -73039,7 +73236,7 @@ "zh-chs": "MeshAgent", "zh-cht": "MeshAgent", "xloc": [ - "default.handlebars->41->592" + "default.handlebars->45->595" ] }, { @@ -73065,7 +73262,7 @@ "zh-cht": "移動", "xloc": [ "default-mobile.handlebars->11->162", - "default.handlebars->41->2192" + "default.handlebars->45->2207" ] }, { @@ -73225,7 +73422,7 @@ "tr": "veya", "zh-chs": "或者", "xloc": [ - "default.handlebars->41->714" + "default.handlebars->45->718" ] }, { @@ -73251,8 +73448,8 @@ "xloc": [ "default-mobile.handlebars->11->182", "default-mobile.handlebars->11->183", - "default.handlebars->41->733", - "default.handlebars->41->734" + "default.handlebars->45->737", + "default.handlebars->45->738" ] }, { @@ -73309,6 +73506,7 @@ "nl": "scherm", "pl": "ekran", "ru": "screen", + "fr": "écran", "xloc": [ "default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize" ] @@ -73335,7 +73533,7 @@ "zh-chs": "servererrors.txt", "zh-cht": "servererrors.txt", "xloc": [ - "default.handlebars->41->1847" + "default.handlebars->45->1862" ] }, { @@ -73360,7 +73558,7 @@ "zh-chs": "servertrace.csv", "zh-cht": "servertrace.csv", "xloc": [ - "default.handlebars->41->2980" + "default.handlebars->45->2995" ] }, { @@ -73408,8 +73606,8 @@ "xloc": [ "default-mobile.handlebars->11->176", "default-mobile.handlebars->11->177", - "default.handlebars->41->727", - "default.handlebars->41->728" + "default.handlebars->45->731", + "default.handlebars->45->732" ] }, { @@ -73436,8 +73634,8 @@ "xloc": [ "default-mobile.handlebars->11->174", "default-mobile.handlebars->11->175", - "default.handlebars->41->725", - "default.handlebars->41->726" + "default.handlebars->45->729", + "default.handlebars->45->730" ] }, { @@ -73462,7 +73660,7 @@ "zh-chs": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss", "zh-cht": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss", "xloc": [ - "default.handlebars->41->2955" + "default.handlebars->45->2970" ] }, { @@ -73487,7 +73685,7 @@ "zh-chs": "时间,来源,信息", "zh-cht": "時間,來源,訊息", "xloc": [ - "default.handlebars->41->2979" + "default.handlebars->45->2994" ] }, { @@ -73534,8 +73732,8 @@ "zh-chs": "总计", "zh-cht": "總", "xloc": [ - "default.handlebars->41->2924", - "default.handlebars->41->2927" + "default.handlebars->45->2939", + "default.handlebars->45->2942" ] }, { @@ -73586,8 +73784,8 @@ "xloc": [ "default-mobile.handlebars->11->166", "default-mobile.handlebars->11->167", - "default.handlebars->41->717", - "default.handlebars->41->718" + "default.handlebars->45->721", + "default.handlebars->45->722" ] }, { @@ -73636,8 +73834,8 @@ "xloc": [ "default-mobile.handlebars->11->164", "default-mobile.handlebars->11->165", - "default.handlebars->41->715", - "default.handlebars->41->716" + "default.handlebars->45->719", + "default.handlebars->45->720" ] }, { @@ -73662,8 +73860,8 @@ "zh-chs": "userlist.csv", "zh-cht": "userlist.csv", "xloc": [ - "default.handlebars->41->2444", - "default.handlebars->41->2449" + "default.handlebars->45->2459", + "default.handlebars->45->2464" ] }, { @@ -73688,8 +73886,8 @@ "zh-chs": "userlist.json", "zh-cht": "userlist.json", "xloc": [ - "default.handlebars->41->2446", - "default.handlebars->41->2450" + "default.handlebars->45->2461", + "default.handlebars->45->2465" ] }, { @@ -73714,7 +73912,7 @@ "zh-chs": "utc,时间,类型,指令,用户,设备,消息", "zh-cht": "utc,時間,類型,指令,用戶,裝置,消息", "xloc": [ - "default.handlebars->41->2380" + "default.handlebars->45->2395" ] }, { @@ -73794,11 +73992,7 @@ "sv": "{0}", "tr": "{0}", "zh-chs": "{0}", - "zh-cht": "{0}", - "xloc": [ - "default-mobile.handlebars->11->557", - "default-mobile.handlebars->11->561" - ] + "zh-cht": "{0}" }, { "cs": "{0} - Instalace agenta", @@ -73931,8 +74125,8 @@ "zh-chs": "{0} Gb", "zh-cht": "{0} Gb", "xloc": [ - "default.handlebars->41->2166", - "default.handlebars->41->2171" + "default.handlebars->45->2181", + "default.handlebars->45->2186" ] }, { @@ -73978,9 +74172,9 @@ "zh-chs": "{0} Kb", "zh-cht": "{0} Kb", "xloc": [ - "default.handlebars->41->2164", - "default.handlebars->41->2169", - "default.handlebars->41->2743" + "default.handlebars->45->2179", + "default.handlebars->45->2184", + "default.handlebars->45->2758" ] }, { @@ -74028,10 +74222,10 @@ "xloc": [ "default-mobile.handlebars->11->593", "default-mobile.handlebars->11->598", - "default.handlebars->41->1475", - "default.handlebars->41->1480", - "default.handlebars->41->2165", - "default.handlebars->41->2170" + "default.handlebars->45->1490", + "default.handlebars->45->1495", + "default.handlebars->45->2180", + "default.handlebars->45->2185" ] }, { @@ -74057,7 +74251,7 @@ "zh-cht": "{0} Mb,{1} Mhz", "xloc": [ "default-mobile.handlebars->11->591", - "default.handlebars->41->1473" + "default.handlebars->45->1488" ] }, { @@ -74103,7 +74297,7 @@ "zh-chs": "{0}个活跃会话", "zh-cht": "{0}個活躍節", "xloc": [ - "default.handlebars->41->2663" + "default.handlebars->45->2678" ] }, { @@ -74128,8 +74322,8 @@ "zh-chs": "{0} b", "zh-cht": "{0} b", "xloc": [ - "default.handlebars->41->2163", - "default.handlebars->41->2168" + "default.handlebars->45->2178", + "default.handlebars->45->2183" ] }, { @@ -74155,8 +74349,8 @@ "zh-cht": "{0}個字節", "xloc": [ "default-mobile.handlebars->11->150", - "default.handlebars->41->2179", - "default.handlebars->41->2764", + "default.handlebars->45->2194", + "default.handlebars->45->2779", "download.handlebars->3->2", "download2.handlebars->5->2", "sharing.handlebars->11->97" @@ -74184,7 +74378,7 @@ "zh-chs": "剩余{0}个字节", "zh-cht": "剩餘{0}個字節", "xloc": [ - "default.handlebars->41->2158" + "default.handlebars->45->2173" ] }, { @@ -74230,7 +74424,7 @@ "zh-chs": "{0}个连接", "zh-cht": "{0}個連接", "xloc": [ - "default.handlebars->41->1226", + "default.handlebars->45->1241", "sharing.handlebars->11->16" ] }, @@ -74255,7 +74449,7 @@ "tr": "{1} ile {2} arasında {0}.", "zh-chs": "{0} 从 {1} 到 {2}。", "xloc": [ - "default.handlebars->41->1124" + "default.handlebars->45->1139" ] }, { @@ -74280,7 +74474,7 @@ "zh-chs": "剩余{0} GB", "zh-cht": "剩餘{0} GB", "xloc": [ - "default.handlebars->41->2161" + "default.handlebars->45->2176" ] }, { @@ -74305,7 +74499,7 @@ "zh-chs": "{0}个群组", "zh-cht": "{0}個群組", "xloc": [ - "default.handlebars->41->2622" + "default.handlebars->45->2637" ] }, { @@ -74330,7 +74524,7 @@ "zh-chs": "{0}小時", "zh-cht": "{0}小時", "xloc": [ - "default.handlebars->41->260" + "default.handlebars->45->261" ] }, { @@ -74377,7 +74571,7 @@ "zh-chs": "剩余{0}千字节", "zh-cht": "剩餘{0}千字節", "xloc": [ - "default.handlebars->41->2159" + "default.handlebars->45->2174" ] }, { @@ -74429,7 +74623,7 @@ "zh-chs": "剩余{0}兆字节", "zh-cht": "剩餘{0}兆字節", "xloc": [ - "default.handlebars->41->2160" + "default.handlebars->45->2175" ] }, { @@ -74449,7 +74643,7 @@ "ru": "{0} минута", "tr": "{0} dakika", "xloc": [ - "default.handlebars->41->273" + "default.handlebars->45->274" ] }, { @@ -74469,7 +74663,7 @@ "ru": "{0} минут", "tr": "{0} dakika", "xloc": [ - "default.handlebars->41->275" + "default.handlebars->45->276" ] }, { @@ -74515,7 +74709,7 @@ "zh-chs": "{0}分钟直到断开连接", "zh-cht": "{0}分鐘直到斷開連接", "xloc": [ - "default.handlebars->41->81" + "default.handlebars->45->81" ] }, { @@ -74540,7 +74734,7 @@ "zh-chs": "{0}未显示更多用户,请使用搜索框查找用户...", "zh-cht": "{0}未顯示更多用戶,請使用搜索框查找用戶...", "xloc": [ - "default.handlebars->41->2390" + "default.handlebars->45->2405" ] }, { @@ -74565,7 +74759,7 @@ "zh-chs": "{0}个节点", "zh-cht": "{0}個節點", "xloc": [ - "default.handlebars->41->598" + "default.handlebars->45->601" ] }, { @@ -74767,9 +74961,9 @@ "tr": "{0} saniye", "zh-chs": "{0} 秒", "xloc": [ - "default.handlebars->41->125", - "default.handlebars->41->127", - "default.handlebars->41->129" + "default.handlebars->45->126", + "default.handlebars->45->128", + "default.handlebars->45->130" ] }, { @@ -74815,7 +75009,7 @@ "zh-chs": "{0}秒后断开连接", "zh-cht": "{0}秒後斷開連接", "xloc": [ - "default.handlebars->41->79" + "default.handlebars->45->79" ] }, { @@ -74886,7 +75080,7 @@ "tr": "{0} seçili cihaz çevrimdışı.", "zh-chs": "{0} 个选定的设备处于离线状态。", "xloc": [ - "default.handlebars->41->664" + "default.handlebars->45->667" ] }, { @@ -74910,7 +75104,7 @@ "tr": "{0} seçili cihaz çevrimiçi.", "zh-chs": "{0} 个选定的设备在线。", "xloc": [ - "default.handlebars->41->662" + "default.handlebars->45->665" ] }, { @@ -74942,14 +75136,14 @@ "default-mobile.handlebars->11->219", "default-mobile.handlebars->11->223", "default-mobile.handlebars->11->227", - "default.handlebars->41->2394", - "default.handlebars->41->400", - "default.handlebars->41->403", - "default.handlebars->41->407", - "default.handlebars->41->411", - "default.handlebars->41->415", - "default.handlebars->41->419", - "default.handlebars->41->423" + "default.handlebars->45->2409", + "default.handlebars->45->403", + "default.handlebars->45->406", + "default.handlebars->45->410", + "default.handlebars->45->414", + "default.handlebars->45->418", + "default.handlebars->45->422", + "default.handlebars->45->426" ] }, { @@ -74974,7 +75168,7 @@ "zh-chs": "{0}设置(.msh)", "zh-cht": "{0}设置(.msh)", "xloc": [ - "default.handlebars->41->563" + "default.handlebars->45->566" ] }, { @@ -75111,7 +75305,7 @@ "zh-chs": "{0}个用户", "zh-cht": "{0}個用戶", "xloc": [ - "default.handlebars->41->426" + "default.handlebars->45->429" ] }, { @@ -75154,11 +75348,7 @@ "ru": "{0}, маска: {1}, шлюз: {2}", "sv": "{0}, Mask: {1}, Gateway: {2}", "tr": "{0}, Maske: {1}, Ağ Geçidi: {2}", - "zh-chs": "{0},掩码:{1},网关:{2}", - "xloc": [ - "default-mobile.handlebars->11->555", - "default-mobile.handlebars->11->559" - ] + "zh-chs": "{0},掩码:{1},网关:{2}" }, { "cs": "{0}, {1} po dobu {2} minut", @@ -75177,8 +75367,8 @@ "ru": "{0}, {1} на {2} мин.", "tr": "{0}, {1} için {2} dakika", "xloc": [ - "default.handlebars->41->1932", - "default.handlebars->41->972" + "default.handlebars->45->1947", + "default.handlebars->45->986" ] }, { @@ -75198,8 +75388,8 @@ "ru": "{0}, {1} на {2} мин.", "tr": "{0}, {1} için {2} dakika", "xloc": [ - "default.handlebars->41->1933", - "default.handlebars->41->973" + "default.handlebars->45->1948", + "default.handlebars->45->987" ] }, { @@ -75224,8 +75414,8 @@ "zh-chs": "{0},{1}至{2}", "zh-cht": "{0},{1}至{2}", "xloc": [ - "default.handlebars->41->1931", - "default.handlebars->41->971" + "default.handlebars->45->1946", + "default.handlebars->45->985" ] }, { @@ -75300,7 +75490,7 @@ "zh-chs": "{0}k在1档案内。最多{1}k", "zh-cht": "{0}k在1檔案內。最多{1}k", "xloc": [ - "default.handlebars->41->2173" + "default.handlebars->45->2188" ] }, { @@ -75325,7 +75515,7 @@ "zh-chs": "{1}k在{0}个档案中。最多{2}k", "zh-cht": "{1}k在{0}個檔案中。最多{2}k", "xloc": [ - "default.handlebars->41->2172" + "default.handlebars->45->2187" ] }, { @@ -75378,6 +75568,9 @@ "default-mobile.handlebars->11->144" ] }, + { + "en": "Á/span>" + }, { "cs": "↺", "da": "↺", diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index 6f469ea4..0bf905c2 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -3541,7 +3541,7 @@ x += '
'; // Show action button, only show if we have permissions 4, 8, 64 - if (((meshrights & (4 + 8 + 64)) != 0) && (node.mtype < 3)) { x += ''; } + if (((meshrights & (4 + 8 + 64 + 262144)) != 0) && (node.mtype < 3)) { x += ''; } x += ''; //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += ''; } @@ -3676,35 +3676,6 @@ if (currentDevicePanel == 1) { deskAdjust(); } } - /* - function deviceActionFunction() { - if (xxdialogMode) return; - var rights = GetNodeRights(currentNode), count = 0; - var x = "Select an operation to perform on this device." + '

'; - var y = ''; - x += addHtmlValue("Operation", y); - if (count == 0) { x = "No actions currently available for this device."; } - setDialogMode(2, "Device Action", (count == 0) ? 1 : 3, deviceActionFunctionEx, x); - } - - function deviceActionFunctionEx() { - var op = Q('d2deviceop').value; - if (op == 100) { - // Device wake - meshserver.send({ action: 'wakedevices', nodeids: [currentNode._id] }); - } else { - // Power operation - meshserver.send({ action: 'poweraction', nodeids: [currentNode._id], actiontype: op }); - } - } - */ - function deviceActionFunction() { if (xxdialogMode) return; var rights = GetNodeRights(currentNode), count = 0; @@ -3723,12 +3694,15 @@ //if (((currentNode.conn & 1) != 0) && ((rights & 131072) != 0)) { count++; y += ''; } // Remote command permission if ((currentNode.conn != 0) && ((rights & 262144) != 0)) { count++; y += ''; } //if ((currentNode.conn & 16) != 0) { count++; y += ''; } - if ((currentNode.intelamt != null) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && (rights == 0xFFFFFFFF)) { + if ((currentNode.intelamt != null) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && ((rights & 262144) != 0)) { count++; y += ''; - y += ''; y += ''; } + if ((currentNode.intelamt != null) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && ((rights & 64) != 0)) { + count++; + y += ''; + } //if ((getNodeAmtVersion(currentNode) >= 15) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && (rights == 0xFFFFFFFF) && ((features & 0x00000400) == 0)) { count++; y += ''; } // CIRA (2) or AMT (4) connected //if (((currentNode.conn & 1) != 0) && ((rights & 32768) != 0)) { count++; y += ''; } } @@ -4070,7 +4044,7 @@ ); // Show the right settings - QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (currentNode.agent == null))) && ((deskState == 0) || (desktop.contype == 2))); + QV('d7amtkvm', (currentNode.intelamt != null && ((typeof currentNode.intelamt.sku != 'number') || ((currentNode.intelamt.sku & 16) == 0)) && ((currentNode.intelamt.ver != null) || (currentNode.agent == null))) && ((deskState == 0) || (desktop.contype == 2))); QV('d7meshkvm', ((currentNode.agent != null) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1)))); // Enable buttons @@ -4241,7 +4215,7 @@ } function applyDesktopSettings() { - var r = '', ops = (features & 512) ? [90, 70, 50, 40, 30, 20, 10, 5, 1] : [50, 40, 30, 20, 10, 5, 1]; + var r = '', ops = (features & 512) ? [100, 90, 70, 50, 40, 30, 20, 10, 5, 1] : [50, 40, 30, 20, 10, 5, 1]; for (var i in ops) { r += ''; } QH('d7bitmapquality', r); d7desktopmode.value = desktopsettings.encoding; @@ -4695,7 +4669,7 @@ // Enable action button if mesh type is not "local devices" QV('termActionsBtn', terminalNode.mtype != 3); - if (((termState == true) && (terminal.contype != 3)) || (terminalNode.agent.id == 3) || (terminalNode.agent.id == 4)) { + if (((termState == true) && (terminal.contype != 3)) || (terminalNode.agent == null) || (terminalNode.agent.id == 3) || (terminalNode.agent.id == 4)) { QH('terminalCustomUpperRight', ''); } else { QH('terminalCustomUpperRight', '' + format("SSH Port {0}", (terminalNode.sshport ? terminalNode.sshport : 22)) + ''); @@ -5321,7 +5295,7 @@ QE('p13PasteButton', advancedFeatures && (currentNode.mtype != 3) && ((p13filetreelocation.length > 0) || (winAgent == false)) && ((p13clipboard != null) && (p13clipboard.length > 0))); } var filesState = ((files != null) && (files.state != 0)); - if (((filesState == true) && (files.contype != 2)) || (filesNode.agent.id == 3) || (filesNode.agent.id == 4)) { + if (((filesState == true) && (files.contype != 2)) || (filesNode.agent == null) || (filesNode.agent.id == 3) || (filesNode.agent.id == 4)) { QH('filesCustomUpperRight', ''); } else { QH('filesCustomUpperRight', '' + format("SSH Port {0}", (filesNode.sshport ? filesNode.sshport : 22)) + ''); @@ -5798,20 +5772,13 @@ } } for (var j = 0; j < m.length; j++) { - var iplayer = m[j]; - if (iplayer.family == 'IPv4') { - if (iplayer.gateway && iplayer.netmask) { - x += addDetailItem("IPv4 Layer", format("{0}, Mask: {1}, Gateway: {2}", EscapeHtml(iplayer.address), EscapeHtml(iplayer.netmask), EscapeHtml(iplayer.gateway))); - } else { - if (iplayer.address) { x += addDetailItem("IPv4 Layer", format("{0}", EscapeHtml(iplayer.address))); } - } - } - if (iplayer.family == 'IPv6') { - if (iplayer.gateway && iplayer.netmask) { - x += addDetailItem("IPv6 Layer", format("{0}, Mask: {1}, Gateway: {2}", EscapeHtml(iplayer.address), EscapeHtml(iplayer.netmask), EscapeHtml(iplayer.gateway))); - } else { - if (iplayer.address) { x += addDetailItem("IPv6 Layer", format("{0}", EscapeHtml(iplayer.address))); } - } + var iplayer = m[j], items = []; + if (iplayer.address) { items.push(format("IP: {0}", EscapeHtml(iplayer.address))); } + if (iplayer.netmask) { items.push(format("Mask: {0}", EscapeHtml(iplayer.netmask))); } + if (iplayer.gateway) { items.push(format("Gateway: {0}", EscapeHtml(iplayer.gateway))); } + if (items.length > 0) { + if (iplayer.family == 'IPv4') { x += addDetailItem("IPv4 Layer", items.join(", ")); } + if (iplayer.family == 'IPv6') { x += addDetailItem("IPv6 Layer", items.join(", ")); } } } x += ''; @@ -5831,7 +5798,13 @@ x += addDetailItem("Security", (node.intelamt.tls == 1) ? "Secured using TLS" : "TLS is not setup", s); // Check that the Intel AMT user is setup and there is no warnings (1 = invalid credentials, 8 = trying) x += addDetailItem("Admin Credentials", ((node.intelamt.user) == null || (node.intelamt.user == '') || ((node.intelamt.warn != null) && ((node.intelamt.warn & 9) != 0))) ? "Not Known" : "Known", s); - if (x != '') { sections.push({ name: "Intel® Active Management Technology (Intel® AMT)", html: x, img: 'amt' }); } + if (x != '') { + if ((typeof node.intelamt.sku == 'number') && ((node.intelamt.sku & 16) != 0)) { + sections.push({ name: "Intel® Standard Manageability (Intel® SM)", html: x, img: 'amt' }); + } else { + sections.push({ name: "Intel® Active Management Technology (Intel® AMT)", html: x, img: 'amt' }); + } + } } if (hardware.identifiers) { diff --git a/views/default.handlebars b/views/default.handlebars index b5000e5a..7bfaf286 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -112,6 +112,12 @@ + +
-
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
+
Redirection port or KVM feature is disabled, click here to enable it.
@@ -655,7 +661,7 @@ - + Disconnected
@@ -696,7 +702,7 @@ -   +   @@ -731,7 +737,7 @@
-
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
+
Redirection port or KVM feature is disabled, click here to enable it.
@@ -864,7 +870,7 @@
-

Intel® AMT -

+

Intel® AMT -

@@ -1323,6 +1329,7 @@
Other Settings
+ @@ -1346,6 +1353,7 @@ +
@@ -1379,6 +1387,7 @@ + @@ -1446,6 +1455,7 @@ var features = parseInt('{{{features}}}'); var features2 = parseInt('{{{features2}}}'); var sessionTime = parseInt('{{{sessiontime}}}'); + var webRelayPort = parseInt('{{{webRelayPort}}}'); var sessionRefreshTimer = null; var domain = '{{{domain}}}'; var domainUrl = '{{{domainurl}}}'; @@ -2316,7 +2326,8 @@ 18: "SMTP server has limited use in LAN mode.", 19: "SMS gateway has limited use in LAN mode.", 20: "Invalid \"LoginCookieEncryptionKey\" in config.json.", - 21: "Backup path can't be set within meshcentral-data folder, backup settings ignored." + 21: "Backup path can't be set within meshcentral-data folder, backup settings ignored.", + 22: "Failed to sign agent {0}: {1}" }; var x = ''; for (var i in message.warnings) { @@ -2325,7 +2336,7 @@ x += '
' + "WARNING: " + y + '
'; } else { var z = ServerWarnings[y.id]; - if (z == null) { z = y.msg; } else { z = format(z, y.args); } + if (z == null) { z = y.msg; } else { z = format(z, ...y.args); } x += '
' + "WARNING: " + z + '
'; } } @@ -2733,7 +2744,7 @@ if (message.name != null) { url += ('&name=' + encodeURIComponentEx(message.name)); } if (message.ip != null) { url += ('&remoteip=' + message.ip); } url += ('&appid=' + message.protocol + '&autoexit=1'); // Protocol: 0 = Custom, 1 = HTTP, 2 = HTTPS, 3 = RDP, 4 = PuTTY, 5 = WinSCP, 6 = MCRDesktop, 7 = MCRFiles - console.log(url); + //console.log(url); downloadFile(url, ''); } else if (message.tag == 'novnc') { var vncurl = window.location.origin + domainUrl + 'novnc/vnc.html?ws=wss%3A%2F%2F' + window.location.host + encodeURIComponentEx(domainUrl) + (message.localRelay?'local':'mesh') + 'relay.ashx%3Fauth%3D' + message.cookie + '&show_dot=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&l={{{lang}}}'; @@ -3235,6 +3246,8 @@ node.rdpport = message.event.node.rdpport; node.rfbport = message.event.node.rfbport; node.sshport = message.event.node.sshport; + node.httpport = message.event.node.httpport; + node.httpsport = message.event.node.httpsport; node.consent = message.event.node.consent; node.pmt = message.event.node.pmt; if (message.event.node.links != null) { node.links = message.event.node.links; } else { delete node.links; } @@ -4569,6 +4582,10 @@ // RDP link, show this link only of the remote machine is Windows. if ((((node.conn & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0) && (node.agent.id != 14)) { + if (webRelayPort != 0) { + x += '' + "HTTP" + ((node.httpport && (node.httpport != 80)) ? '/' + node.httpport : '') + ' '; + x += '' + "HTTPS" + ((node.httspport && (node.httpsport != 443)) ? '/' + node.httpsport : '') + ' '; + } if ((node.agent.id > 0) && (node.agent.id < 5)) { if (navigator.platform.toLowerCase() == 'win32') { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false)) { @@ -4579,12 +4596,12 @@ if (node.agent.id > 4) { if ((navigator.platform.toLowerCase() == 'win32') || (navigator.platform.toLowerCase() == 'macintel')) { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.ssh != false)) { - x += '' + "SSH" + ' '; + x += '' + "SSH" + ' '; } } if (navigator.platform.toLowerCase() == 'win32') { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.scp != false)) { - x += '' + "SCP" + ' '; + x += '' + "SCP" + ' '; } } } @@ -4851,6 +4868,7 @@ desk.m.ScalingLevel = multidesktopsettings.scaling; if (multidesktopsettings.framerate) { desk.m.FrameRateTimer = multidesktopsettings.framerate; } if (multidesktopsettings.swapmouse) { desk.m.SwapMouse = multidesktopsettings.swapmouse; } + if (multidesktopsettings.rmw) { desk.m.ReverseMouseWheel = multidesktopsettings.rmw; } if (multidesktopsettings.remotekeymap == true) { desk.m.remoteKeyMap = multidesktopsettings.remotekeymap; } //desk.m.onDisplayinfo = deskDisplayInfo; desk.m.onScreenSizeChange = mdeskAdjust; // Multi-Desktop Adjust @@ -5546,6 +5564,7 @@ var op = Q('d2deviceop').value, title = Q('dp2notifyTitle').value, msg = Q('d2notifyMsg').value, chkNodeIds = getCheckedDevices(); if (msg.length == 0) return; if (title == '') { title = decodeURIComponent('{{{extitle}}}'); } + if (title == '') { title = "MeshCentral"; } if (op == 1) { // MessageBox for (var i = 0; i < chkNodeIds.length; i++) { meshserver.send({ action: 'msg', type: 'messagebox', nodeid: chkNodeIds[i], title: title, msg: msg }); } } else if (op == 2) { // Toast @@ -6055,6 +6074,32 @@ if (currentNode.rfbport != null) { Q('d10rfbport').value = currentNode.rfbport; } } + function cmhttpportaction(action) { + if (xxdialogMode) return; + var x = "HTTP remote connection port:" + '

'; + setDialogMode(2, "HTTP Connection", 3, function() { + // Save the new HTTP port to the server + var httpport = ((Q('d10httpport').value.length > 0) ? parseInt(Q('d10httpport').value) : 80); + meshserver.send({ action: 'changedevice', nodeid: currentNode._id, httpport: httpport }); + //if (currentNode != null) { p10rfb(currentNode._id, httpport); } + }, x, currentNode); + Q('d10httpport').focus(); + if (currentNode.httpport != null) { Q('d10httpport').value = currentNode.httpport; } + } + + function cmhttpsportaction(action) { + if (xxdialogMode) return; + var x = "HTTPS remote connection port:" + '

'; + setDialogMode(2, "HTTPS Connection", 3, function() { + // Save the new HTTP port to the server + var httpsport = ((Q('d10httpsport').value.length > 0) ? parseInt(Q('d10httpsport').value) : 443); + meshserver.send({ action: 'changedevice', nodeid: currentNode._id, httpsport: httpsport }); + //if (currentNode != null) { p10rfb(currentNode._id, httpsport); } + }, x, currentNode); + Q('d10httpsport').focus(); + if (currentNode.httpsport != null) { Q('d10httpsport').value = currentNode.httpsport; } + } + function cmfilesaction(action) { if (xxdialogMode) return; var filetreexx = p13sort_files(p13filetree.dir); @@ -6144,6 +6189,8 @@ QV('altPortContextMenu', false); QV('rfbPortContextMenu', false); QV('sshPortContextMenu', false); + QV('httpPortContextMenu', false); + QV('httpsPortContextMenu', false); QV('filesContextMenu', false); QV('deskPlayerContextMenu', false); QV('deskKeyShortcutContextMenu', false); @@ -7066,7 +7113,7 @@ x += '
'; // Show action button, only show if we have permissions 4, 8, 64 - if (((meshrights & (4 + 8 + 64)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += ''; } + if (((meshrights & (4 + 8 + 64 + 262144)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += ''; } x += ''; x += ''; if (node.mtype != 4) { @@ -7135,22 +7182,26 @@ // RDP link, show this link only of the remote machine is Windows. if ((((connectivity & 1) != 0) || (node.mtype == 3)) && (node.agent) && ((meshrights & 8) != 0)) { + if (webRelayPort != 0) { + x += '' + "HTTP" + ((node.httpport && (node.httpport != 80)) ? '/' + node.httpport : '') + ' '; + x += '' + "HTTPS" + ((node.httpsport && (node.httpsport != 443)) ? '/' + node.httpsport : '') + ' '; + } if ((node.agent.id > 0) && (node.agent.id < 5)) { if (navigator.platform.toLowerCase() == 'win32') { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.rdp != false)) { - x += '' + "RDP" + ' '; + x += '' + "RDP" + ((node.rdpport && (node.rdpport != 3389)) ? '/' + node.rdpport : '') + ' '; } } } if (node.agent.id > 4) { if ((navigator.platform.toLowerCase() == 'win32') || (navigator.platform.toLowerCase() == 'macintel')) { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.ssh != false)) { - x += '' + "SSH" + ' '; + x += '' + "SSH" + ((node.sshport && (node.sshport != 22)) ? '/' + node.sshport : '') + ' '; } } if (navigator.platform.toLowerCase() == 'win32') { if ((serverinfo.devicemeshrouterlinks == null) || (serverinfo.devicemeshrouterlinks.scp != false)) { - x += '' + "SCP" + ' '; + x += '' + "SCP" + ((node.sshport && (node.sshport != 22)) ? '/' + node.sshport : '') + ' '; } } } @@ -7254,6 +7305,15 @@ QV('p15uploadCore', (node.agent != null) && (node.agent.caps != null) && ((node.agent.caps & 16) != 0)); QH('p15coreName', ((node.agent != null) && (node.agent.core != null))?node.agent.core:''); + // Set the Intel AMT / Intel SM tab name + if ((node.intelamt != null) && (typeof node.intelamt.sku == 'number') && ((node.intelamt.sku & 16) != 0)) { + QH('MainDevAmt', "Intel®SM"); + QH('p14deviceNamePrefix', "Intel® SM"); + } else { + QH('MainDevAmt', "Intel®AMT"); + QH('p14deviceNamePrefix', "Intel® AMT"); + } + // Setup/Refresh Intel AMT tab var amtFrameNode = Q('p14iframe').contentWindow.getCurrentMeshNode(); if ((amtFrameNode != null) && (amtFrameNode._id != currentNode._id)) { Q('p14iframe').contentWindow.disconnect(); } @@ -7585,10 +7645,12 @@ } function deviceMessageFunctionEx() { + var title = decodeURIComponent('{{{extitle}}}'); + if (title == '') { title = "MeshCentral"; } if (currentNode.pmt == 1) { - meshserver.send({ action: 'pushmessage', nodeid: currentNode._id, title: decodeURIComponent('{{{extitle}}}'), msg: Q('d2devMessage').value }); + meshserver.send({ action: 'pushmessage', nodeid: currentNode._id, title: title, msg: Q('d2devMessage').value }); } else { - meshserver.send({ action: 'msg', type: 'messagebox', nodeid: currentNode._id, title: decodeURIComponent('{{{extitle}}}'), msg: Q('d2devMessage').value }); + meshserver.send({ action: 'msg', type: 'messagebox', nodeid: currentNode._id, title: title, msg: Q('d2devMessage').value }); } } @@ -7749,12 +7811,15 @@ if (((currentNode.conn & 1) != 0) && ((rights & 131072) != 0)) { count++; y += ''; } // Remote command permission if ((currentNode.conn != 0) && ((rights & 262144) != 0)) { count++; y += ''; } if ((currentNode.conn & 16) != 0) { count++; y += ''; } - if ((currentNode.intelamt != null) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && (rights == 0xFFFFFFFF)) { + if ((currentNode.intelamt != null) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && ((rights & 262144) != 0)) { count++; y += ''; - y += ''; y += ''; } + if ((currentNode.intelamt != null) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && ((rights & 64) != 0)) { + count++; + y += ''; + } if ((getNodeAmtVersion(currentNode) >= 15) && (currentNode.intelamt.state == 2) && ((currentNode.conn & 6) != 0) && (rights == 0xFFFFFFFF) && ((features & 0x00000400) == 0)) { count++; y += ''; } // CIRA (2) or AMT (4) connected if (((currentNode.conn & 1) != 0) && ((rights & 32768) != 0)) { count++; y += ''; } } @@ -8043,6 +8108,22 @@ meshserver.send({ action: 'removedevices', nodeids: [ nodeid ] }); } + function p10WebRouter(nodeid, protocol, port, addr) { + var relayid = null; + var node = getNodeFromId(nodeid); + if (node.mtype == 3) { // Setup device relay if needed + var mesh = meshes[node.meshid]; + if (mesh && mesh.relayid) { relayid = mesh.relayid; addr = node.host; } + } + var servername = serverinfo.name; + if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name. + var url = 'https://' + servername + ':' + webRelayPort + '/control-redirect.ashx?n=' + nodeid + '&p=' + port + '&appid=' + protocol; // Protocol: 1 = HTTP, 2 = HTTPS + if (addr != null) { url += '&addr=' + addr; } + if (relayid != null) { url += '&relayid=' + relayid; } + safeNewWindow(url, 'WebRelay'); + return false; + } + function p10MCRouter(nodeid, protocol, port, addr, localport) { var node = getNodeFromId(nodeid); var mesh = meshes[node.meshid]; @@ -8370,7 +8451,7 @@ ); } // Show the right settings - QV('td7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (currentNode.agent == null))) && ((deskState == 0) || (desktop.contype == 2))); + QV('td7amtkvm', ((currentNode.intelamt != null) && ((typeof currentNode.intelamt.sku != 'number') || ((currentNode.intelamt.sku & 16) == 0)) && ((currentNode.intelamt.ver != null) || (currentNode.agent == null))) && ((deskState == 0) || (desktop.contype == 2))); QV('td7meshkvm', (webRtcDesktop) || ((currentNode.agent != null) && (currentNode.agent.caps & 1) && ((deskState == 0) || (desktop.contype == 1)))); QV('td7rdpkvm', ((currentNode.agent != null) && ((currentNode.agent.id == 3) || (currentNode.agent.id == 4)) && ((deskState == 0) || (desktop.contype == 4)))); @@ -8456,6 +8537,7 @@ desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2; desktop.m.useZRLE = (desktopsettings.encoding < 3); desktop.m.localKeyMap = desktopsettings.localkeymap; + desktop.m.ReverseMouseWheel = desktopsettings.kvmrmw; desktop.m.showmouse = desktopsettings.showmouse; desktop.m.onScreenSizeChange = deskAdjust; desktop.m.onKvmData = function (x) { @@ -8568,6 +8650,7 @@ desktop.m.ScalingLevel = desktopsettings.scaling; if (desktopsettings.framerate) { desktop.m.FrameRateTimer = desktopsettings.framerate; } if (desktopsettings.swapmouse) { desktop.m.SwapMouse = desktopsettings.swapmouse; } + if (desktopsettings.rmw) { desktop.m.ReverseMouseWheel = desktopsettings.rmw; } if (desktopsettings.remotekeymap == true) { desktop.m.remoteKeyMap = desktopsettings.remotekeymap; } desktop.m.onDisplayinfo = deskDisplayInfo; desktop.m.onScreenSizeChange = deskAdjust; @@ -8584,6 +8667,7 @@ desktop.m.onScreenSizeChange = mdeskAdjust; desktop.m.onClipboardChanged = function(text) { if ((text != null) && (desktopsettings.rdpautoclipboard) && (navigator.clipboard != null)) { navigator.clipboard.writeText(text).then(function() { }).catch(function(err) { console.log(err); }) } } // Put remote clipboard data into our clipboard if (desktopsettings.rdpsmb) { desktop.m.SwapMouse = desktopsettings.rdpsmb; } + if (desktopsettings.rdprmw) { desktop.m.ReverseMouseWheel = desktopsettings.rdprmw; } desktop.Start(desktopNode._id, currentNode.rdpport ? currentNode.rdpport : 3389, tsid); desktop.contype = 4; desktop.onConsoleMessageChange = function () { @@ -8866,12 +8950,15 @@ desktopsettings.scaling = d7bitmapscaling.value; desktopsettings.framerate = d7framelimiter.value; desktopsettings.swapmouse = d7deskSwapMouse.checked; + desktopsettings.rmw = d7deskrmw.checked; desktopsettings.remotekeymap = d7deskRemoteKeyMap.checked; desktopsettings.autoclipboard = d7deskAutoClipboard.checked; desktopsettings.autolock = d7deskAutoLock.checked; desktopsettings.localkeymap = d7localKeyMap.checked; + desktopsettings.kvmrmw = d7kvmrmw.checked; desktopsettings.rdpsize = d7rdpsize.value; desktopsettings.rdpsmb = d7rdpsmb.checked; + desktopsettings.rdprmw = d7rdprmw.checked; desktopsettings.rdpautoclipboard = d7rdpclip.checked; var rdpflags = 0; for (var i = 1; i < 10; i++) { if ((i != 5) && (Q('d7rdp' + i).checked)) { rdpflags |= (1 << (i - 1)); } } @@ -8880,23 +8967,29 @@ applyDesktopSettings(); updateDesktopButtons(); if (desktop) { - if (desktop.contype == 1) { + if (desktop.contype == 1) { // Intel AMT KVM desktop.m.SwapMouse = desktopsettings.swapmouse; + desktop.m.ReverseMouseWheel = desktopsettings.rmw; desktop.m.remoteKeyMap = desktopsettings.remotekeymap; if (desktop.State != 0) { desktop.m.SendCompressionLevel(webpSupport?4:1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate); desktop.sendCtrlMsg('{"ctrlChannel":"102938","type":"autolock","value":' + desktopsettings.autolock + '}'); } } - if (desktop.contype == 2) { + if (desktop.contype == 2) { // Mesh Agent Remote Desktop + desktop.m.ReverseMouseWheel = desktopsettings.kvmrmw; if (desktopsettings.showfocus == false) { desktop.m.focusmode = 0; deskFocusBtn.value = "All Focus"; } if (desktop.State != 0) { desktop.Stop(); setTimeout(function () { connectDesktop(null, 2); }, 50); } } + if (desktop.contype == 4) { // Web-RDP + desktop.m.SwapMouse = desktopsettings.rdpsmb; + desktop.m.ReverseMouseWheel = desktopsettings.rdprmw; + } } } function applyDesktopSettings() { - var r = '', ops = (features & 512)?[90,80,70,60,50,40,30,20,10,5,1]:[60,50,40,30,20,10,5,1]; + var r = '', ops = (features & 512)?[100,90,80,70,60,50,40,30,20,10,5,1]:[60,50,40,30,20,10,5,1]; for (var i in ops) { r += ''; } QH('d7bitmapquality', r); d7desktopmode.value = desktopsettings.encoding; @@ -8907,14 +9000,17 @@ d7bitmapscaling.value = desktopsettings.scaling; if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; } else { d7framelimiter.value = 100; } if (desktopsettings.swapmouse != null) { d7deskSwapMouse.checked = desktopsettings.swapmouse; } + if (desktopsettings.rmw != null) { d7deskrmw.checked = desktopsettings.rmw; } if (desktopsettings.remotekeymap != null) { d7deskRemoteKeyMap.checked = desktopsettings.remotekeymap; } if (desktopsettings.autoclipboard != null) { d7deskAutoClipboard.checked = desktopsettings.autoclipboard; } if (desktopsettings.autolock != null) { d7deskAutoLock.checked = desktopsettings.autolock; } if (desktopsettings.localkeymap) { d7localKeyMap.checked = desktopsettings.localkeymap; } + if (desktopsettings.kvmrmw) { d7kvmrmw.checked = desktopsettings.kvmrmw; } QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (desktop.state != 0) && (desktopsettings.showfocus)); if (desktopsettings.rdpsize != null) { d7rdpsize.value = desktopsettings.rdpsize; } if (desktopsettings.rdpflags == null) { desktopsettings.rdpflags = 0x2F; } if (desktopsettings.rdpsmb != null) { d7rdpsmb.checked = desktopsettings.rdpsmb; } + if (desktopsettings.rdprmw != null) { d7rdprmw.checked = desktopsettings.rdprmw; } if (desktopsettings.rdpautoclipboard != null) { d7rdpclip.checked = desktopsettings.rdpautoclipboard; } for (var i = 1; i < 10; i++) { if (i != 5) { Q('d7rdp' + i).checked = ((desktopsettings.rdpflags & (1 << (i - 1))) != 0); } } } @@ -9639,7 +9735,7 @@ // Enable action button if mesh type is not "local devices" QV('termActionsBtn', terminalNode.mtype != 3); - if (((termState == true) && (terminal.contype != 3)) || (terminalNode.agent.id == 3) || (terminalNode.agent.id == 4)) { + if (((termState == true) && (terminal.contype != 3)) || (terminalNode.agent == null) || (terminalNode.agent.id == 3) || (terminalNode.agent.id == 4)) { QH('terminalCustomUpperRight', ''); } else { QH('terminalCustomUpperRight', '' + format("SSH Port {0}", (terminalNode.sshport?terminalNode.sshport:22)) + ''); @@ -10431,7 +10527,7 @@ QE('p13PasteButton', advancedFeatures && ((p13filetreelocation.length > 0) || (winAgent == false)) && ((p13clipboard != null) && (p13clipboard.length > 0))); } var filesState = ((files != null) && (files.state != 0)); - if (((filesState == true) && (files.contype != 2)) || (filesNode.agent.id == 3) || (filesNode.agent.id == 4)) { + if (((filesState == true) && (files.contype != 2)) || (filesNode.agent == null) || (filesNode.agent.id == 3) || (filesNode.agent.id == 4)) { QH('filesCustomUpperRight', ''); } else { QH('filesCustomUpperRight', '' + format("SSH Port {0}", (filesNode.sshport?filesNode.sshport:22)) + ''); @@ -11130,20 +11226,13 @@ } } for (var j = 0; j < m.length; j++) { - var iplayer = m[j]; - if (iplayer.family == 'IPv4') { - if (iplayer.gateway && iplayer.netmask) { - x += addDetailItem("IPv4 Layer", format("IP: {0}, Mask: {1}, Gateway: {2}", EscapeHtml(iplayer.address), EscapeHtml(iplayer.netmask), EscapeHtml(iplayer.gateway))); - } else { - if (iplayer.address) { x += addDetailItem("IPv4 Layer", format("IP: {0}", EscapeHtml(iplayer.address))); } - } - } - if (iplayer.family == 'IPv6') { - if (iplayer.gateway && iplayer.netmask) { - x += addDetailItem("IPv6 Layer", format("IP: {0}, Mask: {1}, Gateway: {2}", EscapeHtml(iplayer.address), EscapeHtml(iplayer.netmask), EscapeHtml(iplayer.gateway))); - } else { - if (iplayer.address) { x += addDetailItem("IPv6 Layer", format("IP: {0}", EscapeHtml(iplayer.address))); } - } + var iplayer = m[j], items = []; + if (iplayer.address) { items.push(format("IP: {0}", EscapeHtml(iplayer.address))); } + if (iplayer.netmask) { items.push(format("Mask: {0}", EscapeHtml(iplayer.netmask))); } + if (iplayer.gateway) { items.push(format("Gateway: {0}", EscapeHtml(iplayer.gateway))); } + if (items.length > 0) { + if (iplayer.family == 'IPv4') { x += addDetailItem("IPv4 Layer", items.join(", ")); } + if (iplayer.family == 'IPv6') { x += addDetailItem("IPv6 Layer", items.join(", ")); } } } x += ''; @@ -11163,7 +11252,13 @@ x += addDetailItem("Security", (node.intelamt.tls == 1)?"Secured using TLS":"TLS is not setup", s); // Check that the Intel AMT user is setup and there is no warnings (1 = invalid credentials, 8 = trying) x += addDetailItem("Admin Credentials", ((node.intelamt.user) == null || (node.intelamt.user == '') || ((node.intelamt.warn != null) && ((node.intelamt.warn & 9) != 0)))?"Not Known":"Known", s); - if (x != '') { sections.push({ name: "Intel® Active Management Technology (Intel® AMT)", html: x, img: 'amt64.png' }); } + if (x != '') { + if ((typeof node.intelamt.sku == 'number') && ((node.intelamt.sku & 16) != 0)) { + sections.push({ name: "Intel® Standard Manageability (Intel® SM)", html: x, img: 'amt64.png' }); + } else { + sections.push({ name: "Intel® Active Management Technology (Intel® AMT)", html: x, img: 'amt64.png' }); + } + } } if (hardware.identifiers) { diff --git a/views/sharing-mobile.handlebars b/views/sharing-mobile.handlebars index 87bb00ce..e2ad0125 100644 --- a/views/sharing-mobile.handlebars +++ b/views/sharing-mobile.handlebars @@ -1188,7 +1188,7 @@ } function applyDesktopSettings() { - var r = '', ops = (features & 512) ? [90, 70, 50, 40, 30, 20, 10, 5, 1] : [50, 40, 30, 20, 10, 5, 1]; + var r = '', ops = (features & 512) ? [100, 90, 70, 50, 40, 30, 20, 10, 5, 1] : [50, 40, 30, 20, 10, 5, 1]; for (var i in ops) { r += ''; } QH('d7bitmapquality', r); d7desktopmode.value = desktopsettings.encoding; diff --git a/views/sharing.handlebars b/views/sharing.handlebars index ca10d11a..4208d680 100644 --- a/views/sharing.handlebars +++ b/views/sharing.handlebars @@ -780,7 +780,7 @@ } function applyDesktopSettings() { - var r = '', ops = (features2 & 1) ? [90, 80, 70, 60, 50, 40, 30, 20, 10, 5, 1] : [60, 50, 40, 30, 20, 10, 5, 1] + var r = '', ops = (features2 & 1) ? [100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 5, 1] : [60, 50, 40, 30, 20, 10, 5, 1] for (var i in ops) { r += ''; } QH('d7bitmapquality', r); d7desktopmode.value = desktopsettings.encoding; diff --git a/webrelayserver.js b/webrelayserver.js new file mode 100644 index 00000000..15d7334c --- /dev/null +++ b/webrelayserver.js @@ -0,0 +1,272 @@ +/** +* @description Meshcentral web relay server +* @author Ylian Saint-Hilaire +* @copyright Intel Corporation 2018-2022 +* @license Apache-2.0 +* @version v0.0.1 +*/ + +/*jslint node: true */ +/*jshint node: true */ +/*jshint strict:false */ +/*jshint -W097 */ +/*jshint esversion: 6 */ +"use strict"; + +// Construct a HTTP redirection web server object +module.exports.CreateWebRelayServer = function (parent, db, args, certificates, func) { + var obj = {}; + obj.parent = parent; + obj.db = db; + obj.express = require('express'); + obj.session = require('cookie-session'); + obj.expressWs = null; + obj.tlsServer = null; + obj.net = require('net'); + obj.app = obj.express(); + if (args.compression !== false) { obj.app.use(require('compression')()); } + obj.app.disable('x-powered-by'); + obj.webRelayServer = null; + obj.port = 0; + obj.cleanupTimer = null; + var nextSessionId = 1; + var relaySessions = {} // RelayID --> Web Mutli-Tunnel + const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. + var tlsSessionStore = {}; // Store TLS session information for quick resume. + var tlsSessionStoreCount = 0; // Number of cached TLS session information in store. + + function serverStart() { + if (args.trustedproxy) { + // Reverse proxy should add the "X-Forwarded-*" headers + try { + obj.app.set('trust proxy', args.trustedproxy); + } catch (ex) { + // If there is an error, try to resolve the string + if ((args.trustedproxy.length == 1) && (typeof args.trustedproxy[0] == 'string')) { + require('dns').lookup(args.trustedproxy[0], function (err, address, family) { if (err == null) { obj.app.set('trust proxy', address); args.trustedproxy = [address]; } }); + } + } + } + else if (typeof args.tlsoffload == 'object') { + // Reverse proxy should add the "X-Forwarded-*" headers + try { + obj.app.set('trust proxy', args.tlsoffload); + } catch (ex) { + // If there is an error, try to resolve the string + if ((Array.isArray(args.tlsoffload)) && (args.tlsoffload.length == 1) && (typeof args.tlsoffload[0] == 'string')) { + require('dns').lookup(args.tlsoffload[0], function (err, address, family) { if (err == null) { obj.app.set('trust proxy', address); args.tlsoffload = [address]; } }); + } + } + } + + // Setup cookie session + var sessionOptions = { + name: 'xid', // Recommended security practice to not use the default cookie name + httpOnly: true, + keys: [args.sessionkey], // If multiple instances of this server are behind a load-balancer, this secret must be the same for all instances + secure: (args.tlsoffload == null), // Use this cookie only over TLS (Check this: https://expressjs.com/en/guide/behind-proxies.html) + sameSite: args.sessionsamesite + } + if (args.sessiontime != null) { sessionOptions.maxAge = (args.sessiontime * 60 * 1000); } + obj.app.use(obj.session(sessionOptions)); + + // Add HTTP security headers to all responses + obj.app.use(function (req, res, next) { + parent.debug('webrequest', req.url + ' (RelayServer)'); + res.removeHeader('X-Powered-By'); + res.set({ + 'strict-transport-security': 'max-age=60000; includeSubDomains', + 'Referrer-Policy': 'no-referrer', + 'x-frame-options': 'SAMEORIGIN', + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'Content-Security-Policy': "default-src 'none'; style-src 'self' 'unsafe-inline';" + }); + + // Set the real IP address of the request + // If a trusted reverse-proxy is sending us the remote IP address, use it. + var ipex = '0.0.0.0', xforwardedhost = req.headers.host; + if (typeof req.connection.remoteAddress == 'string') { ipex = (req.connection.remoteAddress.startsWith('::ffff:')) ? req.connection.remoteAddress.substring(7) : req.connection.remoteAddress; } + if ( + (args.trustedproxy === true) || (args.tlsoffload === true) || + ((typeof args.trustedproxy == 'object') && (isIPMatch(ipex, args.trustedproxy))) || + ((typeof args.tlsoffload == 'object') && (isIPMatch(ipex, args.tlsoffload))) + ) { + // Get client IP + if (req.headers['cf-connecting-ip']) { // Use CloudFlare IP address if present + req.clientIp = req.headers['cf-connecting-ip'].split(',')[0].trim(); + } else if (req.headers['x-forwarded-for']) { + req.clientIp = req.headers['x-forwarded-for'].split(',')[0].trim(); + } else if (req.headers['x-real-ip']) { + req.clientIp = req.headers['x-real-ip'].split(',')[0].trim(); + } else { + req.clientIp = ipex; + } + + // If there is a port number, remove it. This will only work for IPv4, but nice for people that have a bad reverse proxy config. + const clientIpSplit = req.clientIp.split(':'); + if (clientIpSplit.length == 2) { req.clientIp = clientIpSplit[0]; } + + // Get server host + if (req.headers['x-forwarded-host']) { xforwardedhost = req.headers['x-forwarded-host'].split(',')[0]; } // If multiple hosts are specified with a comma, take the first one. + } else { + req.clientIp = ipex; + } + + // If this is a session start or a websocket, have the application handle this + if ((req.headers.upgrade == 'websocket') || (req.url.startsWith('/control-redirect.ashx?n='))) { + return next(); + } else { + // If this is a normal request (GET, POST, etc) handle it here + if ((req.session.userid != null) && (req.session.rid != null)) { + var relaySession = relaySessions[req.session.userid + '/' + req.session.rid]; + if (relaySession != null) { + // The web relay session is valid, use it + relaySession.handleRequest(req, res); + } else { + // No web relay ession with this relay identifier, close the HTTP request. + res.end(); + } + } else { + // The user is not logged in or does not have a relay identifier, close the HTTP request. + res.end(); + } + } + }); + + // Start the server, only after users and meshes are loaded from the database. + if (args.tlsoffload) { + // Setup the HTTP server without TLS + obj.expressWs = require('express-ws')(obj.app, null, { wsOptions: { perMessageDeflate: (args.wscompression === true) } }); + } else { + // Setup the HTTP server with TLS, use only TLS 1.2 and higher with perfect forward secrecy (PFS). + const tlsOptions = { cert: certificates.web.cert, key: certificates.web.key, ca: certificates.web.ca, rejectUnauthorized: true, ciphers: "HIGH:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_CHACHA20_POLY1305_SHA256", secureOptions: constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_COMPRESSION | constants.SSL_OP_CIPHER_SERVER_PREFERENCE | constants.SSL_OP_NO_TLSv1 | constants.SSL_OP_NO_TLSv1_1 }; + obj.tlsServer = require('https').createServer(tlsOptions, obj.app); + obj.tlsServer.on('secureConnection', function () { /*console.log('tlsServer secureConnection');*/ }); + obj.tlsServer.on('error', function (err) { console.log('tlsServer error', err); }); + obj.tlsServer.on('newSession', function (id, data, cb) { if (tlsSessionStoreCount > 1000) { tlsSessionStoreCount = 0; tlsSessionStore = {}; } tlsSessionStore[id.toString('hex')] = data; tlsSessionStoreCount++; cb(); }); + obj.tlsServer.on('resumeSession', function (id, cb) { cb(null, tlsSessionStore[id.toString('hex')] || null); }); + obj.expressWs = require('express-ws')(obj.app, obj.tlsServer, { wsOptions: { perMessageDeflate: (args.wscompression === true) } }); + } + + // Handle incoming web socket calls + obj.app.ws('/*', function (ws, req) { + if ((req.session.userid != null) && (req.session.rid != null)) { + var relaySession = relaySessions[req.session.userid + '/' + req.session.rid]; + if (relaySession != null) { + // The multi-tunnel session is valid, use it + relaySession.handleWebSocket(ws, req); + } else { + // No multi-tunnel session with this relay identifier, close the websocket. + ws.close(); + } + } else { + // The user is not logged in or does not have a relay identifier, close the websocket. + ws.close(); + } + }); + + // This is the magic URL that will setup the relay session + obj.app.get('/control-redirect.ashx', function (req, res) { + if ((req.session == null) || (req.session.userid == null)) { res.redirect('/'); return; } + res.set({ 'Cache-Control': 'no-store' }); + parent.debug('web', 'webRelaySetup'); + + // Check that all the required arguments are present + if ((req.session.userid == null) || (req.query.n == null) || (req.query.p == null) || ((req.query.appid != 1) && (req.query.appid != 2))) { res.redirect('/'); return; } + + // Get the user and domain information + const userid = req.session.userid; + const domainid = userid.split('/')[1]; + const domain = parent.config.domains[domainid]; + const nodeid = ((req.query.relayid != null) ? req.query.relayid : req.query.n); + const addr = (req.query.addr != null) ? req.query.addr : '127.0.0.1'; + const port = parseInt(req.query.p); + const appid = parseInt(req.query.appid); + + // Check to see if we already have a multi-relay session that matches exactly this device and port for this user + var relaySession = null; + for (var i in relaySessions) { + const xrelaySession = relaySessions[i]; + if ((xrelaySession.domain.id == domain.id) && (xrelaySession.userid == userid) && (xrelaySession.nodeid == nodeid) && (xrelaySession.addr == addr) && (xrelaySession.port == port) && (xrelaySession.appid == appid)) { + relaySession = xrelaySession; // We found an exact match + } + } + + if (relaySession != null) { + // Since we found a match, use it + req.session.rid = relaySession.sessionId; + } else { + // Create a web relay session + relaySession = require('./apprelays.js').CreateWebRelaySession(parent, db, req, args, domain, userid, nodeid, addr, port, appid); + relaySession.onclose = function (sessionId) { + // Remove the relay session + delete relaySessions[sessionId]; + // If there are not more relay sessions, clear the cleanup timer + if ((Object.keys(relaySessions).length == 0) && (obj.cleanupTimer != null)) { clearInterval(obj.cleanupTimer); obj.cleanupTimer = null; } + } + relaySession.sessionId = nextSessionId++; + + // Set the multi-tunnel session + relaySessions[userid + '/' + relaySession.sessionId] = relaySession; + req.session.rid = relaySession.sessionId; + + // Setup the cleanup timer if needed + if (obj.cleanupTimer == null) { obj.cleanupTimer = setInterval(checkTimeout, 10000); } + } + + // Redirect to root + res.redirect('/'); + }); + } + + // Check that everything is cleaned up + function checkTimeout() { + for (var i in relaySessions) { relaySessions[i].checkTimeout(); } + } + + // Find a free port starting with the specified one and going up. + function CheckListenPort(port, addr, func) { + var s = obj.net.createServer(function (socket) { }); + obj.webRelayServer = s.listen(port, addr, function () { s.close(function () { if (func) { func(port, addr); } }); }).on("error", function (err) { + if (args.exactports) { console.error("ERROR: MeshCentral HTTP relay server port " + port + " not available."); process.exit(); } + else { if (port < 65535) { CheckListenPort(port + 1, addr, func); } else { if (func) { func(0); } } } + }); + } + + // Start the ExpressJS web server, if the port is busy try the next one. + function StartWebRelayServer(port, addr) { + if (port == 0 || port == 65535) { return; } + if (obj.tlsServer != null) { + if (args.lanonly == true) { + obj.tcpServer = obj.tlsServer.listen(port, addr, function () { console.log('MeshCentral HTTPS relay server running on port ' + port + ((args.aliasport != null) ? (', alias port ' + args.aliasport) : '') + '.'); }); + } else { + obj.tcpServer = obj.tlsServer.listen(port, addr, function () { console.log('MeshCentral HTTPS relay server running on ' + certificates.CommonName + ':' + port + ((args.aliasport != null) ? (', alias port ' + args.aliasport) : '') + '.'); }); + obj.parent.updateServerState('servername', certificates.CommonName); + } + if (obj.parent.authlog) { obj.parent.authLog('https', 'Web relay server listening on ' + ((addr != null) ? addr : '0.0.0.0') + ' port ' + port + '.'); } + obj.parent.updateServerState('https-relay-port', port); + if (args.aliasport != null) { obj.parent.updateServerState('https-relay-aliasport', args.aliasport); } + } else { + obj.tcpServer = obj.app.listen(port, addr, function () { console.log('MeshCentral HTTP relay server running on port ' + port + ((args.aliasport != null) ? (', alias port ' + args.aliasport) : '') + '.'); }); + obj.parent.updateServerState('http-relay-port', port); + if (args.aliasport != null) { obj.parent.updateServerState('http-relay-aliasport', args.aliasport); } + } + obj.port = port; + } + + function getRandomPassword() { return Buffer.from(require('crypto').randomBytes(9), 'binary').toString('base64').split('/').join('@'); } + + // Perform a IP match against a list + function isIPMatch(ip, matchList) { + const ipcheck = require('ipcheck'); + for (var i in matchList) { if (ipcheck.match(ip, matchList[i]) == true) return true; } + return false; + } + + // Start up the web relay server + serverStart(); + CheckListenPort(args.relayport, args.relayportbind, StartWebRelayServer); + + return obj; +}; diff --git a/webserver.js b/webserver.js index b4b6be3e..70b57ff6 100644 --- a/webserver.js +++ b/webserver.js @@ -2858,7 +2858,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF footer: (domain.footer == null) ? '' : domain.footer, webstate: encodeURIComponent(webstate).replace(/'/g, '%27'), amtscanoptions: amtscanoptions, - pluginHandler: (parent.pluginHandler == null) ? 'null' : parent.pluginHandler.prepExports() + pluginHandler: (parent.pluginHandler == null) ? 'null' : parent.pluginHandler.prepExports(), + webRelayPort: ((parent.webrelayserver != null) ? parent.webrelayserver.port : 0) }, dbGetFunc.req, domain), user); } xdbGetFunc.req = req; @@ -5846,11 +5847,19 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF var selfurl = ' wss://' + req.headers.host; if ((xforwardedhost != null) && (xforwardedhost != req.headers.host)) { selfurl += ' wss://' + xforwardedhost; } const extraScriptSrc = (parent.config.settings.extrascriptsrc != null) ? (' ' + parent.config.settings.extrascriptsrc) : ''; + + // If the web relay port is enabled, allow the web page to redirect to it + var extraFrameSrc = ''; + if ((parent.webrelayserver != null) && (parent.webrelayserver.port != 0)) { + extraFrameSrc = ' https://' + req.headers.host + ':' + parent.webrelayserver.port; + if ((xforwardedhost != null) && (xforwardedhost != req.headers.host)) { extraFrameSrc += ' https://' + xforwardedhost + ':' + parent.webrelayserver.port; } + } + const headers = { 'Referrer-Policy': 'no-referrer', 'X-XSS-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', - 'Content-Security-Policy': "default-src 'none'; font-src 'self'; script-src 'self' 'unsafe-inline'" + extraScriptSrc + "; connect-src 'self'" + geourl + selfurl + "; img-src 'self' blob: data:" + geourl + " data:; style-src 'self' 'unsafe-inline'; frame-src 'self' mcrouter:; media-src 'self'; form-action 'self'" + 'Content-Security-Policy': "default-src 'none'; font-src 'self'; script-src 'self' 'unsafe-inline'" + extraScriptSrc + "; connect-src 'self'" + geourl + selfurl + "; img-src 'self' blob: data:" + geourl + " data:; style-src 'self' 'unsafe-inline'; frame-src 'self' mcrouter:" + extraFrameSrc + "; media-src 'self'; form-action 'self'" }; if (req.headers['user-agent'] && (req.headers['user-agent'].indexOf('Chrome') >= 0)) { headers['Permissions-Policy'] = 'interest-cohort=()'; } // Remove Google's FLoC Network, only send this if Chrome browser if ((parent.config.settings.allowframing !== true) && (typeof parent.config.settings.allowframing !== 'string')) { headers['X-Frame-Options'] = 'sameorigin'; } @@ -6063,7 +6072,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF obj.app.ws(url + 'mstscrelay.ashx', function (ws, req) { const domain = getDomain(req); if (domain == null) { parent.debug('web', 'mstsc: failed checks.'); try { ws.close(); } catch (e) { } return; } - require('./apprelays.js').CreateMstscRelay(obj, obj.db, ws, req, obj.args, domain); + // If no user is logged in and we have a default user, set it now. + if ((req.session.userid == null) && (typeof obj.args.user == 'string') && (obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()])) { req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase(); } + try { require('./apprelays.js').CreateMstscRelay(obj, obj.db, ws, req, obj.args, domain); } catch (ex) { console.log(ex); } }); } @@ -6073,9 +6084,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF obj.app.ws(url + 'sshrelay.ashx', function (ws, req) { const domain = getDomain(req); if (domain == null) { parent.debug('web', 'ssh: failed checks.'); try { ws.close(); } catch (e) { } return; } - try { - require('./apprelays.js').CreateSshRelay(obj, obj.db, ws, req, obj.args, domain); - } catch (ex) { console.log(ex); } + // If no user is logged in and we have a default user, set it now. + if ((req.session.userid == null) && (typeof obj.args.user == 'string') && (obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()])) { req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase(); } + try { require('./apprelays.js').CreateSshRelay(obj, obj.db, ws, req, obj.args, domain); } catch (ex) { console.log(ex); } }); obj.app.ws(url + 'sshterminalrelay.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {