PHP WebShell
Текущая директория: /opt/BitGoJS/modules/express/dist/test/unit
Просмотр файла: bitgoExpress.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const should = require("should");
require("should-http");
require("should-sinon");
require("../lib/asserts");
const nock = require("nock");
const sinon = require("sinon");
const fs = require("fs");
const http = require("http");
const https = require("https");
const debugLib = require("debug");
const path = require("path");
const bitgo_1 = require("bitgo");
const constants_1 = require("constants");
const errors_1 = require("../../src/errors");
nock.disableNetConnect();
const expressApp_1 = require("../../src/expressApp");
const clientRoutes = require("../../src/clientRoutes");
describe('Bitgo Express', function () {
describe('server initialization', function () {
const validPrvJSON = '{"61f039aad587c2000745c687373e0fa9":"xprv9s21ZrQH143K3EuPWCBuqnWxydaQV6et9htQige4EswvcHKEzNmkVmwTwKoadyHzJYppuADB7Us7AbaNLToNvoFoSxuWqndQRYtnNy5DUY2"}';
const validLightningSignerConfigJSON = '{"fakeid":{"url": "https://127.0.0.1:8080","tlsCert":"dummy"}}';
it('should require NODE_ENV to be production when running against prod env', function () {
const envStub = sinon.stub(process, 'env').value({ NODE_ENV: 'production' });
try {
(() => (0, expressApp_1.app)({
env: 'prod',
bind: 'localhost',
})).should.not.throw();
process.env.NODE_ENV = 'dev';
(() => (0, expressApp_1.app)({
env: 'prod',
bind: 'localhost',
})).should.throw(errors_1.NodeEnvironmentError);
}
finally {
envStub.restore();
}
});
it('should disable NODE_ENV check if disableenvcheck argument is given', function () {
const envStub = sinon.stub(process, 'env').value({ NODE_ENV: 'dev' });
try {
(() => (0, expressApp_1.app)({
env: 'prod',
bind: 'localhost',
disableEnvCheck: true,
})).should.not.throw();
}
finally {
envStub.restore();
}
});
it('should require TLS for prod env when listening on external interfaces', function () {
const args = {
env: 'prod',
bind: '1',
disableEnvCheck: true,
disableSSL: false,
crtPath: undefined,
keyPath: undefined,
};
(() => (0, expressApp_1.app)(args)).should.throw(errors_1.TlsConfigurationError);
args.bind = 'localhost';
(() => (0, expressApp_1.app)(args)).should.not.throw();
args.bind = '1';
args.env = 'test';
(() => (0, expressApp_1.app)(args)).should.not.throw();
args.disableSSL = true;
args.env = 'prod';
(() => (0, expressApp_1.app)(args)).should.not.throw();
delete args.disableSSL;
args.crtPath = '/tmp/cert.pem';
(() => (0, expressApp_1.app)(args)).should.throw(errors_1.TlsConfigurationError);
delete args.crtPath;
args.keyPath = '/tmp/key.pem';
(() => (0, expressApp_1.app)(args)).should.throw(errors_1.TlsConfigurationError);
});
it('should require both keypath and crtpath when using TLS, but TLS is not required', function () {
const args = {
env: 'test',
bind: '1',
keyPath: '/tmp/key.pem',
crtPath: undefined,
};
(() => (0, expressApp_1.app)(args)).should.throw(errors_1.TlsConfigurationError);
delete args.keyPath;
args.crtPath = '/tmp/cert.pem';
(() => (0, expressApp_1.app)(args)).should.throw(errors_1.TlsConfigurationError);
});
it('should create an http server when not using TLS', async function () {
const createServerStub = sinon.stub(http, 'createServer');
const args = {
env: 'prod',
bind: 'localhost',
};
(0, expressApp_1.createServer)(args, null);
createServerStub.should.be.calledOnce();
createServerStub.restore();
});
it('should create an https server when using TLS', async function () {
const createServerStub = sinon.stub(https, 'createServer');
const readFileAsyncStub = sinon
.stub(fs.promises, 'readFile')
.onFirstCall()
.resolves('key')
.onSecondCall()
.resolves('cert');
const args = {
env: 'prod',
bind: '1.2.3.4',
crtPath: '/tmp/crt.pem',
keyPath: '/tmp/key.pem',
};
await (0, expressApp_1.createServer)(args, null);
https.createServer.should.be.calledOnce();
https.createServer.should.be.calledWith({ secureOptions: constants_1.SSL_OP_NO_TLSv1, key: 'key', cert: 'cert' });
createServerStub.restore();
readFileAsyncStub.restore();
});
it('should create https server with sslkey and sslcert', async () => {
const createServerStub = sinon.stub(https, 'createServer');
const args = {
env: 'test',
bind: '1',
sslKey: 'ssl-key',
sslCert: 'ssl-cert',
};
try {
await (0, expressApp_1.createServer)(args, null);
https.createServer.should.be.calledOnce();
https.createServer.should.be.calledWith({ secureOptions: constants_1.SSL_OP_NO_TLSv1, key: 'ssl-key', cert: 'ssl-cert' });
}
finally {
createServerStub.restore();
}
});
it('should output basic information upon server startup', () => {
const logStub = sinon.stub(console, 'log');
const args = {
env: 'test',
};
(0, expressApp_1.startup)(args, 'base')();
logStub.should.have.callCount(3);
logStub.should.have.been.calledWith('BitGo-Express running');
logStub.should.have.been.calledWith(`Environment: ${args.env}`);
logStub.should.have.been.calledWith('Base URI: base');
logStub.restore();
});
it('should output custom root uri information upon server startup', () => {
const logStub = sinon.stub(console, 'log');
const args = {
env: 'test',
customRootUri: 'customuri',
};
(0, expressApp_1.startup)(args, 'base')();
logStub.should.have.callCount(4);
logStub.should.have.been.calledWith('BitGo-Express running');
logStub.should.have.been.calledWith(`Environment: ${args.env}`);
logStub.should.have.been.calledWith('Base URI: base');
logStub.should.have.been.calledWith(`Custom root URI: ${args.customRootUri}`);
logStub.restore();
});
it('should output custom bitcoin network information upon server startup', () => {
const logStub = sinon.stub(console, 'log');
const args = {
env: 'test',
customBitcoinNetwork: 'customnetwork',
};
(0, expressApp_1.startup)(args, 'base')();
logStub.should.have.callCount(4);
logStub.should.have.been.calledWith('BitGo-Express running');
logStub.should.have.been.calledWith(`Environment: ${args.env}`);
logStub.should.have.been.calledWith('Base URI: base');
logStub.should.have.been.calledWith(`Custom bitcoin network: ${args.customBitcoinNetwork}`);
logStub.restore();
});
it('should output signer mode upon server startup', () => {
const logStub = sinon.stub(console, 'log');
const args = {
env: 'test',
signerMode: 'signerMode',
};
(0, expressApp_1.startup)(args, 'base')();
logStub.should.have.callCount(4);
logStub.should.have.been.calledWith('BitGo-Express running');
logStub.should.have.been.calledWith(`Environment: ${args.env}`);
logStub.should.have.been.calledWith('Base URI: base');
logStub.should.have.been.calledWith(`External signer mode: ${args.signerMode}`);
logStub.restore();
});
it('should output lightning signer file system path upon server startup', () => {
const logStub = sinon.stub(console, 'log');
const args = {
env: 'test',
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
};
(0, expressApp_1.startup)(args, 'base')();
logStub.should.have.callCount(4);
logStub.should.have.been.calledWith('BitGo-Express running');
logStub.should.have.been.calledWith(`Environment: ${args.env}`);
logStub.should.have.been.calledWith('Base URI: base');
logStub.should.have.been.calledWith(`Lightning signer file system path: ${args.lightningSignerFileSystemPath}`);
logStub.restore();
});
it('should create http base URIs', () => {
const args = {
bind: '1',
port: 2,
};
(0, expressApp_1.createBaseUri)(args).should.equal(`http://${args.bind}:${args.port}`);
args.port = 80;
(0, expressApp_1.createBaseUri)(args).should.equal(`http://${args.bind}`);
args.port = 443;
(0, expressApp_1.createBaseUri)(args).should.equal(`http://${args.bind}:443`);
});
it('should create https base URIs', () => {
const args = {
bind: '6',
port: 8,
keyPath: '3',
crtPath: '4',
};
(0, expressApp_1.createBaseUri)(args).should.equal(`https://${args.bind}:${args.port}`);
args.port = 80;
(0, expressApp_1.createBaseUri)(args).should.equal(`https://${args.bind}:80`);
args.port = 443;
(0, expressApp_1.createBaseUri)(args).should.equal(`https://${args.bind}`);
});
it('should set up logging with a logfile', () => {
const resolveSpy = sinon.spy(path, 'resolve');
const createWriteStreamSpy = sinon.spy(fs, 'createWriteStream');
const logStub = sinon.stub(console, 'log');
const args = {
logFile: '/dev/null',
disableProxy: true,
};
(0, expressApp_1.app)(args);
path.resolve.should.have.been.calledWith(args.logFile);
fs.createWriteStream.should.have.been.calledOnceWith(args.logFile, { flags: 'a' });
logStub.should.have.been.calledOnceWith(`Log location: ${args.logFile}`);
resolveSpy.restore();
createWriteStreamSpy.restore();
logStub.restore();
});
it('should enable specified debug namespaces', () => {
const enableStub = sinon.stub(debugLib, 'enable');
const args = {
debugNamespace: ['a', 'b'],
disableProxy: true,
};
(0, expressApp_1.app)(args);
enableStub.should.have.been.calledTwice();
enableStub.should.have.been.calledWith(args.debugNamespace[0]);
enableStub.should.have.been.calledWith(args.debugNamespace[1]);
enableStub.restore();
});
it('should configure a custom root URI', () => {
const args = {
customRootUri: 'customroot',
env: undefined,
};
(0, expressApp_1.app)(args);
should(args.env).equal('custom');
bitgo_1.Environments.custom.uri.should.equal(args.customRootUri);
});
it('should configure a custom bitcoin network', () => {
const args = {
customBitcoinNetwork: 'custombitcoinnetwork',
env: undefined,
};
(0, expressApp_1.app)(args);
should(args.env).equal('custom');
bitgo_1.Environments.custom.network.should.equal(args.customBitcoinNetwork);
});
it('should fail if IPC option is used on windows', async () => {
const platformStub = sinon.stub(process, 'platform').value('win32');
await (0, expressApp_1.prepareIpc)('testipc').should.be.rejectedWith(/^IPC option is not supported on platform/);
platformStub.restore();
});
it("should not remove the IPC socket if it doesn't exist", async () => {
const statStub = sinon.stub(fs, 'statSync').throws({ code: 'ENOENT' });
const unlinkStub = sinon.stub(fs, 'unlinkSync');
await (0, expressApp_1.prepareIpc)('testipc').should.be.resolved();
unlinkStub.notCalled.should.be.true();
statStub.restore();
unlinkStub.restore();
});
it('should remove the socket before binding if IPC socket exists and is a socket', async () => {
const statStub = sinon.stub(fs, 'statSync').returns({ isSocket: () => true });
const unlinkStub = sinon.stub(fs, 'unlinkSync');
await (0, expressApp_1.prepareIpc)('testipc').should.be.resolved();
unlinkStub.calledWithExactly('testipc').should.be.true();
unlinkStub.calledOnce.should.be.true();
statStub.restore();
unlinkStub.restore();
});
it('should fail if IPC socket is not actually a socket', async () => {
const statStub = sinon.stub(fs, 'statSync').returns({ isSocket: () => false });
const unlinkStub = sinon.stub(fs, 'unlinkSync');
await (0, expressApp_1.prepareIpc)('testipc').should.be.rejectedWith(/IPC socket is not actually a socket/);
unlinkStub.notCalled.should.be.true();
statStub.restore();
unlinkStub.restore();
});
it('should print the IPC socket path on startup', async () => {
const logStub = sinon.stub(console, 'log');
const args = {
env: 'test',
customRootUri: 'customuri',
ipc: 'expressIPC',
};
(0, expressApp_1.startup)(args, 'base')();
logStub.should.have.been.calledWith('IPC path: expressIPC');
logStub.restore();
});
it('should only call setupAPIRoutes when running in regular mode', () => {
const args = {
env: 'test',
signerMode: undefined,
};
const apiStub = sinon.stub(clientRoutes, 'setupAPIRoutes');
const signerStub = sinon.stub(clientRoutes, 'setupSigningRoutes');
(0, expressApp_1.app)(args);
apiStub.should.have.been.calledOnce();
signerStub.called.should.be.false();
apiStub.restore();
signerStub.restore();
});
it('should only call setupLightningSignerNodeRoutes when running with lightningSignerFileSystemPath', () => {
const args = {
env: 'test',
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
};
const readValidStub = sinon.stub(fs, 'readFileSync').returns(validLightningSignerConfigJSON);
const lightningSignerStub = sinon.stub(clientRoutes, 'setupLightningSignerNodeRoutes');
const apiStub = sinon.stub(clientRoutes, 'setupAPIRoutes');
const signerStub = sinon.stub(clientRoutes, 'setupSigningRoutes');
(0, expressApp_1.app)(args);
lightningSignerStub.should.have.been.calledOnce();
apiStub.should.have.been.calledOnce();
signerStub.called.should.be.false();
apiStub.restore();
signerStub.restore();
readValidStub.restore();
});
it('should only call setupSigningRoutes when running in signer mode', () => {
const args = {
env: 'test',
signerMode: 'signerMode',
signerFileSystemPath: 'signerFileSystemPath',
};
const apiStub = sinon.stub(clientRoutes, 'setupAPIRoutes');
const signerStub = sinon.stub(clientRoutes, 'setupSigningRoutes');
const readFileStub = sinon.stub(fs, 'readFileSync').returns(validPrvJSON);
(0, expressApp_1.app)(args);
signerStub.should.have.been.calledOnce();
apiStub.called.should.be.false();
apiStub.restore();
signerStub.restore();
readFileStub.restore();
});
it('should require a signerFileSystemPath and signerMode are both set when running in signer mode', function () {
const args = {
env: 'test',
signerMode: 'signerMode',
signerFileSystemPath: undefined,
};
(() => (0, expressApp_1.app)(args)).should.throw({
name: 'ExternalSignerConfigError',
message: 'signerMode and signerFileSystemPath must both be set in order to run in external signing mode.',
});
args.signerMode = undefined;
args.signerFileSystemPath = 'signerFileSystemPath';
(() => (0, expressApp_1.app)(args)).should.throw({
name: 'ExternalSignerConfigError',
message: 'signerMode and signerFileSystemPath must both be set in order to run in external signing mode.',
});
const readFileStub = sinon.stub(fs, 'readFileSync').returns(validPrvJSON);
args.signerMode = 'signerMode';
(() => (0, expressApp_1.app)(args)).should.not.throw();
readFileStub.restore();
});
it('should require that an externalSignerUrl and signerMode are not both set', function () {
const args = {
env: 'test',
signerMode: 'signerMode',
externalSignerUrl: 'externalSignerUrl',
};
(() => (0, expressApp_1.app)(args)).should.throw({
name: 'ExternalSignerConfigError',
message: 'signerMode or signerFileSystemPath is set, but externalSignerUrl is also set.',
});
args.signerMode = undefined;
(() => (0, expressApp_1.app)(args)).should.not.throw();
});
it('should require that signerMode and lightningSignerFileSystemPath not coexist', function () {
const args = {
env: 'test',
signerMode: 'signerMode',
signerFileSystemPath: 'signerFileSystemPath',
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
};
(() => (0, expressApp_1.app)(args)).should.throw({
name: 'LightningSignerConfigError',
message: 'signerMode and lightningSignerFileSystemPath cannot be set at the same time.',
});
const readFileStub = sinon.stub(fs, 'readFileSync').returns(validLightningSignerConfigJSON);
args.signerMode = undefined;
args.signerFileSystemPath = undefined;
(() => (0, expressApp_1.app)(args)).should.not.throw();
readFileStub.restore();
});
it('should require that an signerFileSystemPath contains a parsable json', function () {
const args = {
env: 'test',
signerMode: 'signerMode',
signerFileSystemPath: 'invalidSignerFileSystemPath',
};
(() => (0, expressApp_1.app)(args)).should.throw();
const invalidPrv = '{"invalid json"}';
const readInvalidStub = sinon.stub(fs, 'readFileSync').returns(invalidPrv);
(() => (0, expressApp_1.app)(args)).should.throw();
readInvalidStub.restore();
const readValidStub = sinon.stub(fs, 'readFileSync').returns(validPrvJSON);
(() => (0, expressApp_1.app)(args)).should.not.throw();
readValidStub.restore();
});
it('should require that an lightningSignerFileSystemPath contains a parsable json', function () {
const args = {
env: 'test',
lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
};
(() => (0, expressApp_1.app)(args)).should.throw();
const invalidPrv = '{"invalid json"}';
const readInvalidStub = sinon.stub(fs, 'readFileSync').returns(invalidPrv);
(() => (0, expressApp_1.app)(args)).should.throw();
readInvalidStub.restore();
const readValidStub = sinon.stub(fs, 'readFileSync').returns(validLightningSignerConfigJSON);
(() => (0, expressApp_1.app)(args)).should.not.throw();
readValidStub.restore();
});
it('should set keepAliveTimeout and headersTimeout if specified in config for HTTP server', async function () {
const createServerStub = sinon.stub(http, 'createServer').callsFake(() => {
return { listen: sinon.stub(), setTimeout: sinon.stub() };
});
const args = {
env: 'test',
bind: 'localhost',
keepAliveTimeout: 5000,
headersTimeout: 10000,
};
const server = await (0, expressApp_1.createServer)(args, null);
server.keepAliveTimeout.should.equal(args.keepAliveTimeout);
server.headersTimeout.should.equal(args.headersTimeout);
createServerStub.restore();
});
it('should set keepAliveTimeout and headersTimeout if specified in config for HTTPS server', async function () {
const createServerStub = sinon.stub(https, 'createServer').callsFake(() => {
return { listen: sinon.stub(), setTimeout: sinon.stub() };
});
const args = {
env: 'test',
bind: 'localhost',
sslKey: 'ssl-key',
sslCert: 'ssl-cert',
keepAliveTimeout: 5000,
headersTimeout: 10000,
};
const server = await (0, expressApp_1.createServer)(args, null);
server.keepAliveTimeout.should.equal(args.keepAliveTimeout);
server.headersTimeout.should.equal(args.headersTimeout);
createServerStub.restore();
});
it('should not set keepAliveTimeout and headersTimeout if not specified in config for HTTP server', async function () {
const createServerStub = sinon.stub(http, 'createServer').callsFake(() => {
return { listen: sinon.stub(), setTimeout: sinon.stub() };
});
const args = {
env: 'test',
bind: 'localhost',
// keepAliveTimeout and headersTimeout are not specified
};
const server = await (0, expressApp_1.createServer)(args, null);
should(server.keepAliveTimeout).be.undefined();
should(server.headersTimeout).be.undefined();
createServerStub.restore();
});
it('should not set keepAliveTimeout and headersTimeout if not specified in config for HTTPS server', async function () {
const createServerStub = sinon.stub(https, 'createServer').callsFake(() => {
return { listen: sinon.stub(), setTimeout: sinon.stub() };
});
const args = {
env: 'test',
bind: 'localhost',
sslKey: 'ssl-key',
sslCert: 'ssl-cert',
// keepAliveTimeout and headersTimeout are not specified
};
const server = await (0, expressApp_1.createServer)(args, null);
should(server.keepAliveTimeout).be.undefined();
should(server.headersTimeout).be.undefined();
createServerStub.restore();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYml0Z29FeHByZXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2JpdGdvRXhwcmVzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlDQUFpQztBQUNqQyx1QkFBcUI7QUFDckIsd0JBQXNCO0FBQ3RCLDBCQUF3QjtBQUV4Qiw2QkFBNkI7QUFDN0IsK0JBQStCO0FBRS9CLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0IsK0JBQStCO0FBQy9CLGtDQUFrQztBQUNsQyw2QkFBNkI7QUFDN0IsaUNBQXFDO0FBRXJDLHlDQUE0QztBQUM1Qyw2Q0FBK0U7QUFFL0UsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFFekIscURBQTJHO0FBQzNHLHVEQUF1RDtBQUV2RCxRQUFRLENBQUMsZUFBZSxFQUFFO0lBQ3hCLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRTtRQUNoQyxNQUFNLFlBQVksR0FDaEIsd0pBQXdKLENBQUM7UUFDM0osTUFBTSw4QkFBOEIsR0FBRyxnRUFBZ0UsQ0FBQztRQUV4RyxFQUFFLENBQUMsd0VBQXdFLEVBQUU7WUFDM0UsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7WUFFN0UsSUFBSTtnQkFDRixDQUFDLEdBQUcsRUFBRSxDQUNKLElBQUEsZ0JBQVUsRUFBQztvQkFDVCxHQUFHLEVBQUUsTUFBTTtvQkFDWCxJQUFJLEVBQUUsV0FBVztpQkFDWCxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUVoQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7Z0JBQzdCLENBQUMsR0FBRyxFQUFFLENBQ0osSUFBQSxnQkFBVSxFQUFDO29CQUNULEdBQUcsRUFBRSxNQUFNO29CQUNYLElB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T0FBTyxFQUFFLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0dBQWdHLEVBQUUsS0FBSztZQUN4RyxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3hFLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQTZCLENBQUM7WUFDdkYsQ0FBQyxDQUFDLENBQUM7WUFFSCxNQUFNLElBQUksR0FBUTtnQkFDaEIsR0FBRyxFQUFFLE1BQU07Z0JBQ1gsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLE1BQU0sRUFBRSxTQUFTO2dCQUNqQixPQUFPLEVBQUUsVUFBVTtnQkFDbkIsd0RBQXdEO2FBQ3pELENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEseUJBQVksRUFBQyxJQUFJLEVBQUUsSUFBVyxDQUFDLENBQUM7WUFFckQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMvQyxNQUFNLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUU3QyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAnc2hvdWxkLWh0dHAnO1xuaW1wb3J0ICdzaG91bGQtc2lub24nO1xuaW1wb3J0ICcuLi9saWIvYXNzZXJ0cyc7XG5cbmltcG9ydCAqIGFzIG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgKiBhcyBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgKiBhcyBkZWJ1Z0xpYiBmcm9tICdkZWJ1Zyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgRW52aXJvbm1lbnRzIH0gZnJvbSAnYml0Z28nO1xuXG5pbXBvcnQgeyBTU0xfT1BfTk9fVExTdjEgfSBmcm9tICdjb25zdGFudHMnO1xuaW1wb3J0IHsgVGxzQ29uZmlndXJhdGlvbkVycm9yLCBOb2RlRW52aXJvbm1lbnRFcnJvciB9IGZyb20gJy4uLy4uL3NyYy9lcnJvcnMnO1xuXG5ub2NrLmRpc2FibGVOZXRDb25uZWN0KCk7XG5cbmltcG9ydCB7IGFwcCBhcyBleHByZXNzQXBwLCBzdGFydHVwLCBjcmVhdGVTZXJ2ZXIsIGNyZWF0ZUJhc2VVcmksIHByZXBhcmVJcGMgfSBmcm9tICcuLi8uLi9zcmMvZXhwcmVzc0FwcCc7XG5pbXBvcnQgKiBhcyBjbGllbnRSb3V0ZXMgZnJvbSAnLi4vLi4vc3JjL2NsaWVudFJvdXRlcyc7XG5cbmRlc2NyaWJlKCdCaXRnbyBFeHByZXNzJywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnc2VydmVyIGluaXRpYWxpemF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHZhbGlkUHJ2SlNPTiA9XG4gICAgICAne1wiNjFmMDM5YWFkNTg3YzIwMDA3NDVjNjg3MzczZTBmYTlcIjpcInhwcnY5czIxWnJRSDE0M0szRXVQV0NCdXFuV3h5ZGFRVjZldDlodFFpZ2U0RXN3dmNIS0V6Tm1rVm13VHdLb2FkeUh6SllwcHVBREI3VXM3QWJhTkxUb052b0ZvU3h1V3FuZFFSWXRuTnk1RFVZMlwifSc7XG4gICAgY29uc3QgdmFsaWRMaWdodG5pbmdTaWduZXJDb25maWdKU09OID0gJ3tcImZha2VpZFwiOntcInVybFwiOiBcImh0dHBzOi8vMTI3LjAuMC4xOjgwODBcIixcInRsc0NlcnRcIjpcImR1bW15XCJ9fSc7XG5cbiAgICBpdCgnc2hvdWxkIHJlcXVpcmUgTk9ERV9FTlYgdG8gYmUgcHJvZHVjdGlvbiB3aGVuIHJ1bm5pbmcgYWdhaW5zdCBwcm9kIGVudicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVudlN0dWIgPSBzaW5vbi5zdHViKHByb2Nlc3MsICdlbnYnKS52YWx1ZSh7IE5PREVfRU5WOiAncHJvZHVjdGlvbicgfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgICgoKSA9PlxuICAgICAgICAgIGV4cHJlc3NBcHAoe1xuICAgICAgICAgICAgZW52OiAncHJvZCcsXG4gICAgICAgICAgICBiaW5kOiAnbG9jYWxob3N0JyxcbiAgICAgICAgICB9IGFzIGFueSkpLnNob3VsZC5ub3QudGhyb3coKTtcblxuICAgICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViA9ICdkZXYnO1xuICAgICAgICAoKCkgPT5cbiAgICAgICAgICBleHByZXNzQXBwKHtcbiAgICAgICAgICAgIGVudjogJ3Byb2QnLFxuICAgICAgICAgICAgYmluZDogJ2xvY2FsaG9zdCcsXG4gICAgICAgICAgfSBhcyBhbnkpKS5zaG91bGQudGhyb3coTm9kZUVudmlyb25tZW50RXJyb3IpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgZW52U3R1Yi5yZXN0b3JlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRpc2FibGUgTk9ERV9FTlYgY2hlY2sgaWYgZGlzYWJsZWVudmNoZWNrIGFyZ3VtZW50IGlzIGdpdmVuJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW52U3R1YiA9IHNpbm9uLnN0dWIocHJvY2VzcywgJ2VudicpLnZhbHVlKHsgTk9ERV9FTlY6ICdkZXYnIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICAoKCkgPT5cbiAgICAgICAgICBleHByZXNzQXBwKHtcbiAgICAgICAgICAgIGVudjogJ3Byb2QnLFxuICAgICAgICAgICAgYmluZDogJ2xvY2FsaG9zdCcsXG4gICAgICAgICAgICBkaXNhYmxlRW52Q2hlY2s6IHRydWUsXG4gICAgICAgICAgfSBhcyBhbnkpKS5zaG91bGQubm90LnRocm93KCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBlbnZTdHViLnJlc3RvcmUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVxdWlyZSBUTFMgZm9yIHByb2QgZW52IHdoZW4gbGlzdGVuaW5nIG9uIGV4dGVybmFsIGludGVyZmFjZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGVudjogJ3Byb2QnLFxuICAgICAgICBiaW5kOiAnMScsXG4gICAgICAgIGRpc2FibGVFbnZDaGVjazogdHJ1ZSxcbiAgICAgICAgZGlzYWJsZVNTTDogZmFsc2UsXG4gICAgICAgIGNydFBhdGg6IHVuZGVmaW5lZCBhcyBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICAgIGtleVBhdGg6IHVuZGVmaW5lZCBhcyBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KFRsc0NvbmZpZ3VyYXRpb25FcnJvcik7XG5cbiAgICAgIGFyZ3MuYmluZCA9ICdsb2NhbGhvc3QnO1xuICAgICAgKCgpID0+IGV4cHJlc3NBcHAoYXJncykpLnNob3VsZC5ub3QudGhyb3coKTtcblxuICAgICAgYXJncy5iaW5kID0gJzEnO1xuICAgICAgYXJncy5lbnYgPSAndGVzdCc7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuXG4gICAgICBhcmdzLmRpc2FibGVTU0wgPSB0cnVlO1xuICAgICAgYXJncy5lbnYgPSAncHJvZCc7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuXG4gICAgICBkZWxldGUgYXJncy5kaXNhYmxlU1NMO1xuICAgICAgYXJncy5jcnRQYXRoID0gJy90bXAvY2VydC5wZW0nO1xuICAgICAgKCgpID0+IGV4cHJlc3NBcHAoYXJncykpLnNob3VsZC50aHJvdyhUbHNDb25maWd1cmF0aW9uRXJyb3IpO1xuXG4gICAgICBkZWxldGUgYXJncy5jcnRQYXRoO1xuICAgICAgYXJncy5rZXlQYXRoID0gJy90bXAva2V5LnBlbSc7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KFRsc0NvbmZpZ3VyYXRpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcXVpcmUgYm90aCBrZXlwYXRoIGFuZCBjcnRwYXRoIHdoZW4gdXNpbmcgVExTLCBidXQgVExTIGlzIG5vdCByZXF1aXJlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGJpbmQ6ICcxJyxcbiAgICAgICAga2V5UGF0aDogJy90bXAva2V5LnBlbScsXG4gICAgICAgIGNydFBhdGg6IHVuZGVmaW5lZCBhcyBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KFRsc0NvbmZpZ3VyYXRpb25FcnJvcik7XG5cbiAgICAgIGRlbGV0ZSBhcmdzLmtleVBhdGg7XG4gICAgICBhcmdzLmNydFBhdGggPSAnL3RtcC9jZXJ0LnBlbSc7XG5cbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQudGhyb3coVGxzQ29uZmlndXJhdGlvbkVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGFuIGh0dHAgc2VydmVyIHdoZW4gbm90IHVzaW5nIFRMUycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNyZWF0ZVNlcnZlclN0dWIgPSBzaW5vbi5zdHViKGh0dHAsICdjcmVhdGVTZXJ2ZXInKTtcblxuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICdwcm9kJyxcbiAgICAgICAgYmluZDogJ2xvY2FsaG9zdCcsXG4gICAgICB9O1xuXG4gICAgICBjcmVhdGVTZXJ2ZXIoYXJncywgbnVsbCBhcyBhbnkpO1xuXG4gICAgICBjcmVhdGVTZXJ2ZXJTdHViLnNob3VsZC5iZS5jYWxsZWRPbmNlKCk7XG4gICAgICBjcmVhdGVTZXJ2ZXJTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGFuIGh0dHBzIHNlcnZlciB3aGVuIHVzaW5nIFRMUycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNyZWF0ZVNlcnZlclN0dWIgPSBzaW5vbi5zdHViKGh0dHBzLCAnY3JlYXRlU2VydmVyJyk7XG4gICAgICBjb25zdCByZWFkRmlsZUFzeW5jU3R1YiA9IHNpbm9uXG4gICAgICAgIC5zdHViKGZzLnByb21pc2VzLCAncmVhZEZpbGUnIGFzIGFueSlcbiAgICAgICAgLm9uRmlyc3RDYWxsKClcbiAgICAgICAgLnJlc29sdmVzKCdrZXknKVxuICAgICAgICAub25TZWNvbmRDYWxsKClcbiAgICAgICAgLnJlc29sdmVzKCdjZXJ0Jyk7XG5cbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAncHJvZCcsXG4gICAgICAgIGJpbmQ6ICcxLjIuMy40JyxcbiAgICAgICAgY3J0UGF0aDogJy90bXAvY3J0LnBlbScsXG4gICAgICAgIGtleVBhdGg6ICcvdG1wL2tleS5wZW0nLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgY3JlYXRlU2VydmVyKGFyZ3MsIG51bGwgYXMgYW55KTtcblxuICAgICAgaHR0cHMuY3JlYXRlU2VydmVyLnNob3VsZC5iZS5jYWxsZWRPbmNlKCk7XG4gICAgICBodHRwcy5jcmVhdGVTZXJ2ZXIuc2hvdWxkLmJlLmNhbGxlZFdpdGgoeyBzZWN1cmVPcHRpb25zOiBTU0xfT1BfTk9fVExTdjEsIGtleTogJ2tleScsIGNlcnQ6ICdjZXJ0JyB9KTtcblxuICAgICAgY3JlYXRlU2VydmVyU3R1Yi5yZXN0b3JlKCk7XG4gICAgICByZWFkRmlsZUFzeW5jU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBodHRwcyBzZXJ2ZXIgd2l0aCBzc2xrZXkgYW5kIHNzbGNlcnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjcmVhdGVTZXJ2ZXJTdHViID0gc2lub24uc3R1YihodHRwcywgJ2NyZWF0ZVNlcnZlcicpO1xuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgYmluZDogJzEnLFxuICAgICAgICBzc2xLZXk6ICdzc2wta2V5JyxcbiAgICAgICAgc3NsQ2VydDogJ3NzbC1jZXJ0JyxcbiAgICAgIH07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGNyZWF0ZVNlcnZlcihhcmdzLCBudWxsIGFzIGFueSk7XG4gICAgICAgIGh0dHBzLmNyZWF0ZVNlcnZlci5zaG91bGQuYmUuY2FsbGVkT25jZSgpO1xuICAgICAgICBodHRwcy5jcmVhdGVTZXJ2ZXIuc2hvdWxkLmJlLmNhbGxlZFdpdGgoeyBzZWN1cmVPcHRpb25zOiBTU0xfT1BfTk9fVExTdjEsIGtleTogJ3NzbC1rZXknLCBjZXJ0OiAnc3NsLWNlcnQnIH0pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgY3JlYXRlU2VydmVyU3R1Yi5yZXN0b3JlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG91dHB1dCBiYXNpYyBpbmZvcm1hdGlvbiB1cG9uIHNlcnZlciBzdGFydHVwJywgKCkgPT4ge1xuICAgICAgY29uc3QgbG9nU3R1YiA9IHNpbm9uLnN0dWIoY29uc29sZSwgJ2xvZycpO1xuXG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGVudjogJ3Rlc3QnLFxuICAgICAgfTtcblxuICAgICAgc3RhcnR1cChhcmdzLCAnYmFzZScpKCk7XG5cbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuY2FsbENvdW50KDMpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0JpdEdvLUV4cHJlc3MgcnVubmluZycpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoYEVudmlyb25tZW50OiAke2FyZ3MuZW52fWApO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0Jhc2UgVVJJOiBiYXNlJyk7XG5cbiAgICAgIGxvZ1N0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBvdXRwdXQgY3VzdG9tIHJvb3QgdXJpIGluZm9ybWF0aW9uIHVwb24gc2VydmVyIHN0YXJ0dXAnLCAoKSA9PiB7XG4gICAgICBjb25zdCBsb2dTdHViID0gc2lub24uc3R1Yihjb25zb2xlLCAnbG9nJyk7XG5cbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGN1c3RvbVJvb3RVcmk6ICdjdXN0b211cmknLFxuICAgICAgfTtcblxuICAgICAgc3RhcnR1cChhcmdzLCAnYmFzZScpKCk7XG5cbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuY2FsbENvdW50KDQpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0JpdEdvLUV4cHJlc3MgcnVubmluZycpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoYEVudmlyb25tZW50OiAke2FyZ3MuZW52fWApO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0Jhc2UgVVJJOiBiYXNlJyk7XG4gICAgICBsb2dTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkV2l0aChgQ3VzdG9tIHJvb3QgVVJJOiAke2FyZ3MuY3VzdG9tUm9vdFVyaX1gKTtcblxuICAgICAgbG9nU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG91dHB1dCBjdXN0b20gYml0Y29pbiBuZXR3b3JrIGluZm9ybWF0aW9uIHVwb24gc2VydmVyIHN0YXJ0dXAnLCAoKSA9PiB7XG4gICAgICBjb25zdCBsb2dTdHViID0gc2lub24uc3R1Yihjb25zb2xlLCAnbG9nJyk7XG5cbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGN1c3RvbUJpdGNvaW5OZXR3b3JrOiAnY3VzdG9tbmV0d29yaycsXG4gICAgICB9O1xuXG4gICAgICBzdGFydHVwKGFyZ3MsICdiYXNlJykoKTtcblxuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5jYWxsQ291bnQoNCk7XG4gICAgICBsb2dTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkV2l0aCgnQml0R28tRXhwcmVzcyBydW5uaW5nJyk7XG4gICAgICBsb2dTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkV2l0aChgRW52aXJvbm1lbnQ6ICR7YXJncy5lbnZ9YCk7XG4gICAgICBsb2dTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkV2l0aCgnQmFzZSBVUkk6IGJhc2UnKTtcbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKGBDdXN0b20gYml0Y29pbiBuZXR3b3JrOiAke2FyZ3MuY3VzdG9tQml0Y29pbk5ldHdvcmt9YCk7XG5cbiAgICAgIGxvZ1N0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBvdXRwdXQgc2lnbmVyIG1vZGUgdXBvbiBzZXJ2ZXIgc3RhcnR1cCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGxvZ1N0dWIgPSBzaW5vbi5zdHViKGNvbnNvbGUsICdsb2cnKTtcblxuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgc2lnbmVyTW9kZTogJ3NpZ25lck1vZGUnLFxuICAgICAgfTtcblxuICAgICAgc3RhcnR1cChhcmdzLCAnYmFzZScpKCk7XG5cbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuY2FsbENvdW50KDQpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0JpdEdvLUV4cHJlc3MgcnVubmluZycpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoYEVudmlyb25tZW50OiAke2FyZ3MuZW52fWApO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoJ0Jhc2UgVVJJOiBiYXNlJyk7XG4gICAgICBsb2dTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkV2l0aChgRXh0ZXJuYWwgc2lnbmVyIG1vZGU6ICR7YXJncy5zaWduZXJNb2RlfWApO1xuXG4gICAgICBsb2dTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgb3V0cHV0IGxpZ2h0bmluZyBzaWduZXIgZmlsZSBzeXN0ZW0gcGF0aCB1cG9uIHNlcnZlciBzdGFydHVwJywgKCkgPT4ge1xuICAgICAgY29uc3QgbG9nU3R1YiA9IHNpbm9uLnN0dWIoY29uc29sZSwgJ2xvZycpO1xuXG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGVudjogJ3Rlc3QnLFxuICAgICAgICBsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aDogJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJyxcbiAgICAgIH07XG5cbiAgICAgIHN0YXJ0dXAoYXJncywgJ2Jhc2UnKSgpO1xuXG4gICAgICBsb2dTdHViLnNob3VsZC5oYXZlLmNhbGxDb3VudCg0KTtcbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKCdCaXRHby1FeHByZXNzIHJ1bm5pbmcnKTtcbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKGBFbnZpcm9ubWVudDogJHthcmdzLmVudn1gKTtcbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKCdCYXNlIFVSSTogYmFzZScpO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoYExpZ2h0bmluZyBzaWduZXIgZmlsZSBzeXN0ZW0gcGF0aDogJHthcmdzLmxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRofWApO1xuXG4gICAgICBsb2dTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGh0dHAgYmFzZSBVUklzJywgKCkgPT4ge1xuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBiaW5kOiAnMScsXG4gICAgICAgIHBvcnQ6IDIsXG4gICAgICB9O1xuXG4gICAgICBjcmVhdGVCYXNlVXJpKGFyZ3MpLnNob3VsZC5lcXVhbChgaHR0cDovLyR7YXJncy5iaW5kfToke2FyZ3MucG9ydH1gKTtcblxuICAgICAgYXJncy5wb3J0ID0gODA7XG4gICAgICBjcmVhdGVCYXNlVXJpKGFyZ3MpLnNob3VsZC5lcXVhbChgaHR0cDovLyR7YXJncy5iaW5kfWApO1xuXG4gICAgICBhcmdzLnBvcnQgPSA0NDM7XG4gICAgICBjcmVhdGVCYXNlVXJpKGFyZ3MpLnNob3VsZC5lcXVhbChgaHR0cDovLyR7YXJncy5iaW5kfTo0NDNgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGh0dHBzIGJhc2UgVVJJcycsICgpID0+IHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgYmluZDogJzYnLFxuICAgICAgICBwb3J0OiA4LFxuICAgICAgICBrZXlQYXRoOiAnMycsXG4gICAgICAgIGNydFBhdGg6ICc0JyxcbiAgICAgIH07XG5cbiAgICAgIGNyZWF0ZUJhc2VVcmkoYXJncykuc2hvdWxkLmVxdWFsKGBodHRwczovLyR7YXJncy5iaW5kfToke2FyZ3MucG9ydH1gKTtcblxuICAgICAgYXJncy5wb3J0ID0gODA7XG4gICAgICBjcmVhdGVCYXNlVXJpKGFyZ3MpLnNob3VsZC5lcXVhbChgaHR0cHM6Ly8ke2FyZ3MuYmluZH06ODBgKTtcblxuICAgICAgYXJncy5wb3J0ID0gNDQzO1xuICAgICAgY3JlYXRlQmFzZVVyaShhcmdzKS5zaG91bGQuZXF1YWwoYGh0dHBzOi8vJHthcmdzLmJpbmR9YCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCB1cCBsb2dnaW5nIHdpdGggYSBsb2dmaWxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzb2x2ZVNweSA9IHNpbm9uLnNweShwYXRoLCAncmVzb2x2ZScpO1xuICAgICAgY29uc3QgY3JlYXRlV3JpdGVTdHJlYW1TcHkgPSBzaW5vbi5zcHkoZnMsICdjcmVhdGVXcml0ZVN0cmVhbScpO1xuICAgICAgY29uc3QgbG9nU3R1YiA9IHNpbm9uLnN0dWIoY29uc29sZSwgJ2xvZycpO1xuXG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGxvZ0ZpbGU6ICcvZGV2L251bGwnLFxuICAgICAgICBkaXNhYmxlUHJveHk6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBleHByZXNzQXBwKGFyZ3MpO1xuXG4gICAgICBwYXRoLnJlc29sdmUuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKGFyZ3MubG9nRmlsZSk7XG4gICAgICBmcy5jcmVhdGVXcml0ZVN0cmVhbS5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZE9uY2VXaXRoKGFyZ3MubG9nRmlsZSwgeyBmbGFnczogJ2EnIH0pO1xuICAgICAgbG9nU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZE9uY2VXaXRoKGBMb2cgbG9jYXRpb246ICR7YXJncy5sb2dGaWxlfWApO1xuXG4gICAgICByZXNvbHZlU3B5LnJlc3RvcmUoKTtcbiAgICAgIGNyZWF0ZVdyaXRlU3RyZWFtU3B5LnJlc3RvcmUoKTtcbiAgICAgIGxvZ1N0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmFibGUgc3BlY2lmaWVkIGRlYnVnIG5hbWVzcGFjZXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCBlbmFibGVTdHViID0gc2lub24uc3R1YihkZWJ1Z0xpYiwgJ2VuYWJsZScpO1xuXG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGRlYnVnTmFtZXNwYWNlOiBbJ2EnLCAnYiddLFxuICAgICAgICBkaXNhYmxlUHJveHk6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBleHByZXNzQXBwKGFyZ3MpO1xuXG4gICAgICBlbmFibGVTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkVHdpY2UoKTtcbiAgICAgIGVuYWJsZVN0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKGFyZ3MuZGVidWdOYW1lc3BhY2VbMF0pO1xuICAgICAgZW5hYmxlU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZFdpdGgoYXJncy5kZWJ1Z05hbWVzcGFjZVsxXSk7XG5cbiAgICAgIGVuYWJsZVN0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25maWd1cmUgYSBjdXN0b20gcm9vdCBVUkknLCAoKSA9PiB7XG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGN1c3RvbVJvb3RVcmk6ICdjdXN0b21yb290JyxcbiAgICAgICAgZW52OiB1bmRlZmluZWQgYXMgc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgZXhwcmVzc0FwcChhcmdzKTtcblxuICAgICAgc2hvdWxkKGFyZ3MuZW52KS5lcXVhbCgnY3VzdG9tJyk7XG4gICAgICBFbnZpcm9ubWVudHMuY3VzdG9tLnVyaS5zaG91bGQuZXF1YWwoYXJncy5jdXN0b21Sb290VXJpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uZmlndXJlIGEgY3VzdG9tIGJpdGNvaW4gbmV0d29yaycsICgpID0+IHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgY3VzdG9tQml0Y29pbk5ldHdvcms6ICdjdXN0b21iaXRjb2lubmV0d29yaycsXG4gICAgICAgIGVudjogdW5kZWZpbmVkIGFzIHN0cmluZyB8IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIGV4cHJlc3NBcHAoYXJncyk7XG5cbiAgICAgIHNob3VsZChhcmdzLmVudikuZXF1YWwoJ2N1c3RvbScpO1xuICAgICAgRW52aXJvbm1lbnRzLmN1c3RvbS5uZXR3b3JrLnNob3VsZC5lcXVhbChhcmdzLmN1c3RvbUJpdGNvaW5OZXR3b3JrKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBpZiBJUEMgb3B0aW9uIGlzIHVzZWQgb24gd2luZG93cycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBsYXRmb3JtU3R1YiA9IHNpbm9uLnN0dWIocHJvY2VzcywgJ3BsYXRmb3JtJykudmFsdWUoJ3dpbjMyJyk7XG4gICAgICBhd2FpdCBwcmVwYXJlSXBjKCd0ZXN0aXBjJykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXklQQyBvcHRpb24gaXMgbm90IHN1cHBvcnRlZCBvbiBwbGF0Zm9ybS8pO1xuICAgICAgcGxhdGZvcm1TdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIG5vdCByZW1vdmUgdGhlIElQQyBzb2NrZXQgaWYgaXQgZG9lc24ndCBleGlzdFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzdGF0U3R1YiA9IHNpbm9uLnN0dWIoZnMsICdzdGF0U3luYycpLnRocm93cyh7IGNvZGU6ICdFTk9FTlQnIH0pO1xuICAgICAgY29uc3QgdW5saW5rU3R1YiA9IHNpbm9uLnN0dWIoZnMsICd1bmxpbmtTeW5jJyk7XG4gICAgICBhd2FpdCBwcmVwYXJlSXBjKCd0ZXN0aXBjJykuc2hvdWxkLmJlLnJlc29sdmVkKCk7XG4gICAgICB1bmxpbmtTdHViLm5vdENhbGxlZC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc3RhdFN0dWIucmVzdG9yZSgpO1xuICAgICAgdW5saW5rU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlbW92ZSB0aGUgc29ja2V0IGJlZm9yZSBiaW5kaW5nIGlmIElQQyBzb2NrZXQgZXhpc3RzIGFuZCBpcyBhIHNvY2tldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRTdHViID0gc2lub24uc3R1YihmcywgJ3N0YXRTeW5jJykucmV0dXJucyh7IGlzU29ja2V0OiAoKSA9PiB0cnVlIH0gYXMgdW5rbm93biBhcyBmcy5TdGF0cyk7XG4gICAgICBjb25zdCB1bmxpbmtTdHViID0gc2lub24uc3R1YihmcywgJ3VubGlua1N5bmMnKTtcbiAgICAgIGF3YWl0IHByZXBhcmVJcGMoJ3Rlc3RpcGMnKS5zaG91bGQuYmUucmVzb2x2ZWQoKTtcbiAgICAgIHVubGlua1N0dWIuY2FsbGVkV2l0aEV4YWN0bHkoJ3Rlc3RpcGMnKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgdW5saW5rU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzdGF0U3R1Yi5yZXN0b3JlKCk7XG4gICAgICB1bmxpbmtTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBpZiBJUEMgc29ja2V0IGlzIG5vdCBhY3R1YWxseSBhIHNvY2tldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRTdHViID0gc2lub24uc3R1YihmcywgJ3N0YXRTeW5jJykucmV0dXJucyh7IGlzU29ja2V0OiAoKSA9PiBmYWxzZSB9IGFzIHVua25vd24gYXMgZnMuU3RhdHMpO1xuICAgICAgY29uc3QgdW5saW5rU3R1YiA9IHNpbm9uLnN0dWIoZnMsICd1bmxpbmtTeW5jJyk7XG4gICAgICBhd2FpdCBwcmVwYXJlSXBjKCd0ZXN0aXBjJykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvSVBDIHNvY2tldCBpcyBub3QgYWN0dWFsbHkgYSBzb2NrZXQvKTtcbiAgICAgIHVubGlua1N0dWIubm90Q2FsbGVkLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzdGF0U3R1Yi5yZXN0b3JlKCk7XG4gICAgICB1bmxpbmtTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJpbnQgdGhlIElQQyBzb2NrZXQgcGF0aCBvbiBzdGFydHVwJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgbG9nU3R1YiA9IHNpbm9uLnN0dWIoY29uc29sZSwgJ2xvZycpO1xuXG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGVudjogJ3Rlc3QnLFxuICAgICAgICBjdXN0b21Sb290VXJpOiAnY3VzdG9tdXJpJyxcbiAgICAgICAgaXBjOiAnZXhwcmVzc0lQQycsXG4gICAgICB9O1xuXG4gICAgICBzdGFydHVwKGFyZ3MsICdiYXNlJykoKTtcbiAgICAgIGxvZ1N0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRXaXRoKCdJUEMgcGF0aDogZXhwcmVzc0lQQycpO1xuICAgICAgbG9nU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG9ubHkgY2FsbCBzZXR1cEFQSVJvdXRlcyB3aGVuIHJ1bm5pbmcgaW4gcmVndWxhciBtb2RlJywgKCkgPT4ge1xuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgc2lnbmVyTW9kZTogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgYXBpU3R1YiA9IHNpbm9uLnN0dWIoY2xpZW50Um91dGVzLCAnc2V0dXBBUElSb3V0ZXMnKTtcbiAgICAgIGNvbnN0IHNpZ25lclN0dWIgPSBzaW5vbi5zdHViKGNsaWVudFJvdXRlcywgJ3NldHVwU2lnbmluZ1JvdXRlcycpO1xuXG4gICAgICBleHByZXNzQXBwKGFyZ3MpO1xuICAgICAgYXBpU3R1Yi5zaG91bGQuaGF2ZS5iZWVuLmNhbGxlZE9uY2UoKTtcbiAgICAgIHNpZ25lclN0dWIuY2FsbGVkLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgYXBpU3R1Yi5yZXN0b3JlKCk7XG4gICAgICBzaWduZXJTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgb25seSBjYWxsIHNldHVwTGlnaHRuaW5nU2lnbmVyTm9kZVJvdXRlcyB3aGVuIHJ1bm5pbmcgd2l0aCBsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVhZFZhbGlkU3R1YiA9IHNpbm9uLnN0dWIoZnMsICdyZWFkRmlsZVN5bmMnKS5yZXR1cm5zKHZhbGlkTGlnaHRuaW5nU2lnbmVyQ29uZmlnSlNPTik7XG4gICAgICBjb25zdCBsaWdodG5pbmdTaWduZXJTdHViID0gc2lub24uc3R1YihjbGllbnRSb3V0ZXMsICdzZXR1cExpZ2h0bmluZ1NpZ25lck5vZGVSb3V0ZXMnKTtcbiAgICAgIGNvbnN0IGFwaVN0dWIgPSBzaW5vbi5zdHViKGNsaWVudFJvdXRlcywgJ3NldHVwQVBJUm91dGVzJyk7XG4gICAgICBjb25zdCBzaWduZXJTdHViID0gc2lub24uc3R1YihjbGllbnRSb3V0ZXMsICdzZXR1cFNpZ25pbmdSb3V0ZXMnKTtcblxuICAgICAgZXhwcmVzc0FwcChhcmdzKTtcbiAgICAgIGxpZ2h0bmluZ1NpZ25lclN0dWIuc2hvdWxkLmhhdmUuYmVlbi5jYWxsZWRPbmNlKCk7XG4gICAgICBhcGlTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZSgpO1xuICAgICAgc2lnbmVyU3R1Yi5jYWxsZWQuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICBhcGlTdHViLnJlc3RvcmUoKTtcbiAgICAgIHNpZ25lclN0dWIucmVzdG9yZSgpO1xuICAgICAgcmVhZFZhbGlkU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG9ubHkgY2FsbCBzZXR1cFNpZ25pbmdSb3V0ZXMgd2hlbiBydW5uaW5nIGluIHNpZ25lciBtb2RlJywgKCkgPT4ge1xuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgc2lnbmVyTW9kZTogJ3NpZ25lck1vZGUnLFxuICAgICAgICBzaWduZXJGaWxlU3lzdGVtUGF0aDogJ3NpZ25lckZpbGVTeXN0ZW1QYXRoJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGFwaVN0dWIgPSBzaW5vbi5zdHViKGNsaWVudFJvdXRlcywgJ3NldHVwQVBJUm91dGVzJyk7XG4gICAgICBjb25zdCBzaWduZXJTdHViID0gc2lub24uc3R1YihjbGllbnRSb3V0ZXMsICdzZXR1cFNpZ25pbmdSb3V0ZXMnKTtcbiAgICAgIGNvbnN0IHJlYWRGaWxlU3R1YiA9IHNpbm9uLnN0dWIoZnMsICdyZWFkRmlsZVN5bmMnKS5yZXR1cm5zKHZhbGlkUHJ2SlNPTik7XG5cbiAgICAgIGV4cHJlc3NBcHAoYXJncyk7XG4gICAgICBzaWduZXJTdHViLnNob3VsZC5oYXZlLmJlZW4uY2FsbGVkT25jZSgpO1xuICAgICAgYXBpU3R1Yi5jYWxsZWQuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICBhcGlTdHViLnJlc3RvcmUoKTtcbiAgICAgIHNpZ25lclN0dWIucmVzdG9yZSgpO1xuICAgICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVxdWlyZSBhIHNpZ25lckZpbGVTeXN0ZW1QYXRoIGFuZCBzaWduZXJNb2RlIGFyZSBib3RoIHNldCB3aGVuIHJ1bm5pbmcgaW4gc2lnbmVyIG1vZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGVudjogJ3Rlc3QnLFxuICAgICAgICBzaWduZXJNb2RlOiAnc2lnbmVyTW9kZScsXG4gICAgICAgIHNpZ25lckZpbGVTeXN0ZW1QYXRoOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KHtcbiAgICAgICAgbmFtZTogJ0V4dGVybmFsU2lnbmVyQ29uZmlnRXJyb3InLFxuICAgICAgICBtZXNzYWdlOiAnc2lnbmVyTW9kZSBhbmQgc2lnbmVyRmlsZVN5c3RlbVBhdGggbXVzdCBib3RoIGJlIHNldCBpbiBvcmRlciB0byBydW4gaW4gZXh0ZXJuYWwgc2lnbmluZyBtb2RlLicsXG4gICAgICB9KTtcblxuICAgICAgYXJncy5zaWduZXJNb2RlID0gdW5kZWZpbmVkO1xuICAgICAgYXJncy5zaWduZXJGaWxlU3lzdGVtUGF0aCA9ICdzaWduZXJGaWxlU3lzdGVtUGF0aCc7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KHtcbiAgICAgICAgbmFtZTogJ0V4dGVybmFsU2lnbmVyQ29uZmlnRXJyb3InLFxuICAgICAgICBtZXNzYWdlOiAnc2lnbmVyTW9kZSBhbmQgc2lnbmVyRmlsZVN5c3RlbVBhdGggbXVzdCBib3RoIGJlIHNldCBpbiBvcmRlciB0byBydW4gaW4gZXh0ZXJuYWwgc2lnbmluZyBtb2RlLicsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVhZEZpbGVTdHViID0gc2lub24uc3R1YihmcywgJ3JlYWRGaWxlU3luYycpLnJldHVybnModmFsaWRQcnZKU09OKTtcbiAgICAgIGFyZ3Muc2lnbmVyTW9kZSA9ICdzaWduZXJNb2RlJztcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQubm90LnRocm93KCk7XG5cbiAgICAgIHJlYWRGaWxlU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcXVpcmUgdGhhdCBhbiBleHRlcm5hbFNpZ25lclVybCBhbmQgc2lnbmVyTW9kZSBhcmUgbm90IGJvdGggc2V0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgc2lnbmVyTW9kZTogJ3NpZ25lck1vZGUnLFxuICAgICAgICBleHRlcm5hbFNpZ25lclVybDogJ2V4dGVybmFsU2lnbmVyVXJsJyxcbiAgICAgIH07XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KHtcbiAgICAgICAgbmFtZTogJ0V4dGVybmFsU2lnbmVyQ29uZmlnRXJyb3InLFxuICAgICAgICBtZXNzYWdlOiAnc2lnbmVyTW9kZSBvciBzaWduZXJGaWxlU3lzdGVtUGF0aCBpcyBzZXQsIGJ1dCBleHRlcm5hbFNpZ25lclVybCBpcyBhbHNvIHNldC4nLFxuICAgICAgfSk7XG5cbiAgICAgIGFyZ3Muc2lnbmVyTW9kZSA9IHVuZGVmaW5lZDtcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQubm90LnRocm93KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcXVpcmUgdGhhdCBzaWduZXJNb2RlIGFuZCBsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCBub3QgY29leGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIHNpZ25lck1vZGU6ICdzaWduZXJNb2RlJyxcbiAgICAgICAgc2lnbmVyRmlsZVN5c3RlbVBhdGg6ICdzaWduZXJGaWxlU3lzdGVtUGF0aCcsXG4gICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgfTtcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQudGhyb3coe1xuICAgICAgICBuYW1lOiAnTGlnaHRuaW5nU2lnbmVyQ29uZmlnRXJyb3InLFxuICAgICAgICBtZXNzYWdlOiAnc2lnbmVyTW9kZSBhbmQgbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGggY2Fubm90IGJlIHNldCBhdCB0aGUgc2FtZSB0aW1lLicsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVhZEZpbGVTdHViID0gc2lub24uc3R1YihmcywgJ3JlYWRGaWxlU3luYycpLnJldHVybnModmFsaWRMaWdodG5pbmdTaWduZXJDb25maWdKU09OKTtcbiAgICAgIGFyZ3Muc2lnbmVyTW9kZSA9IHVuZGVmaW5lZDtcbiAgICAgIGFyZ3Muc2lnbmVyRmlsZVN5c3RlbVBhdGggPSB1bmRlZmluZWQ7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVxdWlyZSB0aGF0IGFuIHNpZ25lckZpbGVTeXN0ZW1QYXRoIGNvbnRhaW5zIGEgcGFyc2FibGUganNvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIHNpZ25lck1vZGU6ICdzaWduZXJNb2RlJyxcbiAgICAgICAgc2lnbmVyRmlsZVN5c3RlbVBhdGg6ICdpbnZhbGlkU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgfTtcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQudGhyb3coKTtcblxuICAgICAgY29uc3QgaW52YWxpZFBydiA9ICd7XCJpbnZhbGlkIGpzb25cIn0nO1xuICAgICAgY29uc3QgcmVhZEludmFsaWRTdHViID0gc2lub24uc3R1YihmcywgJ3JlYWRGaWxlU3luYycpLnJldHVybnMoaW52YWxpZFBydik7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KCk7XG4gICAgICByZWFkSW52YWxpZFN0dWIucmVzdG9yZSgpO1xuXG4gICAgICBjb25zdCByZWFkVmFsaWRTdHViID0gc2lub24uc3R1YihmcywgJ3JlYWRGaWxlU3luYycpLnJldHVybnModmFsaWRQcnZKU09OKTtcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQubm90LnRocm93KCk7XG4gICAgICByZWFkVmFsaWRTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVxdWlyZSB0aGF0IGFuIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoIGNvbnRhaW5zIGEgcGFyc2FibGUganNvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgfTtcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQudGhyb3coKTtcblxuICAgICAgY29uc3QgaW52YWxpZFBydiA9ICd7XCJpbnZhbGlkIGpzb25cIn0nO1xuICAgICAgY29uc3QgcmVhZEludmFsaWRTdHViID0gc2lub24uc3R1YihmcywgJ3JlYWRGaWxlU3luYycpLnJldHVybnMoaW52YWxpZFBydik7XG4gICAgICAoKCkgPT4gZXhwcmVzc0FwcChhcmdzKSkuc2hvdWxkLnRocm93KCk7XG4gICAgICByZWFkSW52YWxpZFN0dWIucmVzdG9yZSgpO1xuXG4gICAgICBjb25zdCByZWFkVmFsaWRTdHViID0gc2lub24uc3R1YihmcywgJ3JlYWRGaWxlU3luYycpLnJldHVybnModmFsaWRMaWdodG5pbmdTaWduZXJDb25maWdKU09OKTtcbiAgICAgICgoKSA9PiBleHByZXNzQXBwKGFyZ3MpKS5zaG91bGQubm90LnRocm93KCk7XG4gICAgICByZWFkVmFsaWRTdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2V0IGtlZXBBbGl2ZVRpbWVvdXQgYW5kIGhlYWRlcnNUaW1lb3V0IGlmIHNwZWNpZmllZCBpbiBjb25maWcgZm9yIEhUVFAgc2VydmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY3JlYXRlU2VydmVyU3R1YiA9IHNpbm9uLnN0dWIoaHR0cCwgJ2NyZWF0ZVNlcnZlcicpLmNhbGxzRmFrZSgoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IGxpc3Rlbjogc2lub24uc3R1YigpLCBzZXRUaW1lb3V0OiBzaW5vbi5zdHViKCkgfSBhcyB1bmtub3duIGFzIGh0dHAuU2VydmVyO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGJpbmQ6ICdsb2NhbGhvc3QnLFxuICAgICAgICBrZWVwQWxpdmVUaW1lb3V0OiA1MDAwLFxuICAgICAgICBoZWFkZXJzVGltZW91dDogMTAwMDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZXJ2ZXIgPSBhd2FpdCBjcmVhdGVTZXJ2ZXIoYXJncywgbnVsbCBhcyBhbnkpO1xuXG4gICAgICBzZXJ2ZXIua2VlcEFsaXZlVGltZW91dC5zaG91bGQuZXF1YWwoYXJncy5rZWVwQWxpdmVUaW1lb3V0KTtcbiAgICAgIHNlcnZlci5oZWFkZXJzVGltZW91dC5zaG91bGQuZXF1YWwoYXJncy5oZWFkZXJzVGltZW91dCk7XG5cbiAgICAgIGNyZWF0ZVNlcnZlclN0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQga2VlcEFsaXZlVGltZW91dCBhbmQgaGVhZGVyc1RpbWVvdXQgaWYgc3BlY2lmaWVkIGluIGNvbmZpZyBmb3IgSFRUUFMgc2VydmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY3JlYXRlU2VydmVyU3R1YiA9IHNpbm9uLnN0dWIoaHR0cHMsICdjcmVhdGVTZXJ2ZXInKS5jYWxsc0Zha2UoKCkgPT4ge1xuICAgICAgICByZXR1cm4geyBsaXN0ZW46IHNpbm9uLnN0dWIoKSwgc2V0VGltZW91dDogc2lub24uc3R1YigpIH0gYXMgdW5rbm93biBhcyBodHRwcy5TZXJ2ZXI7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgYXJnczogYW55ID0ge1xuICAgICAgICBlbnY6ICd0ZXN0JyxcbiAgICAgICAgYmluZDogJ2xvY2FsaG9zdCcsXG4gICAgICAgIHNzbEtleTogJ3NzbC1rZXknLFxuICAgICAgICBzc2xDZXJ0OiAnc3NsLWNlcnQnLFxuICAgICAgICBrZWVwQWxpdmVUaW1lb3V0OiA1MDAwLFxuICAgICAgICBoZWFkZXJzVGltZW91dDogMTAwMDAsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzZXJ2ZXIgPSBhd2FpdCBjcmVhdGVTZXJ2ZXIoYXJncywgbnVsbCBhcyBhbnkpO1xuXG4gICAgICBzZXJ2ZXIua2VlcEFsaXZlVGltZW91dC5zaG91bGQuZXF1YWwoYXJncy5rZWVwQWxpdmVUaW1lb3V0KTtcbiAgICAgIHNlcnZlci5oZWFkZXJzVGltZW91dC5zaG91bGQuZXF1YWwoYXJncy5oZWFkZXJzVGltZW91dCk7XG5cbiAgICAgIGNyZWF0ZVNlcnZlclN0dWIucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3Qgc2V0IGtlZXBBbGl2ZVRpbWVvdXQgYW5kIGhlYWRlcnNUaW1lb3V0IGlmIG5vdCBzcGVjaWZpZWQgaW4gY29uZmlnIGZvciBIVFRQIHNlcnZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNyZWF0ZVNlcnZlclN0dWIgPSBzaW5vbi5zdHViKGh0dHAsICdjcmVhdGVTZXJ2ZXInKS5jYWxsc0Zha2UoKCkgPT4ge1xuICAgICAgICByZXR1cm4geyBsaXN0ZW46IHNpbm9uLnN0dWIoKSwgc2V0VGltZW91dDogc2lub24uc3R1YigpIH0gYXMgdW5rbm93biBhcyBodHRwLlNlcnZlcjtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhcmdzOiBhbnkgPSB7XG4gICAgICAgIGVudjogJ3Rlc3QnLFxuICAgICAgICBiaW5kOiAnbG9jYWxob3N0JyxcbiAgICAgICAgLy8ga2VlcEFsaXZlVGltZW91dCBhbmQgaGVhZGVyc1RpbWVvdXQgYXJlIG5vdCBzcGVjaWZpZWRcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNlcnZlciA9IGF3YWl0IGNyZWF0ZVNlcnZlcihhcmdzLCBudWxsIGFzIGFueSk7XG5cbiAgICAgIHNob3VsZChzZXJ2ZXIua2VlcEFsaXZlVGltZW91dCkuYmUudW5kZWZpbmVkKCk7XG4gICAgICBzaG91bGQoc2VydmVyLmhlYWRlcnNUaW1lb3V0KS5iZS51bmRlZmluZWQoKTtcblxuICAgICAgY3JlYXRlU2VydmVyU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBzZXQga2VlcEFsaXZlVGltZW91dCBhbmQgaGVhZGVyc1RpbWVvdXQgaWYgbm90IHNwZWNpZmllZCBpbiBjb25maWcgZm9yIEhUVFBTIHNlcnZlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNyZWF0ZVNlcnZlclN0dWIgPSBzaW5vbi5zdHViKGh0dHBzLCAnY3JlYXRlU2VydmVyJykuY2FsbHNGYWtlKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHsgbGlzdGVuOiBzaW5vbi5zdHViKCksIHNldFRpbWVvdXQ6IHNpbm9uLnN0dWIoKSB9IGFzIHVua25vd24gYXMgaHR0cHMuU2VydmVyO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGFyZ3M6IGFueSA9IHtcbiAgICAgICAgZW52OiAndGVzdCcsXG4gICAgICAgIGJpbmQ6ICdsb2NhbGhvc3QnLFxuICAgICAgICBzc2xLZXk6ICdzc2wta2V5JyxcbiAgICAgICAgc3NsQ2VydDogJ3NzbC1jZXJ0JyxcbiAgICAgICAgLy8ga2VlcEFsaXZlVGltZW91dCBhbmQgaGVhZGVyc1RpbWVvdXQgYXJlIG5vdCBzcGVjaWZpZWRcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHNlcnZlciA9IGF3YWl0IGNyZWF0ZVNlcnZlcihhcmdzLCBudWxsIGFzIGFueSk7XG5cbiAgICAgIHNob3VsZChzZXJ2ZXIua2VlcEFsaXZlVGltZW91dCkuYmUudW5kZWZpbmVkKCk7XG4gICAgICBzaG91bGQoc2VydmVyLmhlYWRlcnNUaW1lb3V0KS5iZS51bmRlZmluZWQoKTtcblxuICAgICAgY3JlYXRlU2VydmVyU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!