...
 
Commits (6)
......@@ -6,4 +6,5 @@ storage.db
src/server/mods/iwd-*
!helpers/item-tooltip/styles.css
!helpers/passives/**/*.css
helpers/cli/downloads/*.*
creds.js
const fs = require('fs');
const util = require('util');
const clientScp = require('scp2');
const clientSsh = require('node-ssh');
const clone = require('../../src/server/misc/clone.js');
let key = fs.readFileSync('C:/Users/Shaun/.ssh/id_rsa').toString();
module.exports = {
ssh: null,
init: async function (server) {
this.ssh = new clientSsh();
await this.ssh.connect({
host: `${server}.isleward.com`,
username: 'isleward',
port: 4194,
privateKey: key
});
},
downloadFile: async function (server, source, target) {
let config = clone({}, {
host: `${server}.isleward.com`,
username: 'isleward',
privateKey: key,
port: 4194,
path: source
});
await util.promisify(clientScp.scp)(config, target);
},
execCommands: async function (commands) {
const cbExecCommand = this.execCommand.bind(this);
return new Promise(async function (res) {
let output = '';
for (let command of commands)
output += await cbExecCommand(command);
res(output);
});
},
execCommand: async function (command) {
return (await this.ssh.execCommand(command)).stdout;
},
onError: function (err) {
}
};
This diff is collapsed.
TypeError: Cannot read property 'amount' of undefined
config/itemEffects/gainStat.js:22:36
components/inventory.js:794:35
components/inventory.js:784:17
components/workbench.js:156:17
objects/objBase.js:206:21
world/instancer.js:194:8
world/worker.js:94:22
TypeError: Cannot read property 'amount' of undefined
config/itemEffects/gainStat.js:22:36
components/inventory.js:794:35
components/inventory.js:784:17
components/workbench.js:156:17
objects/objBase.js:206:21
world/instancer.js:194:8
world/worker.js:94:22
TypeError: Cannot read property 'length' of undefined
world/syncer.js:125:11
components/wardrobe.js:106:11
objects/objBase.js:206:21
world/instancer.js:194:8
world/worker.js:94:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: node.isWall is not a function
world/physics.js:318:16
objects/objBase.js:247:16
objects/objBase.js:230:23
objects/objBase.js:76:9
objects/objects.js:295:7
world/instancer.js:241:22
TypeError: Cannot read property 'has' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:180:7
world/worker.js:94:22
TypeError: Cannot read property 'has' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:180:7
world/worker.js:94:22
TypeError: Cannot read property 'has' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:179:7
world/worker.js:94:22
TypeError: Cannot read property 'has' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:179:7
world/worker.js:94:22
leaderboard/leaderboard.js:124:3
components/auth.js:468:21
TypeError: Cannot read property 'has' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:179:7
world/worker.js:94:22
TypeError: Cannot read property 'has' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:179:7
world/worker.js:94:22
23399Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:93:19
security/io.js:238:12
23399Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:93:19
security/io.js:238:12
23399Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:93:19
security/io.js:238:12
23399Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:93:19
security/io.js:238:12
23399Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:93:19
security/io.js:238:12
23399Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:93:19
security/io.js:238:12
TypeError: Cannot read property 'id' of undefined
components/equipment.js:177:13
components/equipment.js:113:9
objects/objBase.js:213:21
world/instancer.js:179:7
world/worker.js:94:22
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
TypeError: Cannot read property 'gainStats' of undefined
components/stats.js:462:51
components/stats.js:290:9
components/stats.js:373:17
components/stats.js:536:23
config/spells/spellProjectile.js:105:16
components/spellbook.js:472:8
objects/objBase.js:70:11
objects/objects.js:295:7
world/instancer.js:73:11
TypeError: Cannot read property 'gainStats' of undefined
components/stats.js:462:51
components/stats.js:290:9
components/stats.js:373:17
components/stats.js:536:23
config/spells/spellProjectile.js:105:16
components/spellbook.js:472:8
objects/objBase.js:70:11
objects/objects.js:295:7
world/instancer.js:73:11
TypeError: Cannot read property 'gainStats' of undefined
components/stats.js:462:51
components/stats.js:290:9
components/stats.js:373:17
components/stats.js:536:23
config/spells/spellProjectile.js:105:16
components/spellbook.js:472:8
objects/objBase.js:70:11
objects/objects.js:295:7
world/instancer.js:73:11
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
27902Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
TypeError: Cannot read property 'gainStats' of undefined
components/stats.js:462:51
components/stats.js:290:9
components/stats.js:373:17
components/stats.js:536:23
config/spells/spellProjectile.js:105:16
components/spellbook.js:472:8
objects/objBase.js:70:11
objects/objects.js:295:7
world/instancer.js:73:11
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
Forbidden
server.js:84:8
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
28368Channel Closed
world/atlas.js:107:18
world/atlas.js:30:8
components/player.js:109:9
components/auth.js:91:19
\ No newline at end of file
const fs = require('fs');
const exec = require('child_process').exec;
let client = require('./client');
let startup = {
init: async function (cmd, pars) {
if (['uptime', 'mem'].indexOf(cmd) > -1)
await client.init(pars);
await this[cmd](pars);
process.exit();
},
mem: async function (serverName) {
let output = await client.execCommands([
'free -m'
]);
output = output
.split('\n')
[1]
.split(' ')
.filter(f => f.length);
const total = ~~output[1] + ~~output[2];
const percentage = ~~((~~output[1] / total) * 100);
console.log(`${output[1]}mb / ${total}mb (${percentage}% Used)`);
},
uptime: async function (serverName) {
let output = await client.execCommands([
'forever list --no-colors'
]);
output = output
.split('\n')
.pop()
.split(' ')
.pop()
.split(':');
console.log([
'D',
'H',
'M',
'S'
].map((m, i) => output[i] + m).join(' '));
},
db: async function (serverName) {
const targetFilename = '../../data/storage.db';
await client.downloadFile(serverName, '/opt/stagecoach/apps/isleward/current/data/storage.db', targetFilename);
},
log: async function (serverName) {
const targetFilename = `./downloads/${serverName}Log.log`;
await client.downloadFile(serverName, '.forever/isleward.log', targetFilename);
let contents = fs
.readFileSync(targetFilename)
.toString()
.split('\n')
.filter(c => {
return (
(
c.indexOf('Error Logged:') > -1 ||
c.indexOf('ERR_IPC_CHANNEL_CLOSED') > -1 ||
c.indexOf('ForbiddenError: Forbidden') > -1 ||
(
c.indexOf(' at ') > -1 &&
c.indexOf('/src/') > -1
)
) &&
c.indexOf('node_modules') === -1
);
})
.map(c => {
let res = c
.replace('Error Logged: ', '\n')
.replace(' UnhandledPromiseRejectionWarning: Error [ERR_IPC_CHANNEL_CLOSED]: channel closed', 'Channel Closed')
.replace(')', '')
.replace('(node:', '\n')
.replace('ForbiddenError: ', '\n');
res = res.split('/src/server/');
res = (res.length > 1) ? res[1] : res[0];
return res;
});
fs.writeFileSync(targetFilename, contents.join('\n'));
exec(`"C:/Program Files/Sublime Text 3/sublime_text.exe" ${targetFilename}`);
}
};
let args = process.argv;
startup.init(args[2], args[3]);
{
"version": "0.0.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"requires": {
"safer-buffer": "2.1.2"
}
},
"async": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"glob": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
"integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"lodash": {
"version": "4.11.2",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.11.2.tgz",
"integrity": "sha1-1rQzixEKWOIdrlzrz9u/0rxM2zs="
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "1.1.11"
}
},
"node-ssh": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/node-ssh/-/node-ssh-5.1.2.tgz",
"integrity": "sha512-Z1dXZzKthWELy7/+obyQmxgci8UNS89bzvKMdNTynskt5QWrhXhry0GdfH4kmqyKUo2BB3JELIQDk+6mSJLylA==",
"requires": {
"p-map": "1.2.0",
"sb-promisify": "2.0.2",
"sb-scandir": "2.0.0",
"shell-escape": "0.2.0",
"ssh2": "0.5.5"
},
"dependencies": {
"ssh2": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.5.tgz",
"integrity": "sha1-x3gezS7OcwSiU89iD6taXCK7IjU=",
"requires": {
"ssh2-streams": "0.1.20"
}
},
"ssh2-streams": {
"version": "0.1.20",
"resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.20.tgz",
"integrity": "sha1-URGNFUVV31Rp7h9n4M8efoosDjo=",
"requires": {
"asn1": "0.2.4",
"semver": "5.5.1",
"streamsearch": "0.1.2"
}
}
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1.0.2"
}
},
"p-map": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
"integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA=="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"readable-stream": {
"version": "1.0.34",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "0.0.1",
"string_decoder": "0.10.31"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sb-promisify": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/sb-promisify/-/sb-promisify-2.0.2.tgz",
"integrity": "sha1-QnelR1RIiqlnXYhuNU24lMm9yYE="
},
"sb-scandir": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/sb-scandir/-/sb-scandir-2.0.0.tgz",
"integrity": "sha512-SKbyMJB0DUt9OgN4tP2RBcn9OsR26DEpe+nwaDkQTNcrJSJI0FlLhXhBpTd/YEnlQ2GdLrbszSNekGLw4rweOQ==",
"requires": {
"p-map": "1.2.0",
"sb-promisify": "2.0.2"
}
},
"scp2": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/scp2/-/scp2-0.5.0.tgz",
"integrity": "sha1-ZO50vDaF86TGKQ8tqMHjtO75Lo0=",
"requires": {
"async": "0.9.2",
"glob": "7.0.6",
"lodash": "4.11.2",
"ssh2": "0.4.15"
}
},
"semver": {
"version": "5.5.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
"integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw=="
},
"shell-escape": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/shell-escape/-/shell-escape-0.2.0.tgz",
"integrity": "sha1-aP0CXrBJC09WegJ/C/IkgLX4QTM="
},
"ssh2": {
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.4.15.tgz",
"integrity": "sha1-B8b0EG2fe26m5N9jbGxT8fmBf/g=",
"requires": {
"readable-stream": "1.0.34",
"ssh2-streams": "0.0.23"
}
},
"ssh2-streams": {
"version": "0.0.23",
"resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.0.23.tgz",
"integrity": "sha1-ru8wgxu1/Er2qj9tCiYaQTUxYSs=",
"requires": {
"asn1": "0.2.4",
"readable-stream": "1.0.34",
"streamsearch": "0.1.2"
}
},
"streamsearch": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}
{
"name": "",
"version": "0.0.1",
"description": "",
"dependencies": {
"node-ssh": "^5.1.2",
"scp2": "^0.5.0"
}
}