bitgo
Version:
BitGo JavaScript SDK
4,319 lines • 697 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// Tests for Wallets
//
const assert = require("assert");
const nock = require("nock");
const sinon = require("sinon");
const should = require("should");
const _ = require("lodash");
const utxoLib = require("@bitgo/utxo-lib");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_core_1 = require("@bitgo/sdk-core");
const src_1 = require("../../../src");
const mocha_1 = require("mocha");
const moduleBitgo = require("@bitgo/sdk-core");
describe('V2 Wallets:', function () {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
let wallets;
let ofcWallets;
let bgUrl;
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
bitgo.initializeTestVars();
const basecoin = bitgo.coin('tbtc');
wallets = basecoin.wallets();
ofcWallets = bitgo.coin('ofc').wallets();
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
describe('Add Wallet:', function () {
it('throws on invalid arguments', async function () {
// isCustodial flag is not a boolean
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, isCustodial: 1 })
.should.be.rejectedWith('invalid argument for isCustodial - boolean expected');
// type is not a string
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, type: 1 })
.should.be.rejectedWith('Expecting parameter string: type but found number');
// Address is an invalid address
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, address: '$' })
.should.be.rejectedWith('invalid argument for address - valid address string expected');
// gasPrice is a number
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, gasPrice: '17' })
.should.be.rejectedWith('invalid argument for gasPrice - number expected');
// walletVersion is a number
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, walletVersion: '1' })
.should.be.rejectedWith('invalid argument for walletVersion - number expected');
});
it('creates a paired custodial wallet', async function () {
nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.isCustodial.should.be.true();
body.should.have.property('keys');
body.m.should.equal(2);
body.n.should.equal(3);
return true;
})
.reply(200, {});
await wallets.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, isCustodial: true });
});
it('creates an eos wallet with custom address', async function () {
const eosBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
eosBitGo.initializeTestVars();
const eosWallets = eosBitGo.coin('teos').wallets();
const address = 'testeosaddre';
nock(bgUrl)
.post('/api/v2/teos/wallet/add', function (body) {
body.should.have.property('keys');
body.m.should.equal(2);
body.n.should.equal(3);
body.address.should.equal(address);
return true;
})
.reply(200, {});
await eosWallets.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, address });
});
it('creates a single custodial wallet', async function () {
nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('custodial');
body.should.not.have.property('keys');
body.should.not.have.property('m');
body.should.not.have.property('n');
return true;
})
.reply(200, {});
await wallets.add({ label: 'label', enterprise: 'enterprise', type: 'custodial' });
});
it('creates a wallet with custom gasPrice', async function () {
const ethBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
ethBitGo.initializeTestVars();
const ethWallets = ethBitGo.coin('teth').wallets();
nock(bgUrl)
.post('/api/v2/teth/wallet/add', function (body) {
body.type.should.equal('custodial');
body.gasPrice.should.equal(20000000000);
body.should.not.have.property('keys');
body.should.not.have.property('m');
body.should.not.have.property('n');
return true;
})
.reply(200, {});
await ethWallets.add({
label: 'label',
enterprise: 'enterprise',
type: 'custodial',
gasPrice: 20000000000,
});
});
it('creates a new wallet with walletVersion', async function () {
const ethBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
ethBitGo.initializeTestVars();
const ethWallets = ethBitGo.coin('teth').wallets();
nock(bgUrl)
.post('/api/v2/teth/wallet/add', function (body) {
body.type.should.equal('custodial');
body.walletVersion.should.equal(1);
body.should.not.have.property('keys');
body.should.not.have.property('m');
body.should.not.have.property('n');
return true;
})
.reply(200, {});
await ethWallets.add({ label: 'label', enterprise: 'enterprise', type: 'custodial', walletVersion: 1 });
});
it('creates a new hot wallet with userKey', async function () {
nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('hot');
body.should.have.property('keys');
body.should.have.property('m');
body.should.have.property('n');
return true;
})
.reply(200, {});
await wallets.add({
label: 'label',
enterprise: 'enterprise',
type: 'hot',
keys: [],
m: 2,
n: 3,
userKey: 'test123',
});
});
});
describe('Generate wallet:', function () {
const sandbox = sinon.createSandbox();
it('should validate parameters', async function () {
let params = {};
await wallets.generateWallet(params).should.be.rejectedWith('Missing parameter: label');
params = {
label: 'abc',
backupXpub: 'backup',
backupXpubProvider: 'provider',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('Cannot provide more than one backupXpub or backupXpubProvider flag');
params = {
label: 'abc',
passcodeEncryptionCode: 123,
};
await wallets.generateWallet(params).should.be.rejectedWith('passcodeEncryptionCode must be a string');
params = {
label: 'abc',
enterprise: 1234,
};
await wallets.generateWallet(params).should.be.rejectedWith('invalid enterprise argument, expecting string');
params = {
label: 'abc',
disableTransactionNotifications: 'string',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid disableTransactionNotifications argument, expecting boolean');
params = {
label: 'abc',
gasPrice: 'string',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid gas price argument, expecting number or number as string');
params = {
label: 'abc',
gasPrice: true,
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid gas price argument, expecting number or number as string');
params = {
label: 'abc',
gasPrice: 123,
eip1559: {
maxFeePerGas: 1234,
maxPriorityFeePerGas: 123,
},
};
await wallets.generateWallet(params).should.be.rejectedWith('can not use both eip1559 and gasPrice values');
params = {
label: 'abc',
eip1559: {
maxFeePerGas: 'q1234',
maxPriorityFeePerGas: '123',
},
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid max fee argument, expecting number or number as string');
params = {
label: 'abc',
eip1559: {
maxFeePerGas: 1234,
maxPriorityFeePerGas: '123a',
},
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid priority fee argument, expecting number or number as string');
params = {
label: 'abc',
disableKRSEmail: 'string',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid disableKRSEmail argument, expecting boolean');
params = {
label: 'abc',
krsSpecific: {
malicious: {
javascript: {
code: 'bad.js',
},
},
},
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('krsSpecific object contains illegal values. values must be strings, booleans, or numbers');
});
it('should correctly disable krs emails when creating backup keychains', async function () {
const params = {
label: 'my_wallet',
disableKRSEmail: true,
backupXpubProvider: 'test',
passphrase: 'test123',
userKey: 'xpub123',
};
// bitgo key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
// user key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200);
// backup key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({
source: 'backup',
provider: params.backupXpubProvider,
disableKRSEmail: true,
}))
.reply(200);
// wallet
nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
await wallets.generateWallet(params);
});
it('should correctly pass through the krsSpecific param when creating backup keychains', async function () {
const params = {
label: 'my_wallet',
backupXpubProvider: 'test',
passphrase: 'test123',
userKey: 'xpub123',
krsSpecific: { coverage: 'insurance', expensive: true, howExpensive: 25 },
};
// bitgo key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
// user key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200);
// backup key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({
source: 'backup',
provider: params.backupXpubProvider,
krsSpecific: { coverage: 'insurance', expensive: true, howExpensive: 25 },
}))
.reply(200);
// wallet
nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
await wallets.generateWallet(params);
});
it('should send the cold derivation seed for a user key', async () => {
const params = {
label: 'my-cold-wallet',
passphrase: 'test123',
userKey: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
coldDerivationSeed: '123',
};
// bitgo key
const bitgoKeyNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
// user key
const userKeyNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({
derivedFromParentWithSeed: params.coldDerivationSeed,
}))
.reply(200);
// backup key
const backupKeyNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200);
// wallet
const walletNock = nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
await wallets.generateWallet(params);
for (const scope of [bitgoKeyNock, userKeyNock, backupKeyNock, walletNock]) {
scope.done();
}
});
it('should generate custodial onchain wallet without passing m, n, keys, keySignatures', async () => {
const params = {
label: 'test wallet',
enterprise: 'myenterprise',
type: 'custodial',
};
const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('custodial');
should.not.exist(body.m);
should.not.exist(body.n);
should.not.exist(body.keys);
should.not.exist(body.keySignatures);
return true;
})
.reply(200, { id: '123', baseCoin: bitgo.coin('tbtc'), keys: ['123', '456', '789'] });
nock(bgUrl).get('/api/v2/tbtc/key/123').reply(200, { pub: 'bitgoPub', id: '789' });
nock(bgUrl).get('/api/v2/tbtc/key/456', _.matches({})).reply(200);
nock(bgUrl).get('/api/v2/tbtc/key/789').reply(200, { pub: 'backupPub', id: '789' });
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase === undefined);
assert.ok(response.wallet);
});
it('should generate hot onchain wallet', async () => {
const params = {
label: 'test wallet',
passphrase: 'multisig password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('hot');
return true;
})
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200, { pub: 'bitgoPub' });
nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200, { pub: 'backupPub' });
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should generate hot onchain wallet without passing multisig type', async () => {
const params = {
label: 'test wallet',
passphrase: 'multisig password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('hot');
return true;
})
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200, { pub: 'bitgoPub' });
nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200, { pub: 'backupPub' });
const generateWalletSpy = sandbox.spy(wallets, 'generateWallet');
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
sinon.assert.calledOnce(generateWalletSpy);
assert.equal(generateWalletSpy.firstCall?.args[0]?.multisigType, sdk_core_1.multisigTypes.onchain);
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should generate Go Account wallet', async () => {
const params = {
label: 'Go Account Wallet',
passphrase: 'go_account_password',
enterprise: 'enterprise-id',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
type: 'trading',
};
const keychainId = 'user_keychain_id';
// Mock keychain creation and upload
nock(bgUrl)
.post('/api/v2/ofc/key', function (body) {
body.should.have.property('encryptedPrv');
body.should.have.property('originalPasscodeEncryptionCode');
body.keyType.should.equal('independent');
body.source.should.equal('user');
return true;
})
.reply(200, { id: keychainId, pub: 'userPub', encryptedPrv: 'encryptedPrivateKey' });
// Mock wallet creation
const walletNock = nock(bgUrl)
.post('/api/v2/ofc/wallet/add', function (body) {
body.type.should.equal('trading');
body.m.should.equal(1);
body.n.should.equal(1);
body.keys.should.have.length(1);
body.keys[0].should.equal(keychainId);
return true;
})
.reply(200, { id: 'wallet123', keys: [keychainId] });
const response = await ofcWallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.ok('userKeychain' in response);
});
});
describe('Generate TSS wallet:', function () {
const tsol = bitgo.coin('tsol');
const sandbox = sinon.createSandbox();
beforeEach(function () {
nock('https://bitgo.fakeurl')
.get(`/api/v2/tss/settings`)
.query(true)
.times(2)
.reply(200, {
coinSettings: {
eth: {
walletCreationSettings: {},
},
bsc: {
walletCreationSettings: {},
},
polygon: {
walletCreationSettings: {},
},
},
});
});
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
sandbox.verifyAndRestore();
});
it('should create a new TSS wallet', async function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should create a new TSS wallet without passing multisig type', async function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/wallet/add', function (body) {
body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const generateWalletSpy = sandbox.spy(wallets, 'generateWallet');
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
sinon.assert.calledOnce(generateWalletSpy);
assert.equal(generateWalletSpy.firstCall?.args[0]?.multisigType, sdk_core_1.multisigTypes.tss);
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should create a new TSS wallet without providing passcodeEncryptionCode', async function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const response = await wallets.generateWallet({
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
});
walletNock.isDone().should.be.true();
assert.ok(response.wallet);
assert.ok(response.encryptedWalletPassphrase === undefined);
});
it('should fail to create TSS wallet with invalid inputs', async function () {
const tbtc = bitgo.coin('tbtc');
const params = {
label: 'my-cold-wallet',
passphrase: 'test123',
userKey: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
coldDerivationSeed: '123',
};
const wallets = new sdk_core_1.Wallets(bitgo, tbtc);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ derivedFromParentWithSeed: params.coldDerivationSeed }))
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200);
nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
// create a non tss wallet for coin that doesn't support tss even though multisigType is set to tss
await wallets.generateWallet({ ...params, multisigType: 'tss' });
const tsolWallets = new sdk_core_1.Wallets(bitgo, tsol);
await tsolWallets
.generateWallet({
label: 'tss cold wallet',
passphrase: 'passphrase',
userKey: 'user key',
multisigType: 'tss',
})
.should.be.rejectedWith('enterprise is required for TSS wallet');
await tsolWallets
.generateWallet({
label: 'tss cold wallet',
userKey: 'user key',
multisigType: 'tss',
enterprise: 'enterpriseId',
})
.should.be.rejectedWith('cannot generate TSS keys without passphrase');
});
it('should create a new TSS custodial wallet', async function () {
const keys = ['1', '2', '3'];
const walletParams = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
type: 'custodial',
};
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/wallet/add')
.times(1)
.reply(200, { ...walletParams, keys });
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const res = await wallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
res.wallet.multisigType().should.equal(walletParams.multisigType);
res.userKeychain.id.should.equal(keys[0]);
res.backupKeychain.id.should.equal(keys[1]);
res.bitgoKeychain.id.should.equal(keys[2]);
walletNock.isDone().should.be.true();
});
it('should create a new FLRP TSS custodial wallet without requiring a passphrase', async function () {
const keys = ['1', '2', '3'];
const tflrp = bitgo.coin('tflrp');
const walletParams = {
label: 'flrp custodial wallet',
enterprise: 'enterprise',
type: 'custodial',
// No multisigType specified — should default to 'tss' for FLRP
// No passphrase — custodial wallets must not require one
};
// FLRP is ECDSA, so generateCustodialMpcWallet fetches TSS settings
nock('https://bitgo.fakeurl')
.get('/api/v2/tss/settings')
.query(true)
.reply(200, { coinSettings: { flrp: { walletCreationSettings: {} } } });
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tflrp/wallet/add')
.times(1)
.reply(200, { ...walletParams, multisigType: 'tss', keys });
const flrpWallets = new sdk_core_1.Wallets(bitgo, tflrp);
const res = await flrpWallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.multisigType().should.equal('tss');
res.userKeychain.id.should.equal(keys[0]);
res.backupKeychain.id.should.equal(keys[1]);
res.bitgoKeychain.id.should.equal(keys[2]);
walletNock.isDone().should.be.true();
});
it('should create a new TSS SMC wallet', async function () {
const commonKeychain = 'longstring';
const seed = 'seed';
const keys = {
userKeychain: {
id: '1',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain,
type: 'tss',
source: 'bitgo',
},
};
const bitgoKeyNock = nock('https://bitgo.fakeurl').get('/api/v2/tsol/key/3').reply(200, keys.bitgoKeychain);
const userKeyExpectedBody = {
source: 'user',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: seed,
};
const userKeyNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/key', userKeyExpectedBody)
.reply(200, keys.userKeychain);
const backupKeyExpectedBody = {
source: 'backup',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: seed,
};
const backupKeyNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/key', backupKeyExpectedBody)
.reply(200, keys.backupKeychain);
const walletParams = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
type: 'cold',
bitgoKeyId: keys.bitgoKeychain.id,
commonKeychain,
coldDerivationSeed: seed,
};
const walletNockExpected = {
label: walletParams.label,
m: 2,
n: 3,
keys: [keys.userKeychain.id, keys.backupKeychain.id, keys.bitgoKeychain.id],
type: walletParams.type,
multisigType: walletParams.multisigType,
enterprise: walletParams.enterprise,
walletVersion: undefined,
};
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/wallet/add', walletNockExpected)
.reply(200, { ...walletNockExpected, responseType: 'WalletWithKeychains' });
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const res = await wallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.responseType.should.equal('WalletWithKeychains');
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
res.wallet.multisigType().should.equal(walletParams.multisigType);
res.userKeychain.should.deepEqual(keys.userKeychain);
res.backupKeychain.should.deepEqual(keys.backupKeychain);
res.bitgoKeychain.should.deepEqual(keys.bitgoKeychain);
bitgoKeyNock.isDone().should.be.true();
userKeyNock.isDone().should.be.true();
backupKeyNock.isDone().should.be.true();
walletNock.isDone().should.be.true();
});
it('should throw an error for TSS SMC wallet if the bitgoKeyId is not a bitgo key ', async function () {
const commonKeychain = 'longstring';
const seed = 'seed';
const keys = {
userKeychain: {
id: '1',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain,
type: 'tss',
source: 'bitgo',
},
};
const bitgoKeyNock = nock('https://bitgo.fakeurl').get('/api/v2/tsol/key/1').reply(200, keys.userKeychain);
const walletParams = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
type: 'cold',
bitgoKeyId: keys.userKeychain.id,
commonKeychain,
coldDerivationSeed: seed,
};
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
await wallets
.generateWallet(walletParams)
.should.be.rejectedWith('The provided bitgoKeyId is not a BitGo keychain');
bitgoKeyNock.isDone().should.be.true();
});
});
describe('Generate TSS MPCv2 wallet:', async function () {
const sandbox = sinon.createSandbox();
beforeEach(function () {
const tssSettings = {
coinSettings: {
eth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
bsc: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
polygon: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
atom: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
tia: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
bera: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
arbeth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
opeth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
},
};
nock('https://bitgo.fakeurl').get(`/api/v2/tss/settings`).query(true).times(2).reply(200, tssSettings);
});
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
sandbox.verifyAndRestore();
});
['hteth', 'tbsc', 'tpolygon', 'ttia', 'tatom', 'tbera', 'tarbeth', 'topeth'].forEach((coin) => {
it(`should create a new ${coin} TSS MPCv2 hot wallet`, async function () {
const testCoin = bitgo.coin(coin);
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post(`/api/v2/${coin}/wallet/add`).reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it(`should create a new ${coin} TSS MPCv2 hot wallet without passing multisig type`, async function () {
const testCoin = bitgo.coin(coin);
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/wallet/add`, function (body) {
body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it(`should create a new ${coin} TSS MPCv2 cold wallet`, async function () {
const testCoin = bitgo.coin(coin);
const bitgoKeyId = 'key123';
const commonKeychain = '0xabc';
const bitgoKeyNock = nock('https://bitgo.fakeurl')
.get(`/api/v2/${coin}/key/${bitgoKeyId}`)
.times(1)
.reply(200, {
id: 'key123',
pub: 'bitgoPub',
type: 'tss',
source: 'bitgo',
commonKeychain,
});
const userKeyNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/key`, {
source: 'user',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: '37',
isMPCv2: true,
})
.times(1)
.reply(200, {
id: 'userKey123',
pub: 'userPub',
type: 'tss',
source: 'user',
});
const backupKeyNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/key`, {
source: 'backup',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: '37',
isMPCv2: true,
})
.times(1)
.reply(200, {
id: 'backupKey123',
pub: 'backupPub',
type: 'tss',
source: 'backup',
});
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/wallet/add`, {
label: 'tss wallet',
m: 2,
n: 3,
keys: ['userKey123', 'backupKey123', 'key123'],
type: 'cold',
multisigType: 'tss',
enterprise: 'enterprise',
walletVersion: 5,
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 5,
type: 'cold',
bitgoKeyId: 'key123',
commonKeychain: '0xabc',
coldDerivationSeed: '37',
};
const response = (await wallets.generateWallet(params));
bitgoKeyNock.isDone().should.be.true();
userKeyNock.isDone().should.be.true();
backupKeyNock.isDone().should.be.true();
walletNock.isDone().should.be.true();
should.exist(response.wallet);
should.exist(response.userKeychain);
should.exist(response.backupKeychain);
should.exist(response.bitgoKeychain);
response.responseType.should.equal('WalletWithKeychains');
response.userKeychain.id.should.equal('userKey123');
response.backupKeychain.id.should.equal('backupKey123');
response.bitgoKeychain.id.should.equal('key123');
});
it(`should create a new ${coin} TSS MPCv2 custody wallet`, async function () {
const testCoin = bitgo.coin(coin);
const keys = ['userKey', 'backupKey', 'bitgoKey'];
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 5,
type: 'custodial',
};
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/wallet/add`)
.times(1)
.reply(200, { ...params, keys });
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const response = (await wallets.generateWallet(params));
walletNock.isDone().should.be.true();
should.exist(response.wallet);
should.exist(response.userKeychain);
should.exist(response.backupKeychain);
should.exist(response.bitgoKeychain);
response.responseType.should.equal('WalletWithKeychains');
response.userKeychain.id.should.equal(keys[0]);
response.backupKeychain.id.should.equal(keys[1]);
response.bitgoKeychain.id.should.equal(keys[2]);
});
});
it(`should create a new hteth TSS MPCv2 wallet with walletVersion 6`, async function () {
const testCoin = bitgo.coin('hteth');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/hteth/wallet/add`, (body) => {
body.walletVersion.should.equal(6);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 6,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it(`should create a new MPCv2 wallet with version 5 if walletVersion passed is not 5 or 6`, async function () {
const testCoin = bitgo.coin('hteth');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/hteth/wallet/add`, (body) => {
body.walletVersion.should.equal(5);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
});
describe('Generate TSS EdDSA MPCv2 wallet:', async function () {
const sandbox = sinon.createSandbox();
beforeEach(function () {
const tssSettings = {
coinSettings: {
sol: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
},
},
},
};
nock('https://bitgo.fakeurl').get(`/api/v2/tss/settings`).query(true).times(2).reply(200, tssSettings);
});
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
sandbox.verifyAndRestore();
});
it('should create a new tsol TSS EdDSA MPCv2 hot wallet', async function () {
const testCoin = bitgo.coin('tsol');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.EDDSAUtils.EddsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss eddsa mpcv2 wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should fall back to EddsaUtils when tss/settings does not return MPCv2 for tsol', async function () {
nock.cleanAll();
nock('https://bitgo.fakeurl')
.get('/api/v2/tss/settings')
.query(true)
.reply(200, { coinSettings: { sol: { walletCreationSettings: {} } } });
const testCoin = bitgo.coin('tsol');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubEddsaUtils = sandbox
.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss eddsa wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubEddsaUtils.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
});
});
describe('Sharing', () => {
describe('Wallet share where keychainOverrideRequired is set true', () => {
const sandbox = sinon.createSandbox();
(0, mocha_1.afterEach)(function () {
sandbox.verifyAndRestore();
});
it('when password not provived we should receive validation error', async function () {
const shareId = 'test_case_1';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
});
// Validate accept share case
await ofcWallets
.acceptShare({ walletShareId: shareId })
.should.be.rejectedWith('userPassword param must be provided to decrypt shared key');
walletShareNock.done();
});
it('when we accept share and failed to make changes, reshare should not be called', async function () {
const shareId = 'test_case_2';
const keychainId = 'test_case_2';
const userPassword = 'test_case_2';
// create a user key
const keyChainNock = nock(bgUrl)
.post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const walletShareInfoNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: false });
// Stub wallet share wallet method
const walletShareStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'shareWallet').onCall(0).resolves('success');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, false);
keyChainNock.done();
walletShareInfoNock.done();
acceptShareNock.done();
should.equal(walletShareStub.called, false);
});
it('when we accept share but state is not valid, reshare should not be called', async function () {
const shareId = 'test_case_3';
const keychainId = 'test_case_3';
const userPassword = 'test_case_3';
// create a user key
const keyChainNock = nock(bgUrl)
.post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const walletShareInfoNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: true, state: 'not_accepted' });
// Stub wallet share wallet method
const walletShareStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'shareWallet').onCall(0).resolves('success');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'not_accepted');
keyChainNock.done();
walletShareInfoNock.done();
acceptShareNock.done();
should.equal(walletShareStub.called, false);
});
it('when we get a correct resposne from accept share method, but failed to reshare wallet with spenders', async function () {
const shareId = 'test_case_6';
const keychainId = 'test_case_6';
const spenderUserOne = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_6',
},
email: { email: 'test_case_6' },
id: 'test_case_6',
coin: 'ofc',
};
const spenderUserTwo = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_9',
},
email: { email: 'test_case_9' },
id: 'test_case_9',
coin: 'ofc',
};
const adminUser = {
payload: {
permissions: ['admin', 'spend', 'view'],
user: 'test_case_7',
},
email: { email: 'test_case_7' },
id: 'test_case_7',
coin: 'ofc',
};
const viewerUser = {
payload: {
permissions: ['view'],
user: 'test_case_8',
},
email: { email: 'test_case_8' },
id: 'test_case_8',
coin: 'ofc',
};
const userPassword = 'test_case_6';
const walletId = 'test_case_6';
const enterpriseId = 'test_case_6';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
// create a user key
const keyChainCreateNock = nock(bgUrl)
.post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: true, state: 'accepted' });
const walletInfoNock = nock(bgUrl)
.get(`/api/v2/ofc/wallet/${walletId}`)
.reply(200, {
users: [spenderUserOne.payload, spenderUserTwo.payload, adminUser.payload, viewerUser.payload],
enterprise: enterpriseId,
coin: spenderUserOne.coin,
id: walletId,
keys: [{}],
});
const enterpriseUserNock = nock(bgUrl)
.get(`/api/v1/enterprise/${enterpriseId}/user`)
.reply(200, {
adminUsers: [
{ id: spenderUserOne.id, email: spenderUserOne.email },
{ id: spenderUserTwo.id, email: spenderUserTwo.email },
{ id: adminUser.id, email: adminUser.email },
{ id: viewerUser.id, email: viewerUser.email },
],
nonAdminUsers: [],
});
const walletShareStub = sandbox
.stub(sdk_core_1.Wallet.prototype, 'shareWallet')
.returns(new Promise((_resolve, reject) => reject(new Error('Failed to reshare wallet'))));
const shareParamsOne = {
walletId: walletId,
user: spenderUserOne.id,
permissions: spenderUserOne.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserOne.email.email,
reshare: true,
skipKeychain: false,
};
const shareParamsTwo = {
walletId: walletId,
user: spenderUserTwo.id,
permissions: spenderUserTwo.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserTwo.email.email,
reshare: true,
skipKeychain: false,
};
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
keyChainCreateNock.done();
walletShareNock.done();
walletInfoNock.done();
acceptShareNock.done();
enterpriseUserNock.done();
should.equal(walletShareStub.calledOnce, true);
should.equal(walletShareStub.calledWith(shareParamsOne), true);
should.equal(walletShareStub.calledWith(shareParamsTwo), false);
});
it('when we get a correct resposne from accept share method and reshare wallet with spenders', async function () {
const shareId = 'test_case_6';
const keychainId = 'test_case_6';
const spenderUserOne = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_6',
},
email: { email: 'test_case_6' },
id: 'test_case_6',
coin: 'ofc',
};
const spenderUserTwo = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_9',
},
email: { email: 'test_case_9' },
id: 'test_case_9',
coin: 'ofc',
};
const adminUser = {
payload: {
permissions: ['admin', 'spend', 'view'],
user: 'test_case_7',
},
email: { email: 'test_case_7' },
id: 'test_case_7',
coin: 'ofc',
};
const viewerUser = {
payload: {
permissions: ['view'],
user: 'test_case_8',
},
email: { email: 'test_case_8' },
id: 'test_case_8',
coin: 'ofc',
};
const userPassword = 'test_case_6';
const walletId = 'test_case_6';
const enterpriseId = 'test_case_6';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/tbtc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
// create a user key
const keyChainCreateNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/tbtc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: true, state: 'accepted' });
const walletInfoNock = nock(bgUrl)
.get(`/api/v2/tbtc/wallet/${walletId}`)
.reply(200, {
users: [spenderUserOne.payload, spenderUserTwo.payload, adminUser.payload, viewerUser.payload],
enterprise: enterpriseId,
coin: spenderUserOne.coin,
id: walletId,
keys: [{}],
});
const enterpriseUserNock = nock(bgUrl)
.get(`/api/v1/enterprise/${enterpriseId}/user`)
.reply(200, {
adminUsers: [
{ id: spenderUserOne.id, email: spenderUserOne.email },
{ id: spenderUserTwo.id, email: spenderUserTwo.email },
{ id: adminUser.id, email: adminUser.email },
{ id: viewerUser.id, email: viewerUser.email },
],
nonAdminUsers: [],
});
const walletShareStub = sandbox
.stub(sdk_core_1.Wallet.prototype, 'shareWallet')
.returns(new Promise((resolve, _reject) => resolve('success')));
const shareParamsOne = {
walletId: walletId,
user: spenderUserOne.id,
permissions: spenderUserOne.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserOne.email.email,
reshare: true,
skipKeychain: false,
};
const shareParamsTwo = {
walletId: walletId,
user: spenderUserTwo.id,
permissions: spenderUserTwo.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserTwo.email.email,
reshare: true,
skipKeychain: false,
};
const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
keyChainCreateNock.done();
walletShareNock.done();
walletInfoNock.done();
acceptShareNock.done();
enterpriseUserNock.done();
should.equal(walletShareStub.calledTwice, true);
should.equal(walletShareStub.calledWith(shareParamsOne), true);
should.equal(walletShareStub.calledWith(shareParamsTwo), true);
});
});
describe('Wallet share where userMultiKeyRotationRequired is set true', () => {
const sandbox = sinon.createSandbox();
(0, mocha_1.afterEach)(function () {
sandbox.verifyAndRestore();
});
it('should throw error when password not provided', async function () {
const shareId = 'test_multi_key_1';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
});
await ofcWallets
.acceptShare({ walletShareId: shareId })
.should.be.rejectedWith('userPassword param must be provided to generate user keychain');
walletShareNock.done();
});
it('should successfully accept share with userMultiKeyRotationRequired and send pub and encryptedPrv', async function () {
const shareId = 'test_multi_key_2';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
// Mock wallet share response
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
// Mock keychain creation - baseCoin.keychains().create() returns { prv, pub }
// We need to create a proper keychain object with prv property
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv, // OFC uses secp256k1 keys, so prv format
pub: testKeychain.pub,
};
// Stub keychains().create() and encrypt() BEFORE calculating encryptedPrv
const keychainsInstance = ofcWallets.baseCoin.keychains();
const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Mock the updateShare API call
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Verify that pub and encryptedPrv are included
if (body.walletShareId !== shareId || body.state !== 'accepted' || !body.pub || !body.encryptedPrv) {
return false;
}
// Verify pub is a valid format (secp256k1 public key for OFC)
if (!ofcWallets.baseCoin.isValidPub(body.pub)) {
return false;
}
return true;
})
.reply(200, { changed: true, state: 'accepted' });
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify keychain creation was called
should.equal(keychainsStub.calledOnce, true);
// Verify encrypt was called with the correct parameters
should.equal(encryptStub.calledWith({ input: keychain.prv, password: userPassword }), true);
walletShareNock.done();
acceptShareNock.done();
});
it('should NOT trigger reshare when userMultiKeyRotationRequired is true', async function () {
const shareId = 'test_multi_key_3';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, { changed: true, state: 'accepted' });
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Stub reshareWalletWithSpenders to verify it's NOT called
const reshareStub = sandbox.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify reshare was NOT called (unlike keychainOverrideRequired case)
should.equal(reshareStub.called, false);
walletShareNock.done();
acceptShareNock.done();
});
it('should handle bulk accept share with userMultiKeyRotationRequired', async function () {
const shareId = 'test_multi_key_bulk_1';
const userPassword = 'test_password_123';
// Mock listSharesV2 to return a share with userMultiKeyRotationRequired
// Note: userMultiKeyRotationRequired shares don't have a keychain, so they won't be filtered
// by the bulkAcceptShare filter, but processAcceptShare will handle them
sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'test wallet',
fromUser: 'fromUser',
toUser: 'toUser',
wallet: 'wallet123',
permissions: ['admin', 'spend', 'view'],
state: 'active',
userMultiKeyRotationRequired: true,
// No keychain - this is the key difference for multi-key-user-key shares
},
],
outgoing: [],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Mock bulk update API - this is called via bulkUpdateWalletShare
nock(bgUrl)
.put('/api/v2/walletshares/update', (body) => {
if (!body.shares || body.shares.length !== 1) {
return false;
}
const share = body.shares[0];
return (share.walletShareId === shareId &&
share.status === 'accept' &&
share.pub === keychain.pub &&
share.encryptedPrv === encryptedPrv);
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Note: bulkAcceptShare filters for shares WITH keychains, but userMultiKeyRotationRequired
// shares don't have keychains, so they go through a different path
// We need to stub the processAcceptShare path or use bulkUpdateWalletShare directly
// For this test, we'll use bulkUpdateWalletShare which calls processAcceptShare internally
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
userLoginPassword: userPassword,
});
should.equal(result.acceptedWalletShares.length, 1);
should.deepEqual(result.acceptedWalletShares[0], { walletShareId: 'test_multi_key_bulk_1' });
should.equal(keychainsStub.calledOnce, true);
should.equal(encryptStub.calledWith({ input: keychain.prv, password: userPassword }), true);
});
it('should handle bulk accept share with userMultiKeyRotationRequired and newWalletPassphrase', async function () {
const shareId = 'test_multi_key_bulk_2';
const userPassword = 'test_password_123';
const newWalletPassphrase = 'new_wallet_passphrase_456';
// Mock listSharesV2 to return a share with userMultiKeyRotationRequired
sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'test wallet',
fromUser: 'fromUser',
toUser: 'toUser',
wallet: 'wallet123',
permissions: ['admin', 'spend', 'view'],
state: 'active',
userMultiKeyRotationRequired: true,
// No keychain - this is the key difference for multi-key-user-key shares
},
],
outgoing: [],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
// Should encrypt with newWalletPassphrase if provided (as per implementation)
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: newWalletPassphrase });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Mock bulk update API - this is called via bulkUpdateWalletShare
nock(bgUrl)
.put('/api/v2/walletshares/update', (body) => {
if (!body.shares || body.shares.length !== 1) {
return false;
}
const share = body.shares[0];
return (share.walletShareId === shareId &&
share.status === 'accept' &&
share.pub === keychain.pub &&
share.encryptedPrv === encryptedPrv);
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
userLoginPassword: userPassword,
newWalletPassphrase: newWalletPassphrase,
});
should.equal(result.acceptedWalletShares.length, 1);
should.deepEqual(result.acceptedWalletShares[0], { walletShareId: shareId });
should.equal(keychainsStub.calledOnce, true);
// Verify encrypt was called with newWalletPassphrase (not userPassword)
should.equal(encryptStub.calledWith({ input: keychain.prv, password: newWalletPassphrase }), true);
});
it('should throw error when neither userLoginPassword nor newWalletPassphrase provided for bulk accept', async function () {
const shareId = 'test_multi_key_bulk_3';
// Mock listSharesV2 to return a share with userMultiKeyRotationRequired
sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'test wallet',
fromUser: 'fromUser',
toUser: 'toUser',
wallet: 'wallet123',
permissions: ['admin', 'spend', 'view'],
state: 'active',
userMultiKeyRotationRequired: true,
},
],
outgoing: [],
});
// Mock user settings API call (required by bulkUpdateWalletShare)
nock(bgUrl).get('/api/v1/user/settings').reply(200, {});
// Mock bulkUpdateWalletShareRequest - when there are errors, it's called with empty array
nock(bgUrl)
.put('/api/v2/walletshares/update', (body) => {
return body.shares && body.shares.length === 0;
})
.reply(200, {
acceptedWalletShares: [],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// bulkUpdateWalletShare uses Promise.allSettled, so errors are caught and returned in walletShareUpdateErrors
// We need to check the result for errors instead of expecting a rejection
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
});
// Verify that the error was captured in walletShareUpdateErrors
should.equal(result.walletShareUpdateErrors.length, 1);
should.equal(result.walletShareUpdateErrors[0].walletShareId, shareId);
should(result.walletShareUpdateErrors[0].reason).containEql('userLoginPassword param must be provided to generate user keychain');
});
it('should work with newWalletPassphrase parameter', async function () {
const shareId = 'test_multi_key_4';
const userPassword = 'test_password_123';
const newWalletPassphrase = 'new_wallet_passphrase_456';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Stub create() and encrypt() BEFORE calculating encryptedPrv to ensure consistency
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
// Should encrypt with newWalletPassphrase if provided (as per implementation)
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: newWalletPassphrase });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.pub === keychain.pub &&
body.encryptedPrv === encryptedPrv);
})
.reply(200, { changed: true, state: 'accepted' });
const res = await ofcWallets.acceptShare({
walletShareId: shareId,
userPassword,
newWalletPassphrase,
});
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify encrypt was called with newWalletPassphrase
should.equal(encryptStub.calledWith({ input: keychain.prv, password: newWalletPassphrase }), true);
walletShareNock.done();
acceptShareNock.done();
});
it('should prioritize userMultiKeyRotationRequired over keychainOverrideRequired', async function () {
const shareId = 'test_multi_key_5';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
keychainOverrideRequired: true, // Both set, but userMultiKeyRotationRequired should take precedence
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Should use the multi-key-user-key flow (no signature/payload/keyId)
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Verify it's using multi-key-user-key flow (has pub and encryptedPrv, but no signature/payload/keyId)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.pub === keychain.pub &&
body.encryptedPrv === encryptedPrv &&
!body.signature &&
!body.payload &&
!body.keyId);
})
.reply(200, { changed: true, state: 'accepted' });
const reshareStub = sandbox.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify reshare was NOT called (multi-key-user-key flow)
should.equal(reshareStub.called, false);
walletShareNock.done();
acceptShareNock.done();
});
it('should handle keychain creation failure', async function () {
const shareId = 'test_multi_key_6';
const userPassword = 'test_password_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const keychainError = new Error('Failed to create keychain');
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').throws(keychainError);
await ofcWallets
.acceptShare({ walletShareId: shareId, userPassword })
.should.be.rejectedWith('Failed to create keychain');
walletShareNock.done();
});
it('should handle encryption failure', async function () {
const shareId = 'test_multi_key_7';
const userPassword = 'test_password_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptionError = new Error('Encryption failed');
sandbox.stub(bitgo, 'encrypt').throws(encryptionError);
await ofcWallets
.acceptShare({ walletShareId: shareId, userPassword })
.should.be.rejectedWith('Encryption failed');
walletShareNock.done();
});
it('should work with view-only permissions', async function () {
const shareId = 'test_multi_key_8';
const userPassword = 'test_password_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['view'], // View-only permissions
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.pub === keychain.pub &&
body.encryptedPrv === encryptedPrv);
})
.reply(200, { changed: true, state: 'accepted' });
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
walletShareNock.done();
acceptShareNock.done();
});
it('should verify exact values sent in API request', async function () {
const shareId = 'test_multi_key_9';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
let capturedBody;
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
capturedBody = body;
return true;
})
.reply(200, { changed: true, state: 'accepted' });
await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
// Verify exact values
should.equal(capturedBody.walletShareId, shareId);
should.equal(capturedBody.state, 'accepted');
should.equal(capturedBody.pub, keychain.pub);
should.equal(capturedBody.encryptedPrv, encryptedPrv);
should.not.exist(capturedBody.signature);
should.not.exist(capturedBody.payload);
should.not.exist(capturedBody.keyId);
walletShareNock.done();
acceptShareNock.done();
});
});
it('should share a wallet to viewer', async function () {
const shareId = '12311';
nock(bgUrl).get(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, {});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/tbtc/walletshare/${shareId}`, { walletShareId: shareId, state: 'accepted' })
.reply(200, {});
await wallets.acceptShare({ walletShareId: shareId });
acceptShareNock.done();
});
describe('v2 envelope support in acceptShare', () => {
const sandbox = sinon.createSandbox();
(0, mocha_1.afterEach)(() => sandbox.verifyAndRestore());
it('should accept share when ECDH sharing keychain encryptedXprv is v2-encrypted', async function () {
const shareId = 'v2-ecdh-xprv-1';
const userPassword = 'test_password';
// Simulate a v2 envelope for the ECDH root key
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
const fakeXprv = 'xprvSomeBase58Value';
const fakeSecret = 'fakeEcdhSharedSecret';
const decryptedWalletPrv = 'walletPrivKeyPlaintext';
const eckey = (0, sdk_core_1.makeRandomKey)();
const v2EncryptedPrv = await bitgo.encrypt({ password: fakeSecret, input: decryptedWalletPrv });
nock(bgUrl)
.get(`/api/v2/tbtc/walletshare/${shareId}`)
.reply(200, {
keychain: {
path: 'm/0/0/1',
fromPubKey: eckey.publicKey.toString('hex'),
toPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: v2EncryptedPrv,
pub: eckey.publicKey.toString('hex'),
},
});
nock(bgUrl).post(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, { changed: true, state: 'accepted' });
sandbox.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
const decryptAsyncStub = sandbox.stub(bitgo, 'decrypt');
// First call decrypts the ECDH keychain (v2), second decrypts the shared wallet prv
decryptAsyncStub.onFirstCall().resolves(fakeXprv);
decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
sandbox.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(fakeSecret));
const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Must have called decrypt (not the sync decrypt) for both the ECDH key and the wallet prv
assert.equal(decryptAsyncStub.callCount, 2);
});
it('should accept share when wallet keychain encryptedPrv is v2-encrypted', async function () {
const shareId = 'v2-wallet-prv-1';
const userPassword = 'test_password';
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
const fakeXprv = 'xprvAnotherKey';
const fakeSecret = 'ecdhSharedSecret2';
const decryptedWalletPrv = 'walletPrivKey2';
const v2EncryptedPrv = JSON.stringify({ v: 2, iv: '112233', ct: '445566', adata: '77' });
const eckey = (0, sdk_core_1.makeRandomKey)();
nock(bgUrl)
.get(`/api/v2/tbtc/walletshare/${shareId}`)
.reply(200, {
keychain: {
path: 'm/0/0/2',
fromPubKey: eckey.publicKey.toString('hex'),
toPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: v2EncryptedPrv,
pub: eckey.publicKey.toString('hex'),
},
});
nock(bgUrl).post(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, { changed: true, state: 'accepted' });
sandbox.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
const decryptAsyncStub = sandbox.stub(bitgo, 'decrypt');
decryptAsyncStub.onFirstCall().resolves(fakeXprv);
decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
sandbox.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(fakeSecret));
const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
});
});
describe('bulkAcceptShare', function () {
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
sinon.restore();
});
it('should throw validation error for userPassword empty string', async () => {
await wallets
.bulkAcceptShare({ walletShareIds: [], userLoginPassword: '' })
.should.rejectedWith('Please provide a valid user login password');
});
it('should throw validation error for sending walletPassphrase empty string', async () => {
await wallets
.bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'password', newWalletPassphrase: 123 })
.should.rejectedWith('Please provide a valid wallet passphrase');
});
it('should throw assertion error for empty walletShareIds', async () => {
await wallets
.bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'dummy@123' })
.should.rejectedWith('Please provide at least one wallet share to accept');
});
it('should throw error for no valid wallet shares', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
await wallets
.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd1'],
userLoginPassword: 'dummy@123',
})
.should.rejectedWith('No valid wallet shares found to accept');
});
it('should throw error for no valid walletShares with keychain', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
await wallets
.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
userLoginPassword: 'dummy@123',
})
.should.rejectedWith('No valid wallet shares found to accept');
});
it('should throw error for ecdh keychain undefined', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
keychain: {
pub: 'pub',
toPubKey: 'toPubKey',
fromPubKey: 'fromPubKey',
encryptedPrv: 'encryptedPrv',
path: 'path',
},
},
],
outgoing: [],
});
sinon.stub(bitgo, 'getECDHKeychain').resolves({
prv: 'private key',
});
await wallets
.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
userLoginPassword: 'dummy@123',
})
.should.rejectedWith('encryptedXprv was not found on sharing keychain');
});
it('should successfully accept share', async () => {
const fromUserPrv = Math.random();
const walletPassphrase = 'bitgo1234';
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
isUMSInitiated: true,
keychain: {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, {
acceptedWalletShares: [
{
walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
},
],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
const share = await wallets.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
userLoginPassword: walletPassphrase,
});
assert.deepEqual(share, {
acceptedWalletShares: [
{
walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
},
],
});
});
it('should accept share when ECDH sharing keychain is v2-encrypted', async () => {
const walletPassphrase = 'bitgo1234';
const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const decryptedPrv = 'someWalletPrivateKey';
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedPrv });
// Simulate v2-encrypted ECDH keychain xprv (envelope with v:2 marker)
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aaa', ct: 'bbb', adata: 'ccc' });
const myEcdhXprv = 'xprvSomeBase58Key';
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, { acceptedWalletShares: [{ walletShareId: shareId }] });
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
// decrypt resolves with the xprv regardless of whether the envelope is v1 or v2
sinon.stub(bitgo, 'decrypt').resolves(myEcdhXprv);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
const share = await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
});
assert.deepEqual(share, { acceptedWalletShares: [{ walletShareId: shareId }] });
});
it('should accept share when wallet keychain encryptedPrv is v2-encrypted', async () => {
const walletPassphrase = 'bitgo1234';
const shareId = 'v2-prv-share-1';
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
// Simulate v2-encrypted encryptedPrv in the wallet share keychain
const v2EncryptedPrv = JSON.stringify({ v: 2, iv: 'xxx', ct: 'yyy', adata: 'zzz' });
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aaa', ct: 'bbb', adata: 'ccc' });
const myEcdhXprv = 'xprvSomeBase58Key';
const decryptedWalletPrv = 'decryptedWalletPrivKey';
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: v2EncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, { acceptedWalletShares: [{ walletShareId: shareId }] });
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
// First call: decrypt ECDH keychain xprv; second call: decrypt v2 wallet share prv
const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
decryptAsyncStub.onFirstCall().resolves(myEcdhXprv);
decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
const share = await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
});
assert.deepEqual(share, { acceptedWalletShares: [{ walletShareId: shareId }] });
// Both decrypt calls must use decrypt (not the sync decrypt)
assert.equal(decryptAsyncStub.callCount, 2);
});
it('should include webauthnInfo in request when provided (ECDH branch)', async () => {
const fromUserPrv = Math.random();
const walletPassphrase = 'bitgo1234';
const webauthnPassphrase = 'prf-derived-secret';
const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
let capturedBody;
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
capturedBody = body;
return true;
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
webauthnInfo: {
otpDeviceId: 'device-001',
prfSalt: 'salt-abc',
passphrase: webauthnPassphrase,
},
});
const sentEntries = capturedBody.keysForWalletShares;
sentEntries.should.have.length(1);
sentEntries[0].should.have.property('encryptedPrv');
sentEntries[0].should.have.property('webauthnInfo');
sentEntries[0].webauthnInfo.should.have.property('otpDeviceId', 'device-001');
sentEntries[0].webauthnInfo.should.have.property('prfSalt', 'salt-abc');
sentEntries[0].webauthnInfo.should.have.property('encryptedPrv');
sentEntries[0].webauthnInfo.should.not.have.property('passphrase');
});
it('should NOT include webauthnInfo when not provided (backward compat)', async () => {
const fromUserPrv = Math.random();
const walletPassphrase = 'bitgo1234';
const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
let capturedBody;
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
capturedBody = body;
return true;
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
});
const sentEntries = capturedBody.keysForWalletShares;
sentEntries.should.have.length(1);
sentEntries[0].should.have.property('encryptedPrv');
sentEntries[0].should.not.have.property('webauthnInfo');
});
it('should handle 413 payload too large error with smart retry', async () => {
const walletPassphrase = 'bitgo1234';
const fromUserPrv = Math.random();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
// Pad the private key with additional data to make it larger before encrypting
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
const keychain = {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
};
const shareIds = Array.from({ length: 20 }, (_, i) => `share${i + 1}`);
// Mock listSharesV2 to return 25 shares
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `testing${index}`,
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: `wallet${index}`,
permissions: ['spend'],
state: 'active',
keychain: keychain,
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: shares,
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(bitgo, 'encrypt').resolves(userPrv + 'X'.repeat(100000));
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
// Mock bulkAcceptShareRequestWithRetry to track batch sizes
const batchSizes = [];
nock(bgUrl)
.persist() // This ensures the interceptor remains active for multiple requests
.put('/api/v2/walletshares/accept')
.reply(function (_, requestBody, cb) {
const params = requestBody['keysForWalletShares'];
batchSizes.push(params.length);
if (Buffer.byteLength(JSON.stringify(requestBody), 'utf8') > 950000) {
// Simulate 413 error
return cb(null, [413, { error: 'Request Entity Too Large' }]);
}
// Return success for smaller batches
return cb(null, [
200,
{
acceptedWalletShares: params.map((param) => ({
walletShareId: param.walletShareId,
})),
},
]);
});
const result = await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
});
// Should have tried with 20 (initial batch size for 25 items), then retried with smaller batches
batchSizes.length.should.be.greaterThan(1);
batchSizes.should.deepEqual([9, 9, 2]); // Initial batch size// Retry batches should be smaller
result.should.have.property('acceptedWalletShares');
result.acceptedWalletShares.should.be.an.Array();
result.acceptedWalletShares.length.should.equal(20);
result.acceptedWalletShares.forEach((share) => {
share.should.have.property('walletShareId');
share.walletShareId.should.match(/^share\d+$/);
});
});
it('should retry with progressively smaller batch sizes on 413 errors', async () => {
const walletPassphrase = 'bitgo1234';
const fromUserPrv = Math.random();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
const keychain = {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
};
const shareIds = Array.from({ length: 20 }, (_, i) => `share${i + 1}`);
// Mock listSharesV2
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `testing${index}`,
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: `wallet${index}`,
permissions: ['spend'],
state: 'active',
keychain: keychain,
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: shares,
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(bitgo, 'encrypt').resolves(userPrv + 'X'.repeat(100000));
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
// Track the sequence of batch sizes attempted
const batchSizeAttempts = [];
nock(bgUrl)
.persist() // This ensures the interceptor remains active for multiple requests
.put('/api/v2/walletshares/accept')
.reply(function (_, requestBody, cb) {
const params = requestBody['keysForWalletShares'];
batchSizeAttempts.push(params.length);
// Simulate 413 for batches > 5, success for batches <= 5
if (Buffer.byteLength(JSON.stringify(requestBody), 'utf8') > 600000) {
// Simulate 413 error
return cb(null, [413, { error: 'Request Entity Too Large' }]);
}
// Return success for smaller batches
return cb(null, [
200,
{
acceptedWalletShares: params.map((param) => ({
walletShareId: param.walletShareId || 'test',
})),
},
]);
});
const result = await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
});
// Should see progressive batch size reduction: 20 -> 10 -> 5 (success)
batchSizeAttempts.should.containDeep([9, 4, 4, 4, 4, 4]);
result.should.have.property('acceptedWalletShares');
result.acceptedWalletShares.should.be.an.Array();
result.acceptedWalletShares.length.should.equal(20);
result.acceptedWalletShares.forEach((share) => {
share.should.have.property('walletShareId');
share.walletShareId.should.match(/^share\d+$/);
});
});
it('should throw error when batch size cannot be reduced further', async () => {
const walletPassphrase = 'bitgo1234';
const fromUserPrv = Math.random();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
const keychain = {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
};
const shareIds = ['share1'];
// Mock listSharesV2
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
keychain: keychain,
},
],
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
// Always throw 413 error, even for batch size 1
nock(bgUrl)
.persist()
.put('/api/v2/walletshares/accept')
.reply(function (_, _requestBody, cb) {
// Always respond with 413 error
return cb(null, [413, { error: 'Request Entity Too Large' }]);
});
await wallets
.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
})
.should.be.rejectedWith('Request Entity Too Large');
});
describe('EncryptionSession (HKDF)', function () {
async function stubForShares(shareCount, decryptedWalletPrv, walletPassphrase) {
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const senderEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedWalletPrv });
const shareIds = Array.from({ length: shareCount }, (_, i) => `hkdf-share-${i}`);
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `w${index}`,
fromUser: 'from',
toUser: 'to',
wallet: `w${index}`,
enterprise: `ent-${index}`,
permissions: ['spend'],
state: 'active',
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: senderEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({ incoming: shares, outgoing: [] });
const ecdh = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: ecdh.xprv, password: walletPassphrase }),
});
const decryptStub = sinon.stub(bitgo, 'decrypt');
decryptStub.onFirstCall().resolves(ecdh.xprv);
decryptStub.resolves(decryptedWalletPrv);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves(secret);
return { shareIds };
}
it('opens one session per passphrase and destroys them after the loop', async function () {
const walletPassphrase = 'strong-outer-passphrase';
const decryptedWalletPrv = 'plaintext-wallet-prv';
const { shareIds } = await stubForShares(3, decryptedWalletPrv, walletPassphrase);
const realSession = await bitgo.createEncryptionSession(walletPassphrase);
const destroySpy = sinon.spy(realSession, 'destroy');
const sessionStub = sinon.stub(bitgo, 'createEncryptionSession').resolves(realSession);
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, {
acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })),
});
await wallets.bulkAcceptShare({ walletShareIds: shareIds, userLoginPassword: walletPassphrase });
sessionStub.callCount.should.equal(1);
sessionStub.firstCall.args[0].should.equal(walletPassphrase);
destroySpy.called.should.equal(true);
});
it('produces standalone-decryptable v2 envelopes with unique per-envelope hkdfSalts', async function () {
const walletPassphrase = 'session-passphrase-42';
const decryptedWalletPrv = 'secret-wallet-material';
const { shareIds } = await stubForShares(4, decryptedWalletPrv, walletPassphrase);
let captured;
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
captured = body;
return true;
})
.reply(200, {
acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })),
});
await wallets.bulkAcceptShare({ walletShareIds: shareIds, userLoginPassword: walletPassphrase });
const entries = captured.keysForWalletShares;
entries.should.have.length(4);
const envelopes = entries.map((e) => JSON.parse(e.encryptedPrv));
for (const env of envelopes) {
env.should.have.property('v', 2);
env.should.have.property('hkdfSalt');
env.should.have.property('salt');
}
// Same session ⇒ same Argon2 salt across envelopes
const argonSalts = new Set(envelopes.map((e) => e.salt));
argonSalts.size.should.equal(1);
// Unique HKDF salt per envelope ⇒ independent AES keys
const hkdfSalts = new Set(envelopes.map((e) => e.hkdfSalt));
hkdfSalts.size.should.equal(4);
// Cross-wallet isolation: every envelope decrypts back under the same passphrase
for (const env of envelopes) {
const roundTrip = await bitgo.decrypt({ password: walletPassphrase, input: JSON.stringify(env) });
roundTrip.should.equal(decryptedWalletPrv);
}
});
it('opens a second, independent session for webauthnInfo.passphrase and binds adata per share', async function () {
const walletPassphrase = 'outer-pw';
const webauthnPassphrase = 'webauthn-prf-pw';
const decryptedWalletPrv = 'wallet-prv-webauthn-case';
const { shareIds } = await stubForShares(2, decryptedWalletPrv, walletPassphrase);
const sessionSpy = sinon.spy(bitgo, 'createEncryptionSession');
let captured;
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
captured = body;
return true;
})
.reply(200, { acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })) });
await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
webauthnInfo: { otpDeviceId: 'dev', prfSalt: 'salt', passphrase: webauthnPassphrase },
});
sessionSpy.callCount.should.equal(2);
const passwords = sessionSpy.getCalls().map((c) => c.args[0]);
passwords.should.containEql(walletPassphrase);
passwords.should.containEql(webauthnPassphrase);
const entries = captured.keysForWalletShares;
for (let i = 0; i < entries.length; i++) {
const webEnv = JSON.parse(entries[i].webauthnInfo.encryptedPrv);
webEnv.should.have.property('adata', `ent-${i}`);
const rt = await bitgo.decrypt({ password: webauthnPassphrase, input: JSON.stringify(webEnv) });
rt.should.equal(decryptedWalletPrv);
}
});
it('destroys the session even when the accept API call fails', async function () {
const walletPassphrase = 'pw-error';
const decryptedWalletPrv = 'x';
const { shareIds } = await stubForShares(2, decryptedWalletPrv, walletPassphrase);
const realSession = await bitgo.createEncryptionSession(walletPassphrase);
const destroySpy = sinon.spy(realSession, 'destroy');
sinon.stub(bitgo, 'createEncryptionSession').resolves(realSession);
nock(bgUrl).put('/api/v2/walletshares/accept').reply(500, { error: 'boom' });
await wallets
.bulkAcceptShare({ walletShareIds: shareIds, userLoginPassword: walletPassphrase })
.should.be.rejected();
destroySpy.called.should.equal(true);
});
it('threads encryptionVersion=1 into the factory so v1 envelopes are produced', async function () {
const walletPassphrase = 'v1-caller';
const decryptedWalletPrv = 'legacy';
const { shareIds } = await stubForShares(2, decryptedWalletPrv, walletPassphrase);
const sessionSpy = sinon.spy(bitgo, 'createEncryptionSession');
let captured;
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
captured = body;
return true;
})
.reply(200, { acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })) });
await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
encryptionVersion: 1,
});
// Factory is still called uniformly, but with encryptionVersion=1
sessionSpy.callCount.should.equal(1);
sessionSpy.firstCall.args[1].should.equal(1);
const entries = captured.keysForWalletShares;
const envelopes = entries.map((e) => JSON.parse(e.encryptedPrv));
for (const env of envelopes) {
env.should.not.have.property('hkdfSalt');
env.should.have.property('iter'); // v1 SJCL
}
});
});
});
describe('bulkUpdateWalletShare', function () {
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
sinon.restore();
});
it('should throw validation error for missing shares parameter', async () => {
await wallets.bulkUpdateWalletShare({}).should.be.rejectedWith('Missing parameter: shares');
});
it('should throw validation error for non-array shares parameter', async () => {
await wallets
.bulkUpdateWalletShare({ shares: 'not-an-array' })
.should.be.rejectedWith('Expecting parameter array: shares but found string');
});
it('should throw validation error for missing walletShareId in share', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ status: 'accept' }] })
.should.be.rejectedWith('Missing walletShareId in share');
});
it('should throw validation error for missing status in share', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: '123' }] })
.should.be.rejectedWith('Missing status in share');
});
it('should throw validation error for invalid status in share', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: '123', status: 'invalid' }] })
.should.be.rejectedWith('Invalid status in share: invalid. Must be either "accept" or "reject"');
});
it('should throw validation error for non-string walletShareId', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: 123, status: 'accept' }] })
.should.be.rejectedWith('Expecting walletShareId to be a string but found number');
});
it('should throw validation error for non-string userLoginPassword', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: '123', status: 'accept' }], userLoginPassword: 123 })
.should.be.rejectedWith('Expecting parameter string: userLoginPassword but found number');
});
it('should throw validation error for non-string newWalletPassphrase', async () => {
await wallets
.bulkUpdateWalletShare({
shares: [{ walletShareId: '123', status: 'accept' }],
userLoginPassword: 'password',
newWalletPassphrase: 123,
})
.should.be.rejectedWith('Expecting parameter string: newWalletPassphrase but found number');
});
it('should throw assertion error for empty shares array', async () => {
await wallets.bulkUpdateWalletShare({ shares: [] }).should.be.rejectedWith('no shares are passed');
});
it('should throw error for no valid wallet shares', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
await wallets
.bulkUpdateWalletShare({
shares: [{ walletShareId: '66a229dbdccdcfb95b44fc2745a60bd1', status: 'accept' }],
userLoginPassword: 'dummy@123',
})
.should.be.rejectedWith('invalid wallet share provided: 66a229dbdccdcfb95b44fc2745a60bd1');
});
it('should throw error for ecdh keychain undefined when accepting share requiring decryption', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
keychain: {
pub: 'pub',
toPubKey: 'toPubKey',
fromPubKey: 'fromPubKey',
encryptedPrv: 'encryptedPrv',
path: 'path',
},
},
],
outgoing: [],
});
sinon.stub(bitgo, 'getECDHKeychain').resolves({
prv: 'private key',
});
await wallets
.bulkUpdateWalletShare({
shares: [{ walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4', status: 'accept' }],
userLoginPassword: 'dummy@123',
})
.should.be.rejectedWith('encryptedXprv was not found on sharing keychain');
});
it('should successfully update shares with both accept and reject statuses', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return two shares
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
},
{
id: 'share2',
coin: 'tsol',
walletLabel: 'testing2',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet2',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: ['share2'],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [
{ walletShareId: 'share1', status: 'accept' },
{ walletShareId: 'share2', status: 'reject' },
],
userLoginPassword: walletPassphrase,
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: ['share2'],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called with correct parameters
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(2);
// Second param should be for share2 with reject status
updateParams.should.containDeep([
{
walletShareId: 'share2',
status: 'reject',
},
]);
});
it('should handle keychainOverrideRequired with newWalletPassphrase in bulk operations', async () => {
const userLoginPassword = 'bitgo1234';
const newWalletPassphrase = 'new_wallet_passphrase_456';
// Mock listSharesV2 to return a share with keychainOverrideRequired
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['admin', 'spend'],
state: 'active',
keychainOverrideRequired: true,
},
],
outgoing: [],
});
// Mock user settings API call (required by bulkUpdateWalletShare)
nock(bgUrl).get('/api/v1/user/settings').reply(200, {});
// Mock getECDHKeychain (required by bulkUpdateWalletShare when userLoginPassword is provided)
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: 'encryptedXprv',
});
// Setup for the baseCoin.keychains().createUserKeychain
const userKeychain = {
id: 'key1',
pub: 'pubKey',
encryptedPrv: 'encryptedPrivateKey',
};
const createUserKeychainStub = sinon
.stub(wallets.baseCoin.keychains(), 'createUserKeychain')
.resolves(userKeychain);
// Mock decrypt and signMessage
sinon.stub(bitgo, 'decrypt').resolves('decryptedPrivateKey');
sinon.stub(wallets.baseCoin, 'signMessage').resolves(Buffer.from('signature'));
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Mock reshareWalletWithSpenders (called for keychainOverrideRequired cases)
const reshareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: userLoginPassword,
newWalletPassphrase: newWalletPassphrase,
});
// Verify createUserKeychain was called with newWalletPassphrase (not userLoginPassword)
createUserKeychainStub.calledOnce.should.be.true();
createUserKeychainStub.calledWith(newWalletPassphrase).should.be.true();
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
bulkUpdateStub.calledOnce.should.be.true();
// Verify reshare was called for keychainOverrideRequired case
reshareStub.calledOnce.should.be.true();
});
it('should handle special override cases and reshare with spenders', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return a share with keychainOverrideRequired
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'ofc',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['admin', 'spend'],
state: 'active',
keychainOverrideRequired: true,
},
],
outgoing: [],
});
// Setup for the baseCoin.keychains().createUserKeychain
const userKeychain = {
id: 'key1',
pub: 'pubKey',
encryptedPrv: 'encryptedPrivateKey',
};
sinon.stub(ofcWallets.baseCoin.keychains(), 'createUserKeychain').resolves(userKeychain);
// Mock decrypt and signMessage
sinon.stub(bitgo, 'decrypt').resolves('decryptedPrivateKey');
sinon.stub(ofcWallets.baseCoin, 'signMessage').resolves(Buffer.from('signature'));
// Mock getECDHKeychain
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: 'encryptedXprv',
});
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Mock reshareWalletWithSpenders
const reshareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called
bulkUpdateStub.calledOnce.should.be.true();
// Verify reshareWalletWithSpenders was called with correct parameters
reshareStub.calledOnce.should.be.true();
reshareStub.firstCall.args[0].should.equal('wallet1');
reshareStub.firstCall.args[1].should.equal(walletPassphrase);
});
it('should handle shares with no keychain to decrypt', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return a share with no keychain
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['view'],
state: 'active',
},
],
outgoing: [],
});
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called with correct parameters
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(1);
// Param should be for share1 with accept status and no additional fields
updateParams.should.containDeep([
{
walletShareId: 'share1',
status: 'accept',
},
]);
});
it('should handle shares with keychain requiring decryption', async () => {
const walletPassphrase = 'bitgo1234';
const path = 'm/999999/1/1';
// Create test keychains
const fromKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef01deadbeef01deadbeef01deadbeef01', 'hex'));
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const fromPubKey = fromKeychain.publicKey.toString('hex');
const toPubKey = toKeychain.derivePath(path).publicKey.toString('hex');
// Create encrypted private key
const originalPrivKey = 'originalPrivateKey';
const sharedSecret = (0, sdk_core_1.getSharedSecret)(fromKeychain, Buffer.from(toPubKey, 'hex')).toString('hex');
const encryptedPrv = await bitgo.encrypt({
password: sharedSecret,
input: originalPrivKey,
});
// Mock listSharesV2 to return a share with keychain
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
keychain: {
pub: toPubKey,
toPubKey: toPubKey,
fromPubKey: fromPubKey,
encryptedPrv: encryptedPrv,
path: path,
},
},
],
outgoing: [],
});
// Mock getECDHKeychain
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
// Setup decrypt stubs
const decryptStub = sinon.stub(bitgo, 'decrypt');
decryptStub.onFirstCall().resolves(myEcdhKeychain.xprv); // For sharing keychain
decryptStub.onSecondCall().resolves(originalPrivKey); // For wallet keychain
// Mock getSharedSecret
sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(sharedSecret));
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
newWalletPassphrase: 'newPassphrase',
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called with correct parameters
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(1);
updateParams[0].should.have.property('walletShareId', 'share1');
updateParams[0].should.have.property('status', 'accept');
// encryptedPrv is now emitted by the session; verify it's a real v2 envelope that
// decrypts back to the original prv under newPassphrase.
const envelope = JSON.parse(updateParams[0].encryptedPrv);
envelope.should.have.property('v', 2);
envelope.should.have.property('hkdfSalt');
// Session encrypt bypasses bitgo.decrypt's stub -- restore then decrypt the envelope
decryptStub.restore();
const rt = await bitgo.decrypt({ password: 'newPassphrase', input: updateParams[0].encryptedPrv });
rt.should.equal(originalPrivKey);
});
it('should handle rejected promises and add them to walletShareUpdateErrors', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return two shares
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
},
{
id: 'share2',
coin: 'tsol',
walletLabel: 'testing2',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet2',
permissions: ['spend'],
state: 'active',
},
{
id: 'share3',
coin: 'tsol',
walletLabel: 'testing3',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet3',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
// Stub processAcceptShare to throw an error for share2
// Using 'as any' to bypass TypeScript's private method restriction
const processAcceptShareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'processAcceptShare');
processAcceptShareStub
.withArgs('share1', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
.resolves([{ walletShareId: 'share1', status: 'accept' }]);
processAcceptShareStub
.withArgs('share2', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
.rejects(new Error('Failed to process share2'));
processAcceptShareStub
.withArgs('share3', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
.resolves([{ walletShareId: 'share3', status: 'accept' }]);
// Mock bulkUpdateWalletShareRequest to return a response
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1', 'share3'],
rejectedWalletShares: [],
walletShareUpdateErrors: [], // Empty array that should be populated
});
const result = await wallets.bulkUpdateWalletShare({
shares: [
{ walletShareId: 'share1', status: 'accept' },
{ walletShareId: 'share2', status: 'accept' },
{ walletShareId: 'share3', status: 'accept' },
],
userLoginPassword: walletPassphrase,
});
// Verify bulkUpdateWalletShareRequest was called with only the successful share
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(2);
updateParams[0].walletShareId.should.equal('share1');
updateParams[0].status.should.equal('accept');
updateParams[1].walletShareId.should.equal('share3');
updateParams[1].status.should.equal('accept');
// Verify the result contains the error information
result.should.have.property('walletShareUpdateErrors');
result.walletShareUpdateErrors.should.be.an.Array();
result.walletShareUpdateErrors.should.have.lengthOf(1);
result.walletShareUpdateErrors[0].should.have.property('walletShareId', 'share2');
result.walletShareUpdateErrors[0].should.have.property('reason', 'Failed to process share2');
});
it('should accept share with v2-encrypted ECDH keychain and wallet prv', async () => {
const walletPassphrase = 'bitgo1234';
const path = 'm/999999/1/1';
const fromKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef01deadbeef01deadbeef01deadbeef01', 'hex'));
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const toPubKey = toKeychain.derivePath(path).publicKey.toString('hex');
const fromPubKey = fromKeychain.publicKey.toString('hex');
const originalPrivKey = 'originalPrivateKey';
const sharedSecret = (0, sdk_core_1.getSharedSecret)(fromKeychain, Buffer.from(toPubKey, 'hex')).toString('hex');
const encryptedPrv = await bitgo.encrypt({ password: sharedSecret, input: originalPrivKey });
// Both the ECDH keychain and share prv are v2-encrypted in this scenario
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
keychain: { pub: toPubKey, toPubKey, fromPubKey, encryptedPrv, path },
},
],
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
// decrypt handles v2 transparently; stub to return expected values
const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
decryptAsyncStub.onFirstCall().resolves(myEcdhKeychain.xprv); // ECDH keychain
decryptAsyncStub.onSecondCall().resolves(originalPrivKey); // wallet share prv
sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(sharedSecret));
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
newWalletPassphrase: 'newPassphrase',
});
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Both decrypt calls must have gone through decrypt
assert.equal(decryptAsyncStub.callCount, 2);
bulkUpdateStub.calledOnce.should.be.true();
// Encryption now goes through the session; assert a real v2 envelope round-trips
const updateParams = bulkUpdateStub.firstCall.args[0];
const envelope = JSON.parse(updateParams[0].encryptedPrv);
envelope.should.have.property('v', 2);
envelope.should.have.property('hkdfSalt');
decryptAsyncStub.restore();
const rt = await bitgo.decrypt({ password: 'newPassphrase', input: updateParams[0].encryptedPrv });
rt.should.equal(originalPrivKey);
});
describe('EncryptionSession (HKDF)', function () {
// Build a set of accept-status shares with realistic ECDH-encrypted keychains so
// bulkUpdateWalletShare walks the standard re-encrypt path for every share.
async function stubForAcceptShares(shareCount, decryptedWalletPrv, walletPassphrase) {
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef03deadbeef03deadbeef03deadbeef03', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const senderEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedWalletPrv });
const shareIds = Array.from({ length: shareCount }, (_, i) => `bulk-update-share-${i}`);
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `w${index}`,
fromUser: 'from',
toUser: 'to',
wallet: `w${index}`,
permissions: ['spend'],
state: 'active',
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: senderEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({ incoming: shares, outgoing: [] });
const ecdh = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: ecdh.xprv, password: walletPassphrase }),
});
const decryptStub = sinon.stub(bitgo, 'decrypt');
decryptStub.onFirstCall().resolves(ecdh.xprv);
decryptStub.resolves(decryptedWalletPrv);
sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(secret));
return { shareIds };
}
it('opens one session over the outer passphrase and destroys it after the loop', async function () {
const walletPassphrase = 'update-passphrase';
const { shareIds } = await stubForAcceptShares(3, 'plaintext-prv', walletPassphrase);
const realSession = await bitgo.createEncryptionSession(walletPassphrase);
const destroySpy = sinon.spy(realSession, 'destroy');
const sessionStub = sinon.stub(bitgo, 'createEncryptionSession').resolves(realSession);
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: shareIds,
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
await wallets.bulkUpdateWalletShare({
shares: shareIds.map((id) => ({ walletShareId: id, status: 'accept' })),
userLoginPassword: walletPassphrase,
});
sessionStub.callCount.should.equal(1);
sessionStub.firstCall.args[0].should.equal(walletPassphrase);
destroySpy.called.should.equal(true);
});
it('threads the session into processAcceptShare so envelopes carry the same argon2 salt', async function () {
const walletPassphrase = 'shared-argon2-salt-test';
const { shareIds } = await stubForAcceptShares(4, 'plaintext-prv', walletPassphrase);
let capturedShares = [];
sinon
.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest')
.callsFake(async (shares) => {
capturedShares = shares;
return { acceptedWalletShares: shareIds, rejectedWalletShares: [], walletShareUpdateErrors: [] };
});
await wallets.bulkUpdateWalletShare({
shares: shareIds.map((id) => ({ walletShareId: id, status: 'accept' })),
userLoginPassword: walletPassphrase,
});
capturedShares.should.have.length(4);
const envelopes = capturedShares.map((s) => JSON.parse(s.encryptedPrv));
for (const env of envelopes) {
env.should.have.property('v', 2);
env.should.have.property('hkdfSalt');
}
const argonSalts = new Set(envelopes.map((e) => e.salt));
argonSalts.size.should.equal(1); // one session -> one argon2 salt
const hkdfSalts = new Set(envelopes.map((e) => e.hkdfSalt));
hkdfSalts.size.should.equal(4); // per-envelope key isolation
// Cross-envelope round-trip: each envelope decrypts under the same passphrase
for (const env of envelopes) {
const rt = await bitgo.decrypt({ password: walletPassphrase, input: JSON.stringify(env) });
rt.should.equal('plaintext-prv');
}
});
it('bounds concurrent processAcceptShare calls at BULK_SHARE_BATCH_SIZE (16)', async function () {
const walletPassphrase = 'batch-cap-pw';
const { shareIds } = await stubForAcceptShares(20, 'plaintext-prv', walletPassphrase);
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: shareIds,
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Track concurrent in-flight processAcceptShare invocations. The batching in
// bulkUpdateWalletShare should cap this at BULK_SHARE_BATCH_SIZE (16).
let inFlight = 0;
let maxInFlight = 0;
sinon.stub(sdk_core_1.Wallets.prototype, 'processAcceptShare').callsFake(async (...args) => {
const walletShareId = args[0];
inFlight++;
maxInFlight = Math.max(maxInFlight, inFlight);
await new Promise((r) => setTimeout(r, 5));
inFlight--;
return [{ walletShareId, status: 'accept' }];
});
await wallets.bulkUpdateWalletShare({
shares: shareIds.map((id) => ({ walletShareId: id, status: 'accept' })),
userLoginPassword: walletPassphrase,
});
maxInFlight.should.be.lessThanOrEqual(16);
});
it('does not open a session when the bulk contains only rejects', async function () {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'reject-1',
coin: 'tsol',
walletLabel: 'x',
fromUser: 'a',
toUser: 'b',
wallet: 'w',
permissions: ['view'],
state: 'active',
},
],
outgoing: [],
});
const sessionStub = sinon.stub(bitgo, 'createEncryptionSession');
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: [],
rejectedWalletShares: ['reject-1'],
walletShareUpdateErrors: [],
});
await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'reject-1', status: 'reject' }],
userLoginPassword: 'irrelevant',
});
sessionStub.callCount.should.equal(0);
});
it('threads the session through createUserKeychain in the special override path', async function () {
const walletPassphrase = 'override-pw';
const shareId = 'override-share-1';
const walletId = 'override-wallet';
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'x',
fromUser: 'a',
toUser: 'b',
wallet: walletId,
permissions: ['admin', 'spend', 'view'],
state: 'active',
keychainOverrideRequired: true,
},
],
outgoing: [],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
// Short-circuit createUserKeychain so the test doesn't hit the /key API dance; the
// point of this test is verifying the session argument threading, nothing more.
const createUserKeychainStub = sinon.stub(ofcWallets.baseCoin.keychains(), 'createUserKeychain').resolves({
id: 'new-keychain-id',
pub: testKeychain.pub,
encryptedPrv: 'stubbed-encrypted-prv',
type: 'independent',
});
// specialOverrideCase pulls the sharing keychain up front, so stub it.
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: 'stubbed-encrypted-xprv' });
sinon.stub(ofcWallets.baseCoin, 'signMessage').resolves(Buffer.from('signature-bytes'));
sinon.stub(bitgo, 'decrypt').resolves(testKeychain.prv);
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: [shareId],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
userLoginPassword: walletPassphrase,
});
createUserKeychainStub.calledOnce.should.equal(true);
// 3rd positional arg is the session
const sessionArg = createUserKeychainStub.firstCall.args[2];
should.exist(sessionArg);
(typeof sessionArg.encrypt).should.equal('function');
(typeof sessionArg.destroy).should.equal('function');
});
});
});
describe('reshareWalletWithSpenders', function () {
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
sinon.restore();
});
// Build a mock wallet with N spender users on the same enterprise.
function stubForReshare(spenderCount, walletId, enterprise) {
const users = Array.from({ length: spenderCount }, (_, i) => ({
user: `spender-${i}`,
permissions: ['view', 'spend'],
}));
const walletObj = {
id: walletId,
coin: 'tsol',
enterprise,
users,
keys: ['userKeyId', 'backupKeyId', 'bitgoKeyId'],
};
// wallets.get(walletId) -> Wallet wrapping walletObj
sinon.stub(sdk_core_1.Wallets.prototype, 'get').resolves(new sdk_core_1.Wallet(bitgo, bitgo.coin('tsol'), walletObj));
nock(bgUrl)
.get(`/api/v1/enterprise/${enterprise}/user`)
.reply(200, {
adminUsers: [],
nonAdminUsers: users.map((u, i) => ({ id: u.user, email: { email: `spender-${i}@example.com` } })),
});
return { walletObj, users };
}
it('decrypts the wallet keychain once and threads it into every shareWallet call', async function () {
const walletId = 'reshare-wallet-1';
const enterprise = 'ent-1';
const userPassword = 'shared-passphrase';
const decryptedKeychain = { prv: 'plaintext-prv', pub: 'wallet-pub' };
const { users } = stubForReshare(3, walletId, enterprise);
// getDecryptedKeychainForSharing is what runs Argon2id on the wallet's encryptedPrv.
// Assert it fires exactly once regardless of spender count.
const decryptStub = sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing').resolves(decryptedKeychain);
const shareWalletStub = sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet').resolves({ shared: true });
await wallets.reshareWalletWithSpenders(walletId, userPassword);
decryptStub.callCount.should.equal(1);
decryptStub.firstCall.args[0].should.equal(userPassword);
// shareWallet called once per spender, each with decryptedKeychain threaded in
shareWalletStub.callCount.should.equal(users.length);
for (let i = 0; i < users.length; i++) {
const call = shareWalletStub.getCall(i);
const shareArg = call.args[0];
shareArg.should.have.property('decryptedKeychain').eql(decryptedKeychain);
shareArg.should.have.property('walletPassphrase', userPassword);
}
});
it('runs shareWallet calls sequentially so per-recipient Argon2id is bounded', async function () {
const walletId = 'reshare-wallet-seq';
const enterprise = 'ent-2';
stubForReshare(5, walletId, enterprise);
sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing').resolves({ prv: 'p', pub: 'q' });
// Track concurrent in-flight shareWallet calls. Sequential -> max concurrent is 1.
let inFlight = 0;
let maxInFlight = 0;
sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet').callsFake(async () => {
inFlight++;
maxInFlight = Math.max(maxInFlight, inFlight);
await new Promise((r) => setTimeout(r, 5));
inFlight--;
return { shared: true };
});
await wallets.reshareWalletWithSpenders(walletId, 'pw');
maxInFlight.should.equal(1);
});
it('returns early when the wallet has no spender users', async function () {
const walletId = 'reshare-empty';
const enterprise = 'ent-empty';
sinon.stub(sdk_core_1.Wallets.prototype, 'get').resolves(new sdk_core_1.Wallet(bitgo, bitgo.coin('tsol'), {
id: walletId,
coin: 'tsol',
enterprise,
users: [{ user: 'admin-only', permissions: ['admin', 'view', 'spend'] }],
keys: ['userKeyId', 'backupKeyId', 'bitgoKeyId'],
}));
nock(bgUrl)
.get(`/api/v1/enterprise/${enterprise}/user`)
.reply(200, {
adminUsers: [{ id: 'admin-only', email: { email: 'admin@example.com' } }],
nonAdminUsers: [],
});
const decryptStub = sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing');
const shareWalletStub = sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet');
await wallets.reshareWalletWithSpenders(walletId, 'pw');
// No decrypt burned, no shares attempted
decryptStub.called.should.equal(false);
shareWalletStub.called.should.equal(false);
});
it('proceeds with per-recipient shareWallet even when the wallet is cold (no decryptedKeychain)', async function () {
const walletId = 'reshare-cold';
const enterprise = 'ent-cold';
stubForReshare(2, walletId, enterprise);
// Simulate cold wallet: getDecryptedKeychainForSharing throws MissingEncryptedKeychainError
// (which we catch inside reshareWalletWithSpenders and fall through).
sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing').rejects(new sdk_core_1.MissingEncryptedKeychainError());
const shareWalletStub = sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet').resolves({ shared: true });
await wallets.reshareWalletWithSpenders(walletId, 'pw');
// Still fires per recipient; each call gets undefined decryptedKeychain and shareWallet
// can fall back to its own decrypt path (or a no-op for cold wallets internally).
shareWalletStub.callCount.should.equal(2);
for (let i = 0; i < 2; i++) {
const shareArg = shareWalletStub.getCall(i).args[0];
assert.strictEqual(shareArg.decryptedKeychain, undefined);
}
});
});
});
describe('createBulkKeyShares tests', () => {
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tsol = bitgo.coin('tsol');
const wallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
bitgo.initializeTestVars();
});
beforeEach(() => {
sinon.createSandbox();
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
(0, mocha_1.afterEach)(function () {
sinon.restore();
});
it('should throw an error if shareOptions is empty', async () => {
try {
await wallet.createBulkKeyShares([]);
assert.fail('Expected error not thrown');
}
catch (error) {
assert.strictEqual(error.message, 'shareOptions cannot be empty');
}
});
it('should skip shareoption if keychain parameters are missing', async () => {
const params = [
{
user: 'testuser@example.com',
permissions: ['spend'],
keychain: { pub: 'pubkey', encryptedPrv: '', fromPubKey: '', toPubKey: '', path: '' },
},
];
try {
await wallet.createBulkKeyShares(params);
assert.fail('Expected error not thrown');
}
catch (error) {
// Shareoptions with invalid keychains are skipped
assert.strictEqual(error.message, 'shareOptions cannot be empty');
}
});
it('should send the correct data to BitGo API if shareOptions are valid', async () => {
const params = {
shareOptions: [
{
user: 'testuser@example.com',
permissions: ['spend'],
keychain: {
pub: 'pubkey',
encryptedPrv: 'encryptedPrv',
fromPubKey: 'fromPubKey',
toPubKey: 'toPubKey',
path: 'm/0/0',
},
},
],
};
const paramsToSend = [
{
user: 'testuser@example.com',
permissions: ['spend'],
keychain: {
pub: 'pubkey',
encryptedPrv: 'encryptedPrv',
fromPubKey: 'fromPubKey',
toPubKey: 'toPubKey',
path: 'm/0/0',
},
},
];
nock(bgUrl)
.post(`/api/v2/wallet/${walletData.id}/walletshares`, params)
.reply(200, {
shares: [
{
id: 'userId',
coin: walletData.coin,
wallet: walletData.id,
fromUser: 'fromUserId',
toUser: 'toUserId',
permissions: ['view', 'spend'],
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: 'dummyToPubKey',
path: 'dummyPath',
},
},
],
});
const result = await wallet.createBulkKeyShares(paramsToSend);
assert.strictEqual(result.shares[0].id, 'userId', 'The share ID should match');
assert.strictEqual(result.shares[0].coin, walletData.coin, 'The coin should match');
assert.strictEqual(result.shares[0].wallet, walletData.id, 'The wallet ID should match');
assert.ok(result.shares[0].keychain);
assert.strictEqual(result.shares[0].keychain.pub, 'dummyPub', 'The keychain pub should match');
assert.strictEqual(result.shares[0].permissions.includes('view'), true, 'The permissions should include "view"');
assert.strictEqual(result.shares[0].permissions.includes('spend'), true, 'The permissions should include "spend"');
});
});
describe('createBulkWalletShare tests', () => {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tsol = bitgo.coin('tsol');
const wallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
bitgo.initializeTestVars();
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
(0, mocha_1.afterEach)(function () {
sinon.restore();
});
it('should throw an error if no share options are provided', async () => {
try {
await wallet.createBulkWalletShare({ walletPassphrase: 'Test', keyShareOptions: [] });
assert.fail('Expected error not thrown');
}
catch (error) {
assert.strictEqual(error.message, 'No share options provided');
}
});
it('should throw NeedsUserSignup error if pubkey is missing', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
try {
await wallet.createBulkWalletShare({
walletPassphrase: 'Test',
keyShareOptions: [
{
userId: userId,
permissions: permissions,
path: 'm/999999/1/1',
},
],
});
assert.fail('Expected error not thrown');
}
catch (error) {
assert.ok(error instanceof sdk_core_1.NeedUserSignupError);
assert.strictEqual(error.name, 'NeedUserSignupError');
assert.strictEqual(error.message, userId);
}
});
it('should throw error if path is missing', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
try {
await wallet.createBulkWalletShare({
walletPassphrase: 'Test',
keyShareOptions: [
{
userId: userId,
permissions: permissions,
pubKey: 'm/999999/1/1',
},
],
});
assert.fail('Expected error not thrown');
}
catch (error) {
assert.strictEqual(error.name, 'Error');
assert.strictEqual(error.message, 'Missing parameter: path');
}
});
it('should throw NeedsUserSignup error if pubkey is empty string', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
try {
await wallet.createBulkWalletShare({
walletPassphrase: 'Test',
keyShareOptions: [
{
userId: userId,
pubKey: '',
permissions: permissions,
path: 'm/999999/1/1',
},
],
});
assert.fail('Expected error not thrown');
}
catch (error) {
assert.ok(error instanceof sdk_core_1.NeedUserSignupError);
assert.strictEqual(error.name, 'NeedUserSignupError');
assert.strictEqual(error.message, userId);
}
});
it('should correctly process share options and call createBulkKeyShares', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
const path = 'm/999999/1/1';
const walletPassphrase = 'bitgo1234';
const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
nock(bgUrl)
.get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
.reply(200, {
id: wallet.keyIds()[0],
pub,
source: 'user',
encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
coinSpecific: {},
});
const params = {
walletPassphrase,
keyShareOptions: [
{
userId: userId,
permissions: permissions,
pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
path: path,
},
],
};
const prv1 = Math.random().toString();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: prv1, password: walletPassphrase }),
};
sinon.stub(wallet, 'getEncryptedUserKeychain').resolves({
encryptedPrv: keychainTest.encryptedPrv,
pub,
});
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
sinon.stub(wallet, 'createBulkKeyShares').resolves({
shares: [
{
id: userId,
coin: walletData.coin,
wallet: walletData.id,
fromUser: userId,
toUser: userId,
permissions: ['view', 'spend'],
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: 'dummyToPubKey',
path: 'dummyPath',
},
},
],
});
const result = await wallet.createBulkWalletShare(params);
assert.deepStrictEqual(result, {
shares: [
{
id: userId,
coin: walletData.coin,
wallet: walletData.id,
fromUser: userId,
toUser: userId,
permissions: ['view', 'spend'],
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: 'dummyToPubKey',
path: 'dummyPath',
},
},
],
});
});
it('should throw error in processing share options when wallet password is incorrect', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
const path = 'm/999999/1/1';
const walletPassphrase = 'bitgo1234';
const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
nock(bgUrl)
.get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
.reply(200, {
id: wallet.keyIds()[0],
pub,
source: 'user',
encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
coinSpecific: {},
});
const params = {
walletPassphrase: 'wrong password',
keyShareOptions: [
{
userId: userId,
permissions: permissions,
pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
path: path,
},
],
};
const prv1 = Math.random().toString();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: prv1, password: walletPassphrase }),
};
sinon.stub(wallet, 'getEncryptedUserKeychain').resolves({
encryptedPrv: keychainTest.encryptedPrv,
pub,
});
try {
await wallet.createBulkWalletShare(params);
assert.fail('Expected error not thrown');
}
catch (error) {
assert.ok(error instanceof sdk_core_1.IncorrectPasswordError);
assert.equal(error.message, 'Password shared is incorrect for this wallet');
}
});
it('should fetch keychain only ONCE when sharing with multiple users', async () => {
const walletPassphrase = 'bitgo1234';
const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
const prv1 = 'xprv1';
// Create multiple users to share with
const users = [
{
userId: 'user1@example.com',
permissions: ['view', 'spend'],
pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
path: 'm/999999/1/1',
},
{
userId: 'user2@example.com',
permissions: ['view', 'spend'],
pubKey: '03705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f533',
path: 'm/999999/1/2',
},
{
userId: 'user3@example.com',
permissions: ['view', 'spend'],
pubKey: '02815a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f534',
path: 'm/999999/1/3',
},
];
const params = {
walletPassphrase,
keyShareOptions: users,
};
const getDecryptedKeychainStub = sinon.stub(wallet, 'getDecryptedKeychainForSharing').resolves({
prv: prv1,
pub,
});
const encryptPrvForUserStub = sinon
.stub(wallet, 'encryptPrvForUser')
.callsFake(async (prv, pubKey, userPubKey, path) => {
return {
pub: pubKey,
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: userPubKey,
path: path,
};
});
sinon.stub(wallet, 'createBulkKeyShares').resolves({
shares: users.map((user) => ({
id: user.userId,
coin: walletData.coin,
wallet: walletData.id,
fromUser: 'fromUser',
toUser: user.userId,
permissions: user.permissions,
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: user.pubKey,
path: user.path,
},
})),
});
await wallet.createBulkWalletShare(params);
// Verify keychain is fetched only ONCE, not once per user
assert.strictEqual(getDecryptedKeychainStub.callCount, 1, 'getDecryptedKeychainForSharing should be called exactly once, not once per user');
// Verify encryption happens for EACH user (once per user)
assert.strictEqual(encryptPrvForUserStub.callCount, users.length, `encryptPrvForUser should be called once per user (${users.length} times)`);
// Verify each call had the correct user's pubKey and path
users.forEach((user, index) => {
const call = encryptPrvForUserStub.getCall(index);
assert.strictEqual(call.args[0], prv1, 'Should use the same decrypted private key for all users');
assert.strictEqual(call.args[1], pub, 'Should use the same public key for all users');
assert.strictEqual(call.args[2], user.pubKey, `Should use user${index + 1}'s public key`);
assert.strictEqual(call.args[3], user.path, `Should use user${index + 1}'s path`);
});
});
});
describe('downloadKeycard', () => {
const localBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const walletData = {
id: '5b34252f1bf349930e34020a00000002',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tbtc = localBitgo.coin('tbtc');
const wallet = new sdk_core_1.Wallet(localBitgo, tbtc, walletData);
it('should throw when called in Node.js (no browser window)', async () => {
// In Node.js, accessing `window` throws ReferenceError; the method rejects.
await wallet.downloadKeycard().should.be.rejected();
});
it('downloadKeycard (sync) should throw when called in Node.js (no browser window)', () => {
should.throws(() => wallet.downloadKeycard());
});
});
describe('encryptPrvForUser', () => {
const localBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const walletData = {
id: '5b34252f1bf349930e34020a00000001',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tbtc = localBitgo.coin('tbtc');
const wallet = new sdk_core_1.Wallet(localBitgo, tbtc, walletData);
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
localBitgo.initializeTestVars();
});
(0, mocha_1.afterEach)(function () {
sinon.restore();
});
it('should encrypt prv for user and return the correct output shape', async () => {
const decryptedPrv = 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k';
const pub = 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp';
// A valid 33-byte compressed EC point on secp256k1
const userPubkey = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
const path = 'm/999999/0/1';
sinon.stub(localBitgo, 'encrypt').resolves('encryptedPrvForUser');
const result = await wallet.encryptPrvForUser(decryptedPrv, pub, userPubkey, path);
result.should.have.property('pub', pub);
result.should.have.property('encryptedPrv', 'encryptedPrvForUser');
result.should.have.property('fromPubKey').which.is.a.String();
result.should.have.property('toPubKey', userPubkey);
result.should.have.property('path', path);
});
});
describe('List Wallets:', function () {
it('should list wallets with skipReceiveAddress = true', async function () {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const basecoin = bitgo.coin('tbtc');
const wallets = basecoin.wallets();
const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
nock(bgUrl)
.get('/api/v2/tbtc/wallet')
.query({ skipReceiveAddress: true })
.reply(200, {
wallets: [
{ id: 'wallet1', label: 'Test Wallet 1' },
{ id: 'wallet2', label: 'Test Wallet 2' },
],
});
const result = await wallets.list({ skipReceiveAddress: true });
result.wallets.should.have.length(2);
should.not.exist(result.wallets[0].receiveAddress());
should.not.exist(result.wallets[1].receiveAddress());
});
it('should list wallets without skipReceiveAddress', async function () {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const basecoin = bitgo.coin('tbtc');
const wallets = basecoin.wallets();
const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
nock(bgUrl)
.get('/api/v2/tbtc/wallet')
.query({})
.reply(200, {
wallets: [
{ id: 'wallet1', label: 'Test Wallet 1', receiveAddress: { address: 'address1' } },
{ id: 'wallet2', label: 'Test Wallet 2', receiveAddress: { address: 'address2' } },
],
});
const result = await wallets.list();
result.wallets.should.have.length(2);
should.exist(result.wallets[0].receiveAddress());
should.exist(result.wallets[1].receiveAddress());
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC93YWxsZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsRUFBRTtBQUNGLG9CQUFvQjtBQUNwQixFQUFFO0FBQ0YsaUNBQWlDO0FBQ2pDLDZCQUE4QjtBQUM5QiwrQkFBK0I7QUFDL0IsaUNBQWtDO0FBQ2xDLDRCQUE0QjtBQUM1QiwyQ0FBMkM7QUFDM0MsOENBQTRDO0FBQzVDLDhDQXVCeUI7QUFDekIsc0NBQXFDO0FBQ3JDLGlDQUFrQztBQUVsQywrQ0FBK0M7QUFFL0MsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUN0QixNQUFNLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksVUFBVSxDQUFDO0lBQ2YsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqSCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDN0IsVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDekMsS0FBSyxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFD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LENBQUM7WUFFTCxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNwQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQ2pELE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vXG4vLyBUZXN0cyBmb3IgV2FsbGV0c1xuLy9cbmltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IG5vY2sgPSByZXF1aXJlKCdub2NrJyk7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgc2hvdWxkID0gcmVxdWlyZSgnc2hvdWxkJyk7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyB1dHhvTGliIGZyb20gJ0BiaXRnby91dHhvLWxpYic7XG5pbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHtcbiAgY29tbW9uLFxuICBUc3NVdGlscyxcbiAgV2FsbGV0cyxcbiAgRUNEU0FVdGlscyxcbiAgRUREU0FVdGlscyxcbiAgS2V5Y2hhaW5zVHJpcGxldCxcbiAgR2VuZXJhdGVXYWxsZXRPcHRpb25zLFxuICBXYWxsZXQsXG4gIGlzV2FsbGV0V2l0aEtleWNoYWlucyxcbiAgT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSxcbiAgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleSxcbiAgbWFrZVJhbmRvbUtleSxcbiAgZ2V0U2hhcmVkU2VjcmV0LFxuICBCdWxrVXBkYXRlV2FsbGV0U2hhcmVPcHRpb25zUmVxdWVzdCxcbiAgQnVsa1dhbGxldFNoYXJlT3B0aW9ucyxcbiAgQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdCxcbiAgS2V5Y2hhaW5XaXRoRW5jcnlwdGVkUHJ2LFxuICBXYWxsZXRXaXRoS2V5Y2hhaW5zLFxuICBtdWx0aXNpZ1R5cGVzLFxuICBJbmNvcnJlY3RQYXNzd29yZEVycm9yLFxuICBNaXNzaW5nRW5jcnlwdGVkS2V5Y2hhaW5FcnJvcixcbiAgTmVlZFVzZXJTaWdudXBFcnJvcixcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vc3JjJztcbmltcG9ydCB7IGFmdGVyRWFjaCB9IGZyb20gJ21vY2hhJztcbmltcG9ydCB7IFRzc1NldHRpbmdzIH0gZnJvbSAnQGJpdGdvL3B1YmxpYy10eXBlcyc7XG5pbXBvcnQgKiBhcyBtb2R1bGVCaXRnbyBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuXG5kZXNjcmliZSgnVjIgV2FsbGV0czonLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICBsZXQgd2FsbGV0cztcbiAgbGV0IG9mY1dhbGxldHM7XG4gIGxldCBiZ1VybDtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG5cbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgIHdhbGxldHMgPSBiYXNlY29pbi53YWxsZXRzKCk7XG4gICAgb2ZjV2FsbGV0cyA9IGJpdGdvLmNvaW4oJ29mYycpLndhbGxldHMoKTtcbiAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGQgV2FsbGV0OicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgndGhyb3dzIG9uIGludmFsaWQgYXJndW1lbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gaXNDdXN0b2RpYWwgZmxhZyBpcyBub3QgYSBib29sZWFuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgaXNDdXN0b2RpYWw6IDEgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGlzQ3VzdG9kaWFsIC0gYm9vbGVhbiBleHBlY3RlZCcpO1xuXG4gICAgICAvLyB0eXBlIGlzIG5vdCBhIHN0cmluZ1xuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIHR5cGU6IDEgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiB0eXBlIGJ1dCBmb3VuZCBudW1iZXInKTtcblxuICAgICAgLy8gQWRkcmVzcyBpcyBhbiBpbnZhbGlkIGFkZHJlc3NcbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCBhZGRyZXNzOiAnJCcgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGFkZHJlc3MgLSB2YWxpZCBhZGRyZXNzIHN0cmluZyBleHBlY3RlZCcpO1xuXG4gICAgICAvLyBnYXNQcmljZSBpcyBhIG51bWJlclxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIGdhc1ByaWNlOiAnMTcnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBnYXNQcmljZSAtIG51bWJlciBleHBlY3RlZCcpO1xuXG4gICAgICAvLyB3YWxsZXRWZXJzaW9uIGlzIGEgbnVtYmVyXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgd2FsbGV0VmVyc2lvbjogJzEnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFyZ3VtZW50IGZvciB3YWxsZXRWZXJzaW9uIC0gbnVtYmVyIGV4cGVjdGVkJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIHBhaXJlZCBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LmlzQ3VzdG9kaWFsLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkubS5zaG91bGQuZXF1YWwoMik7XG4gICAgICAgICAgYm9keS5uLnNob3VsZC5lcXVhbCgzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgd2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgaXNDdXN0b2RpYWw6IHRydWUgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhbiBlb3Mgd2FsbGV0IHdpdGggY3VzdG9tIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlb3NCaXRHbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGVvc0JpdEdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgY29uc3QgZW9zV2FsbGV0cyA9IGVvc0JpdEdvLmNvaW4oJ3Rlb3MnKS53YWxsZXRzKCk7XG4gICAgICBjb25zdCBhZGRyZXNzID0gJ3Rlc3Rlb3NhZGRyZSc7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90ZW9zL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5Lm0uc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICAgIGJvZHkubi5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAgICAgYm9keS5hZGRyZXNzLnNob3VsZC5lcXVhbChhZGRyZXNzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgZW9zV2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgYWRkcmVzcyB9IGFzIGFueSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIHNpbmdsZSBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdjdXN0b2RpYWwnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdtJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ24nKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgd2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCB0eXBlOiAnY3VzdG9kaWFsJyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgd2FsbGV0IHdpdGggY3VzdG9tIGdhc1ByaWNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXRoQml0R28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBldGhCaXRHby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldHMgPSBldGhCaXRHby5jb2luKCd0ZXRoJykud2FsbGV0cygpO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGV0aC93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdjdXN0b2RpYWwnKTtcbiAgICAgICAgICBib2R5Lmdhc1ByaWNlLnNob3VsZC5lcXVhbCgyMDAwMDAwMDAwMCk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbScpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCduJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldHMuYWRkKHtcbiAgICAgICAgbGFiZWw6ICdsYWJlbCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgIH0gYXMgYW55KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgbmV3IHdhbGxldCB3aXRoIHdhbGxldFZlcnNpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBldGhCaXRHbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGV0aEJpdEdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgY29uc3QgZXRoV2FsbGV0cyA9IGV0aEJpdEdvLmNvaW4oJ3RldGgnKS53YWxsZXRzKCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90ZXRoL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2N1c3RvZGlhbCcpO1xuICAgICAgICAgIGJvZHkud2FsbGV0VmVyc2lvbi5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbScpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCduJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGV0aFdhbGxldHMuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywgdHlwZTogJ2N1c3RvZGlhbCcsIHdhbGxldFZlcnNpb246IDEgfSBhcyBhbnkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYSBuZXcgaG90IHdhbGxldCB3aXRoIHVzZXJLZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2hvdCcpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdtJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbicpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCB3YWxsZXRzLmFkZCh7XG4gICAgICAgIGxhYmVsOiAnbGFiZWwnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdob3QnLFxuICAgICAgICBrZXlzOiBbXSxcbiAgICAgICAgbTogMixcbiAgICAgICAgbjogMyxcbiAgICAgICAgdXNlcktleTogJ3Rlc3QxMjMnLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHBhcmFtcyA9IHt9O1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBsYWJlbCcpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgYmFja3VwWHB1YjogJ2JhY2t1cCcsXG4gICAgICAgIGJhY2t1cFhwdWJQcm92aWRlcjogJ3Byb3ZpZGVyJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0Nhbm5vdCBwcm92aWRlIG1vcmUgdGhhbiBvbmUgYmFja3VwWHB1YiBvciBiYWNrdXBYcHViUHJvdmlkZXIgZmxhZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogMTIzLFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdwYXNzY29kZUVuY3J5cHRpb25Db2RlIG11c3QgYmUgYSBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGVudGVycHJpc2U6IDEyMzQsXG4gICAgICB9O1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZW50ZXJwcmlzZSBhcmd1bWVudCwgZXhwZWN0aW5nIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9uczogJ3N0cmluZycsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGRpc2FibGVUcmFuc2FjdGlvbk5vdGlmaWNhdGlvbnMgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBnYXNQcmljZTogJ3N0cmluZycsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGdhcyBwcmljZSBhcmd1bWVudCwgZXhwZWN0aW5nIG51bWJlciBvciBudW1iZXIgYXMgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBnYXNQcmljZTogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZ2FzIHByaWNlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGdhc1ByaWNlOiAxMjMsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDEyMzQsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEyMyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdjYW4gbm90IHVzZSBib3RoIGVpcDE1NTkgYW5kIGdhc1ByaWNlIHZhbHVlcycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heEZlZVBlckdhczogJ3ExMjM0JyxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzEyMycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIG1heCBmZWUgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMTIzNCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogJzEyM2EnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBwcmlvcml0eSBmZWUgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZGlzYWJsZUtSU0VtYWlsOiAnc3RyaW5nJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZGlzYWJsZUtSU0VtYWlsIGFyZ3VtZW50LCBleHBlY3RpbmcgYm9vbGVhbicpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAga3JzU3BlY2lmaWM6IHtcbiAgICAgICAgICBtYWxpY2lvdXM6IHtcbiAgICAgICAgICAgIGphdmFzY3JpcHQ6IHtcbiAgICAgICAgICAgICAgY29kZTogJ2JhZC5qcycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdrcnNTcGVjaWZpYyBvYmplY3QgY29udGFpbnMgaWxsZWdhbCB2YWx1ZXMuIHZhbHVlcyBtdXN0IGJlIHN0cmluZ3MsIGJvb2xlYW5zLCBvciBudW1iZXJzJ1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgZGlzYWJsZSBrcnMgZW1haWxzIHdoZW4gY3JlYXRpbmcgYmFja3VwIGtleWNoYWlucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteV93YWxsZXQnLFxuICAgICAgICBkaXNhYmxlS1JTRW1haWw6IHRydWUsXG4gICAgICAgIGJhY2t1cFhwdWJQcm92aWRlcjogJ3Rlc3QnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndGVzdDEyMycsXG4gICAgICAgIHVzZXJLZXk6ICd4cHViMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIGJpdGdvIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB1c2VyIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyBiYWNrdXAga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChcbiAgICAgICAgICAnL2FwaS92Mi90YnRjL2tleScsXG4gICAgICAgICAgXy5tYXRjaGVzKHtcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICBwcm92aWRlcjogcGFyYW1zLmJhY2t1cFhwdWJQcm92aWRlcixcbiAgICAgICAgICAgIGRpc2FibGVLUlNFbWFpbDogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB3YWxsZXRcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgcGFzcyB0aHJvdWdoIHRoZSBrcnNTcGVjaWZpYyBwYXJhbSB3aGVuIGNyZWF0aW5nIGJhY2t1cCBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnbXlfd2FsbGV0JyxcbiAgICAgICAgYmFja3VwWHB1YlByb3ZpZGVyOiAndGVzdCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTogJ3hwdWIxMjMnLFxuICAgICAgICBrcnNTcGVjaWZpYzogeyBjb3ZlcmFnZTogJ2luc3VyYW5jZScsIGV4cGVuc2l2ZTogdHJ1ZSwgaG93RXhwZW5zaXZlOiAyNSB9LFxuICAgICAgfTtcblxuICAgICAgLy8gYml0Z28ga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHVzZXIga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGJhY2t1cCBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KFxuICAgICAgICAgICcvYXBpL3YyL3RidGMva2V5JyxcbiAgICAgICAgICBfLm1hdGNoZXMoe1xuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHByb3ZpZGVyOiBwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyLFxuICAgICAgICAgICAga3JzU3BlY2lmaWM6IHsgY292ZXJhZ2U6ICdpbnN1cmFuY2UnLCBleHBlbnNpdmU6IHRydWUsIGhvd0V4cGVuc2l2ZTogMjUgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB3YWxsZXRcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZW5kIHRoZSBjb2xkIGRlcml2YXRpb24gc2VlZCBmb3IgYSB1c2VyIGtleScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteS1jb2xkLXdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0WGdTNXNZSkFCcXFHOVlMbUM0UTFSZGFwOWdTRThOcXR3eWJHaGVQWTJnWjI5RVNGanFKb0N1MVJ1cGplOFl0R3FzZWZEMjY1VE1nN3VzVURGZHA2VzFFR01jZXQ4JyxcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiAnMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIGJpdGdvIGtleVxuICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB1c2VyIGtleVxuICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChcbiAgICAgICAgICAnL2FwaS92Mi90YnRjL2tleScsXG4gICAgICAgICAgXy5tYXRjaGVzKHtcbiAgICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHBhcmFtcy5jb2xkRGVyaXZhdGlvblNlZWQsXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gYmFja3VwIGtleVxuICAgICAgY29uc3QgYmFja3VwS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYmFja3VwJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHdhbGxldFxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgICAgZm9yIChjb25zdCBzY29wZSBvZiBbYml0Z29LZXlOb2NrLCB1c2VyS2V5Tm9jaywgYmFja3VwS2V5Tm9jaywgd2FsbGV0Tm9ja10pIHtcbiAgICAgICAgc2NvcGUuZG9uZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBjdXN0b2RpYWwgb25jaGFpbiB3YWxsZXQgd2l0aG91dCBwYXNzaW5nIG0sIG4sIGtleXMsIGtleVNpZ25hdHVyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdteWVudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2N1c3RvZGlhbCcpO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QoYm9keS5tKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KGJvZHkubik7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChib2R5LmtleXMpO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QoYm9keS5rZXlTaWduYXR1cmVzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpZDogJzEyMycsIGJhc2VDb2luOiBiaXRnby5jb2luKCd0YnRjJyksIGtleXM6IFsnMTIzJywgJzQ1NicsICc3ODknXSB9KTtcblxuICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3RidGMva2V5LzEyMycpLnJlcGx5KDIwMCwgeyBwdWI6ICdiaXRnb1B1YicsIGlkOiAnNzg5JyB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90YnRjL2tleS80NTYnLCBfLm1hdGNoZXMoe30pKS5yZXBseSgyMDApO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3RidGMva2V5Lzc4OScpLnJlcGx5KDIwMCwgeyBwdWI6ICdiYWNrdXBQdWInLCBpZDogJzc4OScgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlID09PSB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGhvdCBvbmNoYWluIHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ211bHRpc2lnIHBhc3N3b3JkJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2hvdCcpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAnYml0Z29QdWInIH0pO1xuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7fSkpLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAnYmFja3VwUHViJyB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICBwYXJhbXMucGFzc3BocmFzZVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgaG90IG9uY2hhaW4gd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtdWx0aXNpZyB0eXBlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAnbXVsdGlzaWcgcGFzc3dvcmQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnaG90Jyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdiaXRnb1B1YicgfSk7XG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHt9KSkucmVwbHkoMjAwKTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYmFja3VwJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdiYWNrdXBQdWInIH0pO1xuXG4gICAgICBjb25zdCBnZW5lcmF0ZVdhbGxldFNweSA9IHNhbmRib3guc3B5KHdhbGxldHMsICdnZW5lcmF0ZVdhbGxldCcpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZW5lcmF0ZVdhbGxldFNweSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZ2VuZXJhdGVXYWxsZXRTcHkuZmlyc3RDYWxsPy5hcmdzWzBdPy5tdWx0aXNpZ1R5cGUsIG11bHRpc2lnVHlwZXMub25jaGFpbik7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBHbyBBY2NvdW50IHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ0dvIEFjY291bnQgV2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ2dvX2FjY291bnRfcGFzc3dvcmQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZS1pZCcsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB0eXBlOiAndHJhZGluZycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBrZXljaGFpbklkID0gJ3VzZXJfa2V5Y2hhaW5faWQnO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIGNyZWF0aW9uIGFuZCB1cGxvYWRcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL29mYy9rZXknLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScpO1xuICAgICAgICAgIGJvZHkua2V5VHlwZS5zaG91bGQuZXF1YWwoJ2luZGVwZW5kZW50Jyk7XG4gICAgICAgICAgYm9keS5zb3VyY2Uuc2hvdWxkLmVxdWFsKCd1c2VyJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6IGtleWNoYWluSWQsIHB1YjogJ3VzZXJQdWInLCBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcml2YXRlS2V5JyB9KTtcblxuICAgICAgLy8gTW9jayB3YWxsZXQgY3JlYXRpb25cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi9vZmMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgndHJhZGluZycpO1xuICAgICAgICAgIGJvZHkubS5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgYm9keS5uLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBib2R5LmtleXMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICAgIGJvZHkua2V5c1swXS5zaG91bGQuZXF1YWwoa2V5Y2hhaW5JZCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6ICd3YWxsZXQxMjMnLCBrZXlzOiBba2V5Y2hhaW5JZF0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgb2ZjV2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0Lm9rKCd1c2VyS2V5Y2hhaW4nIGluIHJlc3BvbnNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIFRTUyB3YWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKVxuICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgLnRpbWVzKDIpXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBjb2luU2V0dGluZ3M6IHtcbiAgICAgICAgICAgIGV0aDoge1xuICAgICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBic2M6IHtcbiAgICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcG9seWdvbjoge1xuICAgICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YmJlZEtleWNoYWluc1RyaXBsZXQ6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0c29sKTtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyBhcyBhbnksXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBuZXcgVFNTIHdhbGxldCB3aXRob3V0IHBhc3NpbmcgbXVsdGlzaWcgdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIHNhbmRib3guc3R1YihUc3NVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKS5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkubXVsdGlzaWdUeXBlLnNob3VsZC5lcXVhbChtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZ2VuZXJhdGVXYWxsZXRTcHkgPSBzYW5kYm94LnNweSh3YWxsZXRzLCAnZ2VuZXJhdGVXYWxsZXQnKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoZ2VuZXJhdGVXYWxsZXRTcHkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGdlbmVyYXRlV2FsbGV0U3B5LmZpcnN0Q2FsbD8uYXJnc1swXT8ubXVsdGlzaWdUeXBlLCBtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBuZXcgVFNTIHdhbGxldCB3aXRob3V0IHByb3ZpZGluZyBwYXNzY29kZUVuY3J5cHRpb25Db2RlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YmJlZEtleWNoYWluc1RyaXBsZXQ6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0c29sKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgIH0pO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UgPT09IHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gY3JlYXRlIFRTUyB3YWxsZXQgd2l0aCBpbnZhbGlkIGlucHV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRidGMgPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnbXktY29sZC13YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndGVzdDEyMycsXG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGdFhnUzVzWUpBQnFxRzlZTG1DNFExUmRhcDlnU0U4TnF0d3liR2hlUFkyZ1oyOUVTRmpxSm9DdTFSdXBqZThZdEdxc2VmRDI2NVRNZzd1c1VERmRwNlcxRUdNY2V0OCcsXG4gICAgICAgIGNvbGREZXJpdmF0aW9uU2VlZDogJzEyMycsXG4gICAgICB9O1xuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0YnRjKTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHBhcmFtcy5jb2xkRGVyaXZhdGlvblNlZWQgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiYWNrdXAnIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICAvLyBjcmVhdGUgYSBub24gdHNzIHdhbGxldCBmb3IgY29pbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCB0c3MgZXZlbiB0aG91Z2ggbXVsdGlzaWdUeXBlIGlzIHNldCB0byB0c3NcbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoeyAuLi5wYXJhbXMsIG11bHRpc2lnVHlwZTogJ3RzcycgfSk7XG5cbiAgICAgIGNvbnN0IHRzb2xXYWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBhd2FpdCB0c29sV2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICAgIGxhYmVsOiAndHNzIGNvbGQgd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3BocmFzZScsXG4gICAgICAgICAgdXNlcktleTogJ3VzZXIga2V5JyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZW50ZXJwcmlzZSBpcyByZXF1aXJlZCBmb3IgVFNTIHdhbGxldCcpO1xuXG4gICAgICBhd2FpdCB0c29sV2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICAgIGxhYmVsOiAndHNzIGNvbGQgd2FsbGV0JyxcbiAgICAgICAgICB1c2VyS2V5OiAndXNlciBrZXknLFxuICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2VJZCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdjYW5ub3QgZ2VuZXJhdGUgVFNTIGtleXMgd2l0aG91dCBwYXNzcGhyYXNlJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1MgY3VzdG9kaWFsIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtleXMgPSBbJzEnLCAnMicsICczJ107XG5cbiAgICAgIGNvbnN0IHdhbGxldFBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjdXN0b2RpYWwnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcpXG4gICAgICAgIC50aW1lcygxKVxuICAgICAgICAucmVwbHkoMjAwLCB7IC4uLndhbGxldFBhcmFtcywga2V5cyB9KTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0c29sKTtcblxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMpO1xuICAgICAgaWYgKCFpc1dhbGxldFdpdGhLZXljaGFpbnMocmVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dhbGxldCBtaXNzaW5nIHJlcXVpcmVkIGtleWNoYWlucycpO1xuICAgICAgfVxuICAgICAgcmVzLndhbGxldC5sYWJlbCgpLnNob3VsZC5lcXVhbCh3YWxsZXRQYXJhbXMubGFiZWwpO1xuICAgICAgc2hvdWxkLmVxdWFsKHJlcy53YWxsZXQudHlwZSgpLCB3YWxsZXRQYXJhbXMudHlwZSk7XG4gICAgICByZXMud2FsbGV0LnRvSlNPTigpLmVudGVycHJpc2Uuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5lbnRlcnByaXNlKTtcbiAgICAgIHJlcy53YWxsZXQubXVsdGlzaWdUeXBlKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5tdWx0aXNpZ1R5cGUpO1xuICAgICAgcmVzLnVzZXJLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1swXSk7XG4gICAgICByZXMuYmFja3VwS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKGtleXNbMV0pO1xuICAgICAgcmVzLmJpdGdvS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKGtleXNbMl0pO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBGTFJQIFRTUyBjdXN0b2RpYWwgd2FsbGV0IHdpdGhvdXQgcmVxdWlyaW5nIGEgcGFzc3BocmFzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtleXMgPSBbJzEnLCAnMicsICczJ107XG4gICAgICBjb25zdCB0ZmxycCA9IGJpdGdvLmNvaW4oJ3RmbHJwJyk7XG5cbiAgICAgIGNvbnN0IHdhbGxldFBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ2ZscnAgY3VzdG9kaWFsIHdhbGxldCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICAgIC8vIE5vIG11bHRpc2lnVHlwZSBzcGVjaWZpZWQg4oCUIHNob3VsZCBkZWZhdWx0IHRvICd0c3MnIGZvciBGTFJQXG4gICAgICAgIC8vIE5vIHBhc3NwaHJhc2Ug4oCUIGN1c3RvZGlhbCB3YWxsZXRzIG11c3Qgbm90IHJlcXVpcmUgb25lXG4gICAgICB9O1xuXG4gICAgICAvLyBGTFJQIGlzIEVDRFNBLCBzbyBnZW5lcmF0ZUN1c3RvZGlhbE1wY1dhbGxldCBmZXRjaGVzIFRTUyBzZXR0aW5nc1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKVxuICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBjb2luU2V0dGluZ3M6IHsgZmxycDogeyB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7fSB9IH0gfSk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90ZmxycC93YWxsZXQvYWRkJylcbiAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4ud2FsbGV0UGFyYW1zLCBtdWx0aXNpZ1R5cGU6ICd0c3MnLCBrZXlzIH0pO1xuXG4gICAgICBjb25zdCBmbHJwV2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZmxycCk7XG5cbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGZscnBXYWxsZXRzLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcyk7XG4gICAgICBpZiAoIWlzV2FsbGV0V2l0aEtleWNoYWlucyhyZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignd2FsbGV0IG1pc3NpbmcgcmVxdWlyZWQga2V5Y2hhaW5zJyk7XG4gICAgICB9XG4gICAgICByZXMud2FsbGV0LmxhYmVsKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5sYWJlbCk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLndhbGxldC50eXBlKCksIHdhbGxldFBhcmFtcy50eXBlKTtcbiAgICAgIHJlcy53YWxsZXQubXVsdGlzaWdUeXBlKCkuc2hvdWxkLmVxdWFsKCd0c3MnKTtcbiAgICAgIHJlcy51c2VyS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKGtleXNbMF0pO1xuICAgICAgcmVzLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzFdKTtcbiAgICAgIHJlcy5iaXRnb0tleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzJdKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBuZXcgVFNTIFNNQyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9ICdsb25nc3RyaW5nJztcbiAgICAgIGNvbnN0IHNlZWQgPSAnc2VlZCc7XG4gICAgICBjb25zdCBrZXlzOiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGJpdGdvS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldCgnL2FwaS92Mi90c29sL2tleS8zJykucmVwbHkoMjAwLCBrZXlzLmJpdGdvS2V5Y2hhaW4pO1xuICAgICAgY29uc3QgdXNlcktleUV4cGVjdGVkQm9keSA9IHtcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGtleVR5cGU6ICd0c3MnLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgIH07XG4gICAgICBjb25zdCB1c2VyS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wva2V5JywgdXNlcktleUV4cGVjdGVkQm9keSlcbiAgICAgICAgLnJlcGx5KDIwMCwga2V5cy51c2VyS2V5Y2hhaW4pO1xuICAgICAgY29uc3QgYmFja3VwS2V5RXhwZWN0ZWRCb2R5ID0ge1xuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgYmFja3VwS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wva2V5JywgYmFja3VwS2V5RXhwZWN0ZWRCb2R5KVxuICAgICAgICAucmVwbHkoMjAwLCBrZXlzLmJhY2t1cEtleWNoYWluKTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2NvbGQnLFxuICAgICAgICBiaXRnb0tleUlkOiBrZXlzLmJpdGdvS2V5Y2hhaW4uaWQsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6IHNlZWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrRXhwZWN0ZWQgPSB7XG4gICAgICAgIGxhYmVsOiB3YWxsZXRQYXJhbXMubGFiZWwsXG4gICAgICAgIG06IDIsXG4gICAgICAgIG46IDMsXG4gICAgICAgIGtleXM6IFtrZXlzLnVzZXJLZXljaGFpbi5pZCwga2V5cy5iYWNrdXBLZXljaGFpbi5pZCwga2V5cy5iaXRnb0tleWNoYWluLmlkXSxcbiAgICAgICAgdHlwZTogd2FsbGV0UGFyYW1zLnR5cGUsXG4gICAgICAgIG11bHRpc2lnVHlwZTogd2FsbGV0UGFyYW1zLm11bHRpc2lnVHlwZSxcbiAgICAgICAgZW50ZXJwcmlzZTogd2FsbGV0UGFyYW1zLmVudGVycHJpc2UsXG4gICAgICAgIHdhbGxldFZlcnNpb246IHVuZGVmaW5lZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnLCB3YWxsZXROb2NrRXhwZWN0ZWQpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4ud2FsbGV0Tm9ja0V4cGVjdGVkLCByZXNwb25zZVR5cGU6ICdXYWxsZXRXaXRoS2V5Y2hhaW5zJyB9KTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0c29sKTtcblxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMpO1xuICAgICAgaWYgKCFpc1dhbGxldFdpdGhLZXljaGFpbnMocmVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dhbGxldCBtaXNzaW5nIHJlcXVpcmVkIGtleWNoYWlucycpO1xuICAgICAgfVxuICAgICAgcmVzLnJlc3BvbnNlVHlwZS5zaG91bGQuZXF1YWwoJ1dhbGxldFdpdGhLZXljaGFpbnMnKTtcbiAgICAgIHJlcy53YWxsZXQubGFiZWwoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmxhYmVsKTtcbiAgICAgIHNob3VsZC5lcXVhbChyZXMud2FsbGV0LnR5cGUoKSwgd2FsbGV0UGFyYW1zLnR5cGUpO1xuICAgICAgcmVzLndhbGxldC50b0pTT04oKS5lbnRlcnByaXNlLnNob3VsZC5lcXVhbCh3YWxsZXRQYXJhbXMuZW50ZXJwcmlzZSk7XG4gICAgICByZXMud2FsbGV0Lm11bHRpc2lnVHlwZSgpLnNob3VsZC5lcXVhbCh3YWxsZXRQYXJhbXMubXVsdGlzaWdUeXBlKTtcbiAgICAgIHJlcy51c2VyS2V5Y2hhaW4uc2hvdWxkLmRlZXBFcXVhbChrZXlzLnVzZXJLZXljaGFpbik7XG4gICAgICByZXMuYmFja3VwS2V5Y2hhaW4uc2hvdWxkLmRlZXBFcXVhbChrZXlzLmJhY2t1cEtleWNoYWluKTtcbiAgICAgIHJlcy5iaXRnb0tleWNoYWluLnNob3VsZC5kZWVwRXF1YWwoa2V5cy5iaXRnb0tleWNoYWluKTtcblxuICAgICAgYml0Z29LZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB1c2VyS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgYmFja3VwS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgVFNTIFNNQyB3YWxsZXQgaWYgdGhlIGJpdGdvS2V5SWQgaXMgbm90IGEgYml0Z28ga2V5ICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gJ2xvbmdzdHJpbmcnO1xuICAgICAgY29uc3Qgc2VlZCA9ICdzZWVkJztcbiAgICAgIGNvbnN0IGtleXM6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykuZ2V0KCcvYXBpL3YyL3Rzb2wva2V5LzEnKS5yZXBseSgyMDAsIGtleXMudXNlcktleWNoYWluKTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2NvbGQnLFxuICAgICAgICBiaXRnb0tleUlkOiBrZXlzLnVzZXJLZXljaGFpbi5pZCxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGNvbGREZXJpdmF0aW9uU2VlZDogc2VlZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1RoZSBwcm92aWRlZCBiaXRnb0tleUlkIGlzIG5vdCBhIEJpdEdvIGtleWNoYWluJyk7XG5cbiAgICAgIGJpdGdvS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgVFNTIE1QQ3YyIHdhbGxldDonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHNzU2V0dGluZ3M6IFRzc1NldHRpbmdzID0ge1xuICAgICAgICBjb2luU2V0dGluZ3M6IHtcbiAgICAgICAgICBldGg6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYnNjOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBvbHlnb246IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYXRvbToge1xuICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjb2xkTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY3VzdG9kaWFsTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aWE6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmVyYToge1xuICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjb2xkTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY3VzdG9kaWFsTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBhcmJldGg6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgb3BldGg6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykuZ2V0KGAvYXBpL3YyL3Rzcy9zZXR0aW5nc2ApLnF1ZXJ5KHRydWUpLnRpbWVzKDIpLnJlcGx5KDIwMCwgdHNzU2V0dGluZ3MpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgWydodGV0aCcsICd0YnNjJywgJ3Rwb2x5Z29uJywgJ3R0aWEnLCAndGF0b20nLCAndGJlcmEnLCAndGFyYmV0aCcsICd0b3BldGgnXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyAke2NvaW59IFRTUyBNUEN2MiBob3Qgd2FsbGV0YCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oY29pbik7XG4gICAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC9hZGRgKS5yZXBseSgyMDApO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBzdHViQ3JlYXRlS2V5Y2hhaW5zLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyAke2NvaW59IFRTUyBNUEN2MiBob3Qgd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtdWx0aXNpZyB0eXBlYCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oY29pbik7XG4gICAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC9hZGRgLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgICAgYm9keS5tdWx0aXNpZ1R5cGUuc2hvdWxkLmVxdWFsKG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBzdHViQ3JlYXRlS2V5Y2hhaW5zLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyAke2NvaW59IFRTUyBNUEN2MiBjb2xkIHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBiaXRnb0tleUlkID0gJ2tleTEyMyc7XG4gICAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gJzB4YWJjJztcblxuICAgICAgICBjb25zdCBiaXRnb0tleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvJHtjb2lufS9rZXkvJHtiaXRnb0tleUlkfWApXG4gICAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaWQ6ICdrZXkxMjMnLFxuICAgICAgICAgICAgcHViOiAnYml0Z29QdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB1c2VyS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS9rZXlgLCB7XG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgIGtleVR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiAnMzcnLFxuICAgICAgICAgICAgaXNNUEN2MjogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAndXNlcktleTEyMycsXG4gICAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYmFja3VwS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS9rZXlgLCB7XG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAga2V5VHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6ICczNycsXG4gICAgICAgICAgICBpc01QQ3YyOiB0cnVlLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaWQ6ICdiYWNrdXBLZXkxMjMnLFxuICAgICAgICAgICAgcHViOiAnYmFja3VwUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC9hZGRgLCB7XG4gICAgICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICAgICAgbTogMixcbiAgICAgICAgICAgIG46IDMsXG4gICAgICAgICAgICBrZXlzOiBbJ3VzZXJLZXkxMjMnLCAnYmFja3VwS2V5MTIzJywgJ2tleTEyMyddLFxuICAgICAgICAgICAgdHlwZTogJ2NvbGQnLFxuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRlc3RDb2luKTtcblxuICAgICAgICBjb25zdCBwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgICAgdHlwZTogJ2NvbGQnLFxuICAgICAgICAgIGJpdGdvS2V5SWQ6ICdrZXkxMjMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAnMHhhYmMnLFxuICAgICAgICAgIGNvbGREZXJpdmF0aW9uU2VlZDogJzM3JyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IChhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcykpIGFzIFdhbGxldFdpdGhLZXljaGFpbnM7XG5cbiAgICAgICAgYml0Z29LZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHVzZXJLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGJhY2t1cEtleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS53YWxsZXQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2UudXNlcktleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJhY2t1cEtleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4pO1xuICAgICAgICByZXNwb25zZS5yZXNwb25zZVR5cGUuc2hvdWxkLmVxdWFsKCdXYWxsZXRXaXRoS2V5Y2hhaW5zJyk7XG4gICAgICAgIHJlc3BvbnNlLnVzZXJLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoJ3VzZXJLZXkxMjMnKTtcbiAgICAgICAgcmVzcG9uc2UuYmFja3VwS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCdiYWNrdXBLZXkxMjMnKTtcbiAgICAgICAgcmVzcG9uc2UuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoJ2tleTEyMycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBzaG91bGQgY3JlYXRlIGEgbmV3ICR7Y29pbn0gVFNTIE1QQ3YyIGN1c3RvZHkgd2FsbGV0YCwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oY29pbik7XG4gICAgICAgIGNvbnN0IGtleXMgPSBbJ3VzZXJLZXknLCAnYmFja3VwS2V5JywgJ2JpdGdvS2V5J107XG5cbiAgICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIHR5cGU6ICdjdXN0b2RpYWwnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0vd2FsbGV0L2FkZGApXG4gICAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyAuLi5wYXJhbXMsIGtleXMgfSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpKSBhcyBXYWxsZXRXaXRoS2V5Y2hhaW5zO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLndhbGxldCk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS51c2VyS2V5Y2hhaW4pO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2UuYmFja3VwS2V5Y2hhaW4pO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2UuYml0Z29LZXljaGFpbik7XG4gICAgICAgIHJlc3BvbnNlLnJlc3BvbnNlVHlwZS5zaG91bGQuZXF1YWwoJ1dhbGxldFdpdGhLZXljaGFpbnMnKTtcbiAgICAgICAgcmVzcG9uc2UudXNlcktleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzBdKTtcbiAgICAgICAgcmVzcG9uc2UuYmFja3VwS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKGtleXNbMV0pO1xuICAgICAgICByZXNwb25zZS5iaXRnb0tleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzJdKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgaHRldGggVFNTIE1QQ3YyIHdhbGxldCB3aXRoIHdhbGxldFZlcnNpb24gNmAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRlc3RDb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0dWJDcmVhdGVLZXljaGFpbnMgPSBzYW5kYm94XG4gICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvYWRkYCwgKGJvZHkpID0+IHtcbiAgICAgICAgICBib2R5LndhbGxldFZlcnNpb24uc2hvdWxkLmVxdWFsKDYpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyBNUEN2MiB3YWxsZXQgd2l0aCB2ZXJzaW9uIDUgaWYgd2FsbGV0VmVyc2lvbiBwYXNzZWQgaXMgbm90IDUgb3IgNmAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRlc3RDb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0dWJDcmVhdGVLZXljaGFpbnMgPSBzYW5kYm94XG4gICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvYWRkYCwgKGJvZHkpID0+IHtcbiAgICAgICAgICBib2R5LndhbGxldFZlcnNpb24uc2hvdWxkLmVxdWFsKDUpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSBUU1MgRWREU0EgTVBDdjIgd2FsbGV0OicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0c3NTZXR0aW5nczogVHNzU2V0dGluZ3MgPSB7XG4gICAgICAgIGNvaW5TZXR0aW5nczoge1xuICAgICAgICAgIHNvbDoge1xuICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKS5xdWVyeSh0cnVlKS50aW1lcygyKS5yZXBseSgyMDAsIHRzc1NldHRpbmdzKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IHRzb2wgVFNTIEVkRFNBIE1QQ3YyIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0dWJDcmVhdGVLZXljaGFpbnMgPSBzYW5kYm94XG4gICAgICAgIC5zdHViKEVERFNBVXRpbHMuRWRkc2FNUEN2MlV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIGVkZHNhIG1wY3YyIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWxsIGJhY2sgdG8gRWRkc2FVdGlscyB3aGVuIHRzcy9zZXR0aW5ncyBkb2VzIG5vdCByZXR1cm4gTVBDdjIgZm9yIHRzb2wnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpXG4gICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAucmVwbHkoMjAwLCB7IGNvaW5TZXR0aW5nczogeyBzb2w6IHsgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge30gfSB9IH0pO1xuXG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0OiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0dWJFZGRzYVV0aWxzID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFRERTQVV0aWxzLmRlZmF1bHQucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJylcbiAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJykucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3MgZWRkc2Egd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycgYXMgY29uc3QsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc3R1YkVkZHNhVXRpbHMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NoYXJpbmcnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ1dhbGxldCBzaGFyZSB3aGVyZSBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgaXMgc2V0IHRydWUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiBwYXNzd29yZCBub3QgcHJvdml2ZWQgd2Ugc2hvdWxkIHJlY2VpdmUgdmFsaWRhdGlvbiBlcnJvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfMSc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgYWNjZXB0IHNoYXJlIGNhc2VcbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndXNlclBhc3N3b3JkIHBhcmFtIG11c3QgYmUgcHJvdmlkZWQgdG8gZGVjcnlwdCBzaGFyZWQga2V5Jyk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gd2UgYWNjZXB0IHNoYXJlIGFuZCBmYWlsZWQgdG8gbWFrZSBjaGFuZ2VzLCByZXNoYXJlIHNob3VsZCBub3QgYmUgY2FsbGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfY2FzZV8yJztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5JZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvb2ZjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlSW5mb05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50IChzaWduYXR1cmUgYW5kIHBheWxvYWQgYXJlIGR5bmFtaWMpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LmtleUlkID09PSBrZXljaGFpbklkICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnNpZ25hdHVyZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkucGF5bG9hZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IGZhbHNlIH0pO1xuXG4gICAgICAgIC8vIFN0dWIgd2FsbGV0IHNoYXJlIHdhbGxldCBtZXRob2RcbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVTdHViID0gc2FuZGJveC5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaGFyZVdhbGxldCcpLm9uQ2FsbCgwKS5yZXNvbHZlcygnc3VjY2VzcycpO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgZmFsc2UpO1xuICAgICAgICBrZXlDaGFpbk5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZUluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWQsIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiB3ZSBhY2NlcHQgc2hhcmUgYnV0IHN0YXRlIGlzIG5vdCB2YWxpZCwgcmVzaGFyZSBzaG91bGQgbm90IGJlIGNhbGxlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfMyc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndGVzdF9jYXNlXzMnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9jYXNlXzMnO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvb2ZjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlSW5mb05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50IChzaWduYXR1cmUgYW5kIHBheWxvYWQgYXJlIGR5bmFtaWMpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LmtleUlkID09PSBrZXljaGFpbklkICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnNpZ25hdHVyZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkucGF5bG9hZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnbm90X2FjY2VwdGVkJyB9KTtcblxuICAgICAgICAvLyBTdHViIHdhbGxldCBzaGFyZSB3YWxsZXQgbWV0aG9kXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3guc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKS5vbkNhbGwoMCkucmVzb2x2ZXMoJ3N1Y2Nlc3MnKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnbm90X2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlSW5mb05vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd3aGVuIHdlIGdldCBhIGNvcnJlY3QgcmVzcG9zbmUgZnJvbSBhY2NlcHQgc2hhcmUgbWV0aG9kLCBidXQgZmFpbGVkIHRvIHJlc2hhcmUgd2FsbGV0IHdpdGggc3BlbmRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBrZXljaGFpbklkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJPbmUgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzYnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNicsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNwZW5kZXJVc2VyVHdvID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV85JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzknLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhZG1pblVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzcnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNycsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHZpZXdlclVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzgnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOCcsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZUlkID0gJ3Rlc3RfY2FzZV82JztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgdXNlciBrZXlcbiAgICAgICAgY29uc3Qga2V5Q2hhaW5DcmVhdGVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92Mi9vZmMva2V5JywgXy5jb25mb3Jtcyh7IHB1YjogKHApID0+IHAuc3RhcnRzV2l0aCgneHB1YicpIH0pKVxuICAgICAgICAgIC5yZXBseSgyMDAsICh1cmksIHJlcXVlc3RCb2R5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4geyBpZDoga2V5Y2hhaW5JZCwgZW5jcnlwdGVkUHJ2OiByZXF1ZXN0Qm9keVsnZW5jcnlwdGVkUHJ2J10sIHB1YjogcmVxdWVzdEJvZHlbJ3B1YiddIH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYWNjZXB0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudCAoc2lnbmF0dXJlIGFuZCBwYXlsb2FkIGFyZSBkeW5hbWljKVxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5rZXlJZCA9PT0ga2V5Y2hhaW5JZCAmJlxuICAgICAgICAgICAgICB0eXBlb2YgYm9keS5zaWduYXR1cmUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnBheWxvYWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRJbmZvTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0LyR7d2FsbGV0SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyczogW3NwZW5kZXJVc2VyT25lLnBheWxvYWQsIHNwZW5kZXJVc2VyVHdvLnBheWxvYWQsIGFkbWluVXNlci5wYXlsb2FkLCB2aWV3ZXJVc2VyLnBheWxvYWRdLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZUlkLFxuICAgICAgICAgICAgY29pbjogc3BlbmRlclVzZXJPbmUuY29pbixcbiAgICAgICAgICAgIGlkOiB3YWxsZXRJZCxcbiAgICAgICAgICAgIGtleXM6IFt7fV0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZVVzZXJOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL2VudGVycHJpc2UvJHtlbnRlcnByaXNlSWR9L3VzZXJgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFkbWluVXNlcnM6IFtcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJPbmUuaWQsIGVtYWlsOiBzcGVuZGVyVXNlck9uZS5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBzcGVuZGVyVXNlclR3by5pZCwgZW1haWw6IHNwZW5kZXJVc2VyVHdvLmVtYWlsIH0sXG4gICAgICAgICAgICAgIHsgaWQ6IGFkbWluVXNlci5pZCwgZW1haWw6IGFkbWluVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiB2aWV3ZXJVc2VyLmlkLCBlbWFpbDogdmlld2VyVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG5vbkFkbWluVXNlcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKVxuICAgICAgICAgIC5yZXR1cm5zKG5ldyBQcm9taXNlKChfcmVzb2x2ZSwgcmVqZWN0KSA9PiByZWplY3QobmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzaGFyZSB3YWxsZXQnKSkpKTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc09uZSA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJPbmUuaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyT25lLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHNoYXJlUGFyYW1zVHdvID0ge1xuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXRJZCxcbiAgICAgICAgICB1c2VyOiBzcGVuZGVyVXNlclR3by5pZCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogc3BlbmRlclVzZXJUd28ucGF5bG9hZC5wZXJtaXNzaW9ucy5qb2luKCcsJyksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdXNlclBhc3N3b3JkLFxuICAgICAgICAgIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbC5lbWFpbCxcbiAgICAgICAgICByZXNoYXJlOiB0cnVlLFxuICAgICAgICAgIHNraXBLZXljaGFpbjogZmFsc2UsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgb2ZjV2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluQ3JlYXRlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldEluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgZW50ZXJwcmlzZVVzZXJOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRPbmNlLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRXaXRoKHNoYXJlUGFyYW1zT25lKSwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkV2l0aChzaGFyZVBhcmFtc1R3byksIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiB3ZSBnZXQgYSBjb3JyZWN0IHJlc3Bvc25lIGZyb20gYWNjZXB0IHNoYXJlIG1ldGhvZCBhbmQgcmVzaGFyZSB3YWxsZXQgd2l0aCBzcGVuZGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBzcGVuZGVyVXNlck9uZSA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzYnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfNicgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJUd28gPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV85JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzknIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFkbWluVXNlciA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzcnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfNycgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgdmlld2VyVXNlciA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzgnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfOCcgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBlbnRlcnByaXNlSWQgPSAndGVzdF9jYXNlXzYnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgdXNlciBrZXlcbiAgICAgICAgY29uc3Qga2V5Q2hhaW5DcmVhdGVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgcmVxdWlyZWQgZmllbGRzIGFyZSBwcmVzZW50IChzaWduYXR1cmUgYW5kIHBheWxvYWQgYXJlIGR5bmFtaWMpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LmtleUlkID09PSBrZXljaGFpbklkICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnNpZ25hdHVyZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkucGF5bG9hZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldEluZm9Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMvd2FsbGV0LyR7d2FsbGV0SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyczogW3NwZW5kZXJVc2VyT25lLnBheWxvYWQsIHNwZW5kZXJVc2VyVHdvLnBheWxvYWQsIGFkbWluVXNlci5wYXlsb2FkLCB2aWV3ZXJVc2VyLnBheWxvYWRdLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZUlkLFxuICAgICAgICAgICAgY29pbjogc3BlbmRlclVzZXJPbmUuY29pbixcbiAgICAgICAgICAgIGlkOiB3YWxsZXRJZCxcbiAgICAgICAgICAgIGtleXM6IFt7fV0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZVVzZXJOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL2VudGVycHJpc2UvJHtlbnRlcnByaXNlSWR9L3VzZXJgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFkbWluVXNlcnM6IFtcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJPbmUuaWQsIGVtYWlsOiBzcGVuZGVyVXNlck9uZS5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBzcGVuZGVyVXNlclR3by5pZCwgZW1haWw6IHNwZW5kZXJVc2VyVHdvLmVtYWlsIH0sXG4gICAgICAgICAgICAgIHsgaWQ6IGFkbWluVXNlci5pZCwgZW1haWw6IGFkbWluVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiB2aWV3ZXJVc2VyLmlkLCBlbWFpbDogdmlld2VyVXNlci5lbWFpbCB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG5vbkFkbWluVXNlcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKVxuICAgICAgICAgIC5yZXR1cm5zKG5ldyBQcm9taXNlKChyZXNvbHZlLCBfcmVqZWN0KSA9PiByZXNvbHZlKCdzdWNjZXNzJykpKTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc09uZSA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJPbmUuaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyT25lLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHNoYXJlUGFyYW1zVHdvID0ge1xuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXRJZCxcbiAgICAgICAgICB1c2VyOiBzcGVuZGVyVXNlclR3by5pZCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogc3BlbmRlclVzZXJUd28ucGF5bG9hZC5wZXJtaXNzaW9ucy5qb2luKCcsJyksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogdXNlclBhc3N3b3JkLFxuICAgICAgICAgIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbC5lbWFpbCxcbiAgICAgICAgICByZXNoYXJlOiB0cnVlLFxuICAgICAgICAgIHNraXBLZXljaGFpbjogZmFsc2UsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgd2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluQ3JlYXRlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldEluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgZW50ZXJwcmlzZVVzZXJOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRUd2ljZSwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkV2l0aChzaGFyZVBhcmFtc09uZSksIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZFdpdGgoc2hhcmVQYXJhbXNUd28pLCB0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1dhbGxldCBzaGFyZSB3aGVyZSB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIGlzIHNldCB0cnVlJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIHBhc3N3b3JkIG5vdCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV8xJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndXNlclBhc3N3b3JkIHBhcmFtIG11c3QgYmUgcHJvdmlkZWQgdG8gZ2VuZXJhdGUgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IGFjY2VwdCBzaGFyZSB3aXRoIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQgYW5kIHNlbmQgcHViIGFuZCBlbmNyeXB0ZWRQcnYnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfMic7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3Rfd2FsbGV0XzEyMyc7XG5cbiAgICAgICAgLy8gTW9jayB3YWxsZXQgc2hhcmUgcmVzcG9uc2VcbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGtleWNoYWluIGNyZWF0aW9uIC0gYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlKCkgcmV0dXJucyB7IHBydiwgcHViIH1cbiAgICAgICAgLy8gV2UgbmVlZCB0byBjcmVhdGUgYSBwcm9wZXIga2V5Y2hhaW4gb2JqZWN0IHdpdGggcHJ2IHByb3BlcnR5XG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsIC8vIE9GQyB1c2VzIHNlY3AyNTZrMSBrZXlzLCBzbyBwcnYgZm9ybWF0XG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFN0dWIga2V5Y2hhaW5zKCkuY3JlYXRlKCkgYW5kIGVuY3J5cHQoKSBCRUZPUkUgY2FsY3VsYXRpbmcgZW5jcnlwdGVkUHJ2XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zU3R1YiA9IHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNyeXB0U3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIC8vIE1vY2sgdGhlIHVwZGF0ZVNoYXJlIEFQSSBjYWxsXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyBWZXJpZnkgdGhhdCBwdWIgYW5kIGVuY3J5cHRlZFBydiBhcmUgaW5jbHVkZWRcbiAgICAgICAgICAgIGlmIChib2R5LndhbGxldFNoYXJlSWQgIT09IHNoYXJlSWQgfHwgYm9keS5zdGF0ZSAhPT0gJ2FjY2VwdGVkJyB8fCAhYm9keS5wdWIgfHwgIWJvZHkuZW5jcnlwdGVkUHJ2KSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFZlcmlmeSBwdWIgaXMgYSB2YWxpZCBmb3JtYXQgKHNlY3AyNTZrMSBwdWJsaWMga2V5IGZvciBPRkMpXG4gICAgICAgICAgICBpZiAoIW9mY1dhbGxldHMuYmFzZUNvaW4uaXNWYWxpZFB1Yihib2R5LnB1YikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuXG4gICAgICAgIC8vIFZlcmlmeSBrZXljaGFpbiBjcmVhdGlvbiB3YXMgY2FsbGVkXG4gICAgICAgIHNob3VsZC5lcXVhbChrZXljaGFpbnNTdHViLmNhbGxlZE9uY2UsIHRydWUpO1xuICAgICAgICAvLyBWZXJpZnkgZW5jcnlwdCB3YXMgY2FsbGVkIHdpdGggdGhlIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSksIHRydWUpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBOT1QgdHJpZ2dlciByZXNoYXJlIHdoZW4gdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBpcyB0cnVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzMnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X3dhbGxldF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgY2hhbmdlZDogdHJ1ZSwgc3RhdGU6ICdhY2NlcHRlZCcgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKGVuY3J5cHRlZFBydik7XG5cbiAgICAgICAgLy8gU3R1YiByZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzIHRvIHZlcmlmeSBpdCdzIE5PVCBjYWxsZWRcbiAgICAgICAgY29uc3QgcmVzaGFyZVN0dWIgPSBzYW5kYm94LnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdyZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzJyk7XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgb2ZjV2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHJlc2hhcmUgd2FzIE5PVCBjYWxsZWQgKHVubGlrZSBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgY2FzZSlcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYnVsayBhY2NlcHQgc2hhcmUgd2l0aCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5X2J1bGtfMSc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkXG4gICAgICAgIC8vIE5vdGU6IHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQgc2hhcmVzIGRvbid0IGhhdmUgYSBrZXljaGFpbiwgc28gdGhleSB3b24ndCBiZSBmaWx0ZXJlZFxuICAgICAgICAvLyBieSB0aGUgYnVsa0FjY2VwdFNoYXJlIGZpbHRlciwgYnV0IHByb2Nlc3NBY2NlcHRTaGFyZSB3aWxsIGhhbmRsZSB0aGVtXG4gICAgICAgIHNhbmRib3guc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2Zyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAndG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MTIzJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgIC8vIE5vIGtleWNoYWluIC0gdGhpcyBpcyB0aGUga2V5IGRpZmZlcmVuY2UgZm9yIG11bHRpLWtleS11c2VyLWtleSBzaGFyZXNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB1cCBzdHVicyBmaXJzdFxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluc1N0dWIgPSBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcblxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGtleWNoYWluLnBydiwgcGFzc3dvcmQ6IHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGsgdXBkYXRlIEFQSSAtIHRoaXMgaXMgY2FsbGVkIHZpYSBidWxrVXBkYXRlV2FsbGV0U2hhcmVcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy91cGRhdGUnLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWJvZHkuc2hhcmVzIHx8IGJvZHkuc2hhcmVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzaGFyZSA9IGJvZHkuc2hhcmVzWzBdO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBzaGFyZS5zdGF0dXMgPT09ICdhY2NlcHQnICYmXG4gICAgICAgICAgICAgIHNoYXJlLnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIHNoYXJlLmVuY3J5cHRlZFBydiA9PT0gZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTm90ZTogYnVsa0FjY2VwdFNoYXJlIGZpbHRlcnMgZm9yIHNoYXJlcyBXSVRIIGtleWNoYWlucywgYnV0IHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWRcbiAgICAgICAgLy8gc2hhcmVzIGRvbid0IGhhdmUga2V5Y2hhaW5zLCBzbyB0aGV5IGdvIHRocm91Z2ggYSBkaWZmZXJlbnQgcGF0aFxuICAgICAgICAvLyBXZSBuZWVkIHRvIHN0dWIgdGhlIHByb2Nlc3NBY2NlcHRTaGFyZSBwYXRoIG9yIHVzZSBidWxrVXBkYXRlV2FsbGV0U2hhcmUgZGlyZWN0bHlcbiAgICAgICAgLy8gRm9yIHRoaXMgdGVzdCwgd2UnbGwgdXNlIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSB3aGljaCBjYWxscyBwcm9jZXNzQWNjZXB0U2hhcmUgaW50ZXJuYWxseVxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvZmNXYWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLCAxKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXNbMF0sIHsgd2FsbGV0U2hhcmVJZDogJ3Rlc3RfbXVsdGlfa2V5X2J1bGtfMScgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChrZXljaGFpbnNTdHViLmNhbGxlZE9uY2UsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSksIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGJ1bGsgYWNjZXB0IHNoYXJlIHdpdGggdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBhbmQgbmV3V2FsbGV0UGFzc3BocmFzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV9idWxrXzInO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCBuZXdXYWxsZXRQYXNzcGhyYXNlID0gJ25ld193YWxsZXRfcGFzc3BocmFzZV80NTYnO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGggdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZFxuICAgICAgICBzYW5kYm94LnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdmcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ3RvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEyMycsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAvLyBObyBrZXljaGFpbiAtIHRoaXMgaXMgdGhlIGtleSBkaWZmZXJlbmNlIGZvciBtdWx0aS1rZXktdXNlci1rZXkgc2hhcmVzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgdXAgc3R1YnMgZmlyc3RcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBjb25zdCBrZXljaGFpbnNTdHViID0gc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgLy8gU2hvdWxkIGVuY3J5cHQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIGlmIHByb3ZpZGVkIChhcyBwZXIgaW1wbGVtZW50YXRpb24pXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGsgdXBkYXRlIEFQSSAtIHRoaXMgaXMgY2FsbGVkIHZpYSBidWxrVXBkYXRlV2FsbGV0U2hhcmVcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy91cGRhdGUnLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWJvZHkuc2hhcmVzIHx8IGJvZHkuc2hhcmVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzaGFyZSA9IGJvZHkuc2hhcmVzWzBdO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBzaGFyZS5zdGF0dXMgPT09ICdhY2NlcHQnICYmXG4gICAgICAgICAgICAgIHNoYXJlLnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIHNoYXJlLmVuY3J5cHRlZFBydiA9PT0gZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjV2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogdXNlclBhc3N3b3JkLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6IG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLCAxKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbChyZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXNbMF0sIHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGtleWNoYWluc1N0dWIuY2FsbGVkT25jZSwgdHJ1ZSk7XG4gICAgICAgIC8vIFZlcmlmeSBlbmNyeXB0IHdhcyBjYWxsZWQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIChub3QgdXNlclBhc3N3b3JkKVxuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiBuZXdXYWxsZXRQYXNzcGhyYXNlIH0pLCB0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gbmVpdGhlciB1c2VyTG9naW5QYXNzd29yZCBub3IgbmV3V2FsbGV0UGFzc3BocmFzZSBwcm92aWRlZCBmb3IgYnVsayBhY2NlcHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfYnVsa18zJztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWRcbiAgICAgICAgc2FuZGJveC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBzaGFyZUlkLFxuICAgICAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICd0b1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxMjMnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgdXNlciBzZXR0aW5ncyBBUEkgY2FsbCAocmVxdWlyZWQgYnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlKVxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvdXNlci9zZXR0aW5ncycpLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCAtIHdoZW4gdGhlcmUgYXJlIGVycm9ycywgaXQncyBjYWxsZWQgd2l0aCBlbXB0eSBhcnJheVxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL3VwZGF0ZScsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBib2R5LnNoYXJlcyAmJiBib2R5LnNoYXJlcy5sZW5ndGggPT09IDA7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gYnVsa1VwZGF0ZVdhbGxldFNoYXJlIHVzZXMgUHJvbWlzZS5hbGxTZXR0bGVkLCBzbyBlcnJvcnMgYXJlIGNhdWdodCBhbmQgcmV0dXJuZWQgaW4gd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNcbiAgICAgICAgLy8gV2UgbmVlZCB0byBjaGVjayB0aGUgcmVzdWx0IGZvciBlcnJvcnMgaW5zdGVhZCBvZiBleHBlY3RpbmcgYSByZWplY3Rpb25cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjV2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoYXQgdGhlIGVycm9yIHdhcyBjYXB0dXJlZCBpbiB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yc1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzLmxlbmd0aCwgMSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0ud2FsbGV0U2hhcmVJZCwgc2hhcmVJZCk7XG4gICAgICAgIHNob3VsZChyZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0ucmVhc29uKS5jb250YWluRXFsKFxuICAgICAgICAgICd1c2VyTG9naW5QYXNzd29yZCBwYXJhbSBtdXN0IGJlIHByb3ZpZGVkIHRvIGdlbmVyYXRlIHVzZXIga2V5Y2hhaW4nXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZSBwYXJhbWV0ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfNCc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG4gICAgICAgIGNvbnN0IG5ld1dhbGxldFBhc3NwaHJhc2UgPSAnbmV3X3dhbGxldF9wYXNzcGhyYXNlXzQ1Nic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3Rfd2FsbGV0XzEyMyc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTdHViIGNyZWF0ZSgpIGFuZCBlbmNyeXB0KCkgQkVGT1JFIGNhbGN1bGF0aW5nIGVuY3J5cHRlZFBydiB0byBlbnN1cmUgY29uc2lzdGVuY3lcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcblxuICAgICAgICAvLyBTaG91bGQgZW5jcnlwdCB3aXRoIG5ld1dhbGxldFBhc3NwaHJhc2UgaWYgcHJvdmlkZWQgKGFzIHBlciBpbXBsZW1lbnRhdGlvbilcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiBuZXdXYWxsZXRQYXNzcGhyYXNlIH0pO1xuICAgICAgICBjb25zdCBlbmNyeXB0U3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIGJvZHkuZW5jcnlwdGVkUHJ2ID09PSBlbmNyeXB0ZWRQcnZcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsXG4gICAgICAgICAgdXNlclBhc3N3b3JkLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICAvLyBWZXJpZnkgZW5jcnlwdCB3YXMgY2FsbGVkIHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZVxuICAgICAgICBzaG91bGQuZXF1YWwoZW5jcnlwdFN0dWIuY2FsbGVkV2l0aCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiBuZXdXYWxsZXRQYXNzcGhyYXNlIH0pLCB0cnVlKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcHJpb3JpdGl6ZSB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIG92ZXIga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzUnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X3dhbGxldF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSwgLy8gQm90aCBzZXQsIGJ1dCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIHNob3VsZCB0YWtlIHByZWNlZGVuY2VcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IHVwIHN0dWJzIGZpcnN0XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIC8vIFNob3VsZCB1c2UgdGhlIG11bHRpLWtleS11c2VyLWtleSBmbG93IChubyBzaWduYXR1cmUvcGF5bG9hZC9rZXlJZClcbiAgICAgICAgY29uc3QgYWNjZXB0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIFZlcmlmeSBpdCdzIHVzaW5nIG11bHRpLWtleS11c2VyLWtleSBmbG93IChoYXMgcHViIGFuZCBlbmNyeXB0ZWRQcnYsIGJ1dCBubyBzaWduYXR1cmUvcGF5bG9hZC9rZXlJZClcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIGJvZHkud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBib2R5LnN0YXRlID09PSAnYWNjZXB0ZWQnICYmXG4gICAgICAgICAgICAgIGJvZHkucHViID09PSBrZXljaGFpbi5wdWIgJiZcbiAgICAgICAgICAgICAgYm9keS5lbmNyeXB0ZWRQcnYgPT09IGVuY3J5cHRlZFBydiAmJlxuICAgICAgICAgICAgICAhYm9keS5zaWduYXR1cmUgJiZcbiAgICAgICAgICAgICAgIWJvZHkucGF5bG9hZCAmJlxuICAgICAgICAgICAgICAhYm9keS5rZXlJZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgY2hhbmdlZDogdHJ1ZSwgc3RhdGU6ICdhY2NlcHRlZCcgfSk7XG4gICAgICAgIGNvbnN0IHJlc2hhcmVTdHViID0gc2FuZGJveC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIC8vIFZlcmlmeSByZXNoYXJlIHdhcyBOT1QgY2FsbGVkIChtdWx0aS1rZXktdXNlci1rZXkgZmxvdylcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUga2V5Y2hhaW4gY3JlYXRpb24gZmFpbHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV82JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5FcnJvciA9IG5ldyBFcnJvcignRmFpbGVkIHRvIGNyZWF0ZSBrZXljaGFpbicpO1xuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnRocm93cyhrZXljaGFpbkVycm9yKTtcblxuICAgICAgICBhd2FpdCBvZmNXYWxsZXRzXG4gICAgICAgICAgLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ZhaWxlZCB0byBjcmVhdGUga2V5Y2hhaW4nKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGVuY3J5cHRpb24gZmFpbHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV83JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcbiAgICAgICAgY29uc3QgZW5jcnlwdGlvbkVycm9yID0gbmV3IEVycm9yKCdFbmNyeXB0aW9uIGZhaWxlZCcpO1xuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykudGhyb3dzKGVuY3J5cHRpb25FcnJvcik7XG5cbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFbmNyeXB0aW9uIGZhaWxlZCcpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB3b3JrIHdpdGggdmlldy1vbmx5IHBlcm1pc3Npb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzgnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnXSwgLy8gVmlldy1vbmx5IHBlcm1pc3Npb25zXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IHVwIHN0dWJzIGZpcnN0XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIGJvZHkuZW5jcnlwdGVkUHJ2ID09PSBlbmNyeXB0ZWRQcnZcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG5cbiAgICAgICAgd2FsbGV0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBleGFjdCB2YWx1ZXMgc2VudCBpbiBBUEkgcmVxdWVzdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV85JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAndGVzdF93YWxsZXRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB1cCBzdHVicyBmaXJzdFxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICBsZXQgY2FwdHVyZWRCb2R5OiBhbnk7XG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICBjYXB0dXJlZEJvZHkgPSBib2R5O1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGV4YWN0IHZhbHVlc1xuICAgICAgICBzaG91bGQuZXF1YWwoY2FwdHVyZWRCb2R5LndhbGxldFNoYXJlSWQsIHNoYXJlSWQpO1xuICAgICAgICBzaG91bGQuZXF1YWwoY2FwdHVyZWRCb2R5LnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGNhcHR1cmVkQm9keS5wdWIsIGtleWNoYWluLnB1Yik7XG4gICAgICAgIHNob3VsZC5lcXVhbChjYXB0dXJlZEJvZHkuZW5jcnlwdGVkUHJ2LCBlbmNyeXB0ZWRQcnYpO1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KGNhcHR1cmVkQm9keS5zaWduYXR1cmUpO1xuICAgICAgICBzaG91bGQubm90LmV4aXN0KGNhcHR1cmVkQm9keS5wYXlsb2FkKTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChjYXB0dXJlZEJvZHkua2V5SWQpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2hhcmUgYSB3YWxsZXQgdG8gdmlld2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2hhcmVJZCA9ICcxMjMxMSc7XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdGU6ICdhY2NlcHRlZCcgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9KTtcbiAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgndjIgZW52ZWxvcGUgc3VwcG9ydCBpbiBhY2NlcHRTaGFyZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICBhZnRlckVhY2goKCkgPT4gc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCkpO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBzaGFyZSB3aGVuIEVDREggc2hhcmluZyBrZXljaGFpbiBlbmNyeXB0ZWRYcHJ2IGlzIHYyLWVuY3J5cHRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd2Mi1lY2RoLXhwcnYtMSc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkJztcblxuICAgICAgICAvLyBTaW11bGF0ZSBhIHYyIGVudmVsb3BlIGZvciB0aGUgRUNESCByb290IGtleVxuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFiYmNjJywgY3Q6ICdkZGVlZmYnLCBhZGF0YTogJzAwJyB9KTtcbiAgICAgICAgY29uc3QgZmFrZVhwcnYgPSAneHBydlNvbWVCYXNlNThWYWx1ZSc7XG4gICAgICAgIGNvbnN0IGZha2VTZWNyZXQgPSAnZmFrZUVjZGhTaGFyZWRTZWNyZXQnO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnd2FsbGV0UHJpdktleVBsYWludGV4dCc7XG5cbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBmYWtlU2VjcmV0LCBpbnB1dDogZGVjcnlwdGVkV2FsbGV0UHJ2IH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHBhdGg6ICdtLzAvMC8xJyxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogdjJFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgIHB1YjogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCkucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHsgZW5jcnlwdGVkWHBydjogdjJFbmNyeXB0ZWRYcHJ2IH0pO1xuICAgICAgICBjb25zdCBkZWNyeXB0QXN5bmNTdHViID0gc2FuZGJveC5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICAvLyBGaXJzdCBjYWxsIGRlY3J5cHRzIHRoZSBFQ0RIIGtleWNoYWluICh2MiksIHNlY29uZCBkZWNyeXB0cyB0aGUgc2hhcmVkIHdhbGxldCBwcnZcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKGZha2VYcHJ2KTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICBzYW5kYm94LnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKGZha2VTZWNyZXQpKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgLy8gTXVzdCBoYXZlIGNhbGxlZCBkZWNyeXB0IChub3QgdGhlIHN5bmMgZGVjcnlwdCkgZm9yIGJvdGggdGhlIEVDREgga2V5IGFuZCB0aGUgd2FsbGV0IHBydlxuICAgICAgICBhc3NlcnQuZXF1YWwoZGVjcnlwdEFzeW5jU3R1Yi5jYWxsQ291bnQsIDIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IHNoYXJlIHdoZW4gd2FsbGV0IGtleWNoYWluIGVuY3J5cHRlZFBydiBpcyB2Mi1lbmNyeXB0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndjItd2FsbGV0LXBydi0xJztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmQnO1xuXG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkWHBydiA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaXY6ICdhYWJiY2MnLCBjdDogJ2RkZWVmZicsIGFkYXRhOiAnMDAnIH0pO1xuICAgICAgICBjb25zdCBmYWtlWHBydiA9ICd4cHJ2QW5vdGhlcktleSc7XG4gICAgICAgIGNvbnN0IGZha2VTZWNyZXQgPSAnZWNkaFNoYXJlZFNlY3JldDInO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnd2FsbGV0UHJpdktleTInO1xuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFBydiA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaXY6ICcxMTIyMzMnLCBjdDogJzQ0NTU2NicsIGFkYXRhOiAnNzcnIH0pO1xuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwYXRoOiAnbS8wLzAvMicsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgIHRvUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IHYyRW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICBwdWI6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcbiAgICAgICAgY29uc3QgZGVjcnlwdEFzeW5jU3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKGZha2VYcHJ2KTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICBzYW5kYm94LnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKGZha2VTZWNyZXQpKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2J1bGtBY2NlcHRTaGFyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciB1c2VyUGFzc3dvcmQgZW1wdHkgc3RyaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWRzOiBbXSwgdXNlckxvZ2luUGFzc3dvcmQ6ICcnIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgdXNlciBsb2dpbiBwYXNzd29yZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igc2VuZGluZyB3YWxsZXRQYXNzcGhyYXNlIGVtcHR5IHN0cmluZycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogW10sIHVzZXJMb2dpblBhc3N3b3JkOiAncGFzc3dvcmQnLCBuZXdXYWxsZXRQYXNzcGhyYXNlOiAxMjMgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnUGxlYXNlIHByb3ZpZGUgYSB2YWxpZCB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYXNzZXJ0aW9uIGVycm9yIGZvciBlbXB0eSB3YWxsZXRTaGFyZUlkcycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogW10sIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyB9KVxuICAgICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdQbGVhc2UgcHJvdmlkZSBhdCBsZWFzdCBvbmUgd2FsbGV0IHNoYXJlIHRvIGFjY2VwdCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG5vIHZhbGlkIHdhbGxldCBzaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBbJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQxJ10sXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogJ2R1bW15QDEyMycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnTm8gdmFsaWQgd2FsbGV0IHNoYXJlcyBmb3VuZCB0byBhY2NlcHQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBubyB2YWxpZCB3YWxsZXRTaGFyZXMgd2l0aCBrZXljaGFpbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ2R1bW15V2FsbGV0SWQnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ05vIHZhbGlkIHdhbGxldCBzaGFyZXMgZm91bmQgdG8gYWNjZXB0Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgZWNkaCBrZXljaGFpbiB1bmRlZmluZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgICAgcGF0aDogJ3BhdGgnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgcHJ2OiAncHJpdmF0ZSBrZXknLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgYWNjZXB0IHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBmcm9tVXNlclBydi50b1N0cmluZygpLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBydiA9IGF3YWl0IGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkoYml0Z28sIGtleWNoYWluVGVzdCwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGlmICghdXNlclBydikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRlY3J5cHQgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3dhbGxldHNoYXJlcycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICAgIGlzVU1TSW5pdGlhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIGNvbnN0IHNoYXJlID0gYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBbJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0J10sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHNoYXJlLCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgc2hhcmUgd2hlbiBFQ0RIIHNoYXJpbmcga2V5Y2hhaW4gaXMgdjItZW5jcnlwdGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnO1xuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gJ3NvbWVXYWxsZXRQcml2YXRlS2V5JztcbiAgICAgICAgY29uc3QgbmV3RW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzZWNyZXQsIGlucHV0OiBkZWNyeXB0ZWRQcnYgfSk7XG5cbiAgICAgICAgLy8gU2ltdWxhdGUgdjItZW5jcnlwdGVkIEVDREgga2V5Y2hhaW4geHBydiAoZW52ZWxvcGUgd2l0aCB2OjIgbWFya2VyKVxuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFhJywgY3Q6ICdiYmInLCBhZGF0YTogJ2NjYycgfSk7XG4gICAgICAgIGNvbnN0IG15RWNkaFhwcnYgPSAneHBydlNvbWVCYXNlNThLZXknO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi93YWxsZXRzaGFyZXMnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgICBpc1VNU0luaXRpYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0gfSk7XG5cbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHsgZW5jcnlwdGVkWHBydjogdjJFbmNyeXB0ZWRYcHJ2IH0pO1xuICAgICAgICAvLyBkZWNyeXB0IHJlc29sdmVzIHdpdGggdGhlIHhwcnYgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSBlbnZlbG9wZSBpcyB2MSBvciB2MlxuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKG15RWNkaFhwcnYpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBjb25zdCBzaGFyZSA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaGFyZSwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9XSB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBzaGFyZSB3aGVuIHdhbGxldCBrZXljaGFpbiBlbmNyeXB0ZWRQcnYgaXMgdjItZW5jcnlwdGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndjItcHJ2LXNoYXJlLTEnO1xuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG5cbiAgICAgICAgLy8gU2ltdWxhdGUgdjItZW5jcnlwdGVkIGVuY3J5cHRlZFBydiBpbiB0aGUgd2FsbGV0IHNoYXJlIGtleWNoYWluXG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkUHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpdjogJ3h4eCcsIGN0OiAneXl5JywgYWRhdGE6ICd6enonIH0pO1xuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFhJywgY3Q6ICdiYmInLCBhZGF0YTogJ2NjYycgfSk7XG4gICAgICAgIGNvbnN0IG15RWNkaFhwcnYgPSAneHBydlNvbWVCYXNlNThLZXknO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnZGVjcnlwdGVkV2FsbGV0UHJpdktleSc7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3dhbGxldHNoYXJlcycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiBzaGFyZUlkLFxuICAgICAgICAgICAgICAgIGlzVU1TSW5pdGlhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogdjJFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dIH0pO1xuXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcbiAgICAgICAgLy8gRmlyc3QgY2FsbDogZGVjcnlwdCBFQ0RIIGtleWNoYWluIHhwcnY7IHNlY29uZCBjYWxsOiBkZWNyeXB0IHYyIHdhbGxldCBzaGFyZSBwcnZcbiAgICAgICAgY29uc3QgZGVjcnlwdEFzeW5jU3R1YiA9IHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0Jyk7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhteUVjZGhYcHJ2KTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vblNlY29uZENhbGwoKS5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBjb25zdCBzaGFyZSA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaGFyZSwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9XSB9KTtcbiAgICAgICAgLy8gQm90aCBkZWNyeXB0IGNhbGxzIG11c3QgdXNlIGRlY3J5cHQgKG5vdCB0aGUgc3luYyBkZWNyeXB0KVxuICAgICAgICBhc3NlcnQuZXF1YWwoZGVjcnlwdEFzeW5jU3R1Yi5jYWxsQ291bnQsIDIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaW5jbHVkZSB3ZWJhdXRobkluZm8gaW4gcmVxdWVzdCB3aGVuIHByb3ZpZGVkIChFQ0RIIGJyYW5jaCknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZyb21Vc2VyUHJ2ID0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCB3ZWJhdXRoblBhc3NwaHJhc2UgPSAncHJmLWRlcml2ZWQtc2VjcmV0JztcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG5cbiAgICAgICAgbGV0IGNhcHR1cmVkQm9keTogYW55O1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzJylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgICAgaXNVTVNJbml0aWF0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBuZXdFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIGNhcHR1cmVkQm9keSA9IGJvZHk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHdlYmF1dGhuSW5mbzoge1xuICAgICAgICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMDAxJyxcbiAgICAgICAgICAgIHByZlNhbHQ6ICdzYWx0LWFiYycsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiB3ZWJhdXRoblBhc3NwaHJhc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2VudEVudHJpZXMgPSBjYXB0dXJlZEJvZHkua2V5c0ZvcldhbGxldFNoYXJlcztcbiAgICAgICAgc2VudEVudHJpZXMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBzZW50RW50cmllc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2Jyk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkluZm8nKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0ud2ViYXV0aG5JbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvdHBEZXZpY2VJZCcsICdkZXZpY2UtMDAxJyk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLndlYmF1dGhuSW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJmU2FsdCcsICdzYWx0LWFiYycpO1xuICAgICAgICBzZW50RW50cmllc1swXS53ZWJhdXRobkluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgICAgICBzZW50RW50cmllc1swXS53ZWJhdXRobkluZm8uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdwYXNzcGhyYXNlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBOT1QgaW5jbHVkZSB3ZWJhdXRobkluZm8gd2hlbiBub3QgcHJvdmlkZWQgKGJhY2t3YXJkIGNvbXBhdCknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZyb21Vc2VyUHJ2ID0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBmcm9tVXNlclBydi50b1N0cmluZygpLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBydiA9IGF3YWl0IGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkoYml0Z28sIGtleWNoYWluVGVzdCwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGlmICghdXNlclBydikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRlY3J5cHQgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcblxuICAgICAgICBsZXQgY2FwdHVyZWRCb2R5OiBhbnk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi93YWxsZXRzaGFyZXMnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgICBpc1VNU0luaXRpYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgY2FwdHVyZWRCb2R5ID0gYm9keTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogW3NoYXJlSWRdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzZW50RW50cmllcyA9IGNhcHR1cmVkQm9keS5rZXlzRm9yV2FsbGV0U2hhcmVzO1xuICAgICAgICBzZW50RW50cmllcy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRQcnYnKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkluZm8nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSA0MTMgcGF5bG9hZCB0b28gbGFyZ2UgZXJyb3Igd2l0aCBzbWFydCByZXRyeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICAvLyBQYWQgdGhlIHByaXZhdGUga2V5IHdpdGggYWRkaXRpb25hbCBkYXRhIHRvIG1ha2UgaXQgbGFyZ2VyIGJlZm9yZSBlbmNyeXB0aW5nXG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNoYXJlSWRzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogMjAgfSwgKF8sIGkpID0+IGBzaGFyZSR7aSArIDF9YCk7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIDI1IHNoYXJlc1xuICAgICAgICBjb25zdCBzaGFyZXMgPSBzaGFyZUlkcy5tYXAoKGlkLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgd2FsbGV0TGFiZWw6IGB0ZXN0aW5nJHtpbmRleH1gLFxuICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgIHdhbGxldDogYHdhbGxldCR7aW5kZXh9YCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyBhcyBjb25zdCxcbiAgICAgICAgICBrZXljaGFpbjoga2V5Y2hhaW4sXG4gICAgICAgIH0pKTtcblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBzaGFyZXMsXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKHVzZXJQcnYgKyAnWCcucmVwZWF0KDEwMDAwMCkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtBY2NlcHRTaGFyZVJlcXVlc3RXaXRoUmV0cnkgdG8gdHJhY2sgYmF0Y2ggc2l6ZXNcbiAgICAgICAgY29uc3QgYmF0Y2hTaXplczogbnVtYmVyW10gPSBbXTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wZXJzaXN0KCkgLy8gVGhpcyBlbnN1cmVzIHRoZSBpbnRlcmNlcHRvciByZW1haW5zIGFjdGl2ZSBmb3IgbXVsdGlwbGUgcmVxdWVzdHNcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKVxuICAgICAgICAgIC5yZXBseShmdW5jdGlvbiAoXywgcmVxdWVzdEJvZHksIGNiKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSByZXF1ZXN0Qm9keVsna2V5c0ZvcldhbGxldFNoYXJlcyddIGFzIEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXTtcbiAgICAgICAgICAgIGJhdGNoU2l6ZXMucHVzaChwYXJhbXMubGVuZ3RoKTtcbiAgICAgICAgICAgIGlmIChCdWZmZXIuYnl0ZUxlbmd0aChKU09OLnN0cmluZ2lmeShyZXF1ZXN0Qm9keSksICd1dGY4JykgPiA5NTAwMDApIHtcbiAgICAgICAgICAgICAgLy8gU2ltdWxhdGUgNDEzIGVycm9yXG4gICAgICAgICAgICAgIHJldHVybiBjYihudWxsLCBbNDEzLCB7IGVycm9yOiAnUmVxdWVzdCBFbnRpdHkgVG9vIExhcmdlJyB9XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZXR1cm4gc3VjY2VzcyBmb3Igc21hbGxlciBiYXRjaGVzXG4gICAgICAgICAgICByZXR1cm4gY2IobnVsbCwgW1xuICAgICAgICAgICAgICAyMDAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogcGFyYW1zLm1hcCgocGFyYW0pID0+ICh7XG4gICAgICAgICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiBwYXJhbS53YWxsZXRTaGFyZUlkLFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNob3VsZCBoYXZlIHRyaWVkIHdpdGggMjAgKGluaXRpYWwgYmF0Y2ggc2l6ZSBmb3IgMjUgaXRlbXMpLCB0aGVuIHJldHJpZWQgd2l0aCBzbWFsbGVyIGJhdGNoZXNcbiAgICAgICAgYmF0Y2hTaXplcy5sZW5ndGguc2hvdWxkLmJlLmdyZWF0ZXJUaGFuKDEpO1xuICAgICAgICBiYXRjaFNpemVzLnNob3VsZC5kZWVwRXF1YWwoWzksIDksIDJdKTsgLy8gSW5pdGlhbCBiYXRjaCBzaXplLy8gUmV0cnkgYmF0Y2hlcyBzaG91bGQgYmUgc21hbGxlclxuXG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWNjZXB0ZWRXYWxsZXRTaGFyZXMnKTtcbiAgICAgICAgcmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLnNob3VsZC5iZS5hbi5BcnJheSgpO1xuICAgICAgICByZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgyMCk7XG4gICAgICAgIHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcy5mb3JFYWNoKChzaGFyZSkgPT4ge1xuICAgICAgICAgIHNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRTaGFyZUlkJyk7XG4gICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZC5zaG91bGQubWF0Y2goL15zaGFyZVxcZCskLyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0cnkgd2l0aCBwcm9ncmVzc2l2ZWx5IHNtYWxsZXIgYmF0Y2ggc2l6ZXMgb24gNDEzIGVycm9ycycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzaGFyZUlkcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IDIwIH0sIChfLCBpKSA9PiBgc2hhcmUke2kgKyAxfWApO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyXG4gICAgICAgIGNvbnN0IHNoYXJlcyA9IHNoYXJlSWRzLm1hcCgoaWQsIGluZGV4KSA9PiAoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICB3YWxsZXRMYWJlbDogYHRlc3Rpbmcke2luZGV4fWAsXG4gICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgd2FsbGV0OiBgd2FsbGV0JHtpbmRleH1gLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgc3RhdGU6ICdhY3RpdmUnIGFzIGNvbnN0LFxuICAgICAgICAgIGtleWNoYWluOiBrZXljaGFpbixcbiAgICAgICAgfSkpO1xuXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IHNoYXJlcyxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHBydktleSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXModXNlclBydiArICdYJy5yZXBlYXQoMTAwMDAwKSk7XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICAgIC8vIFRyYWNrIHRoZSBzZXF1ZW5jZSBvZiBiYXRjaCBzaXplcyBhdHRlbXB0ZWRcbiAgICAgICAgY29uc3QgYmF0Y2hTaXplQXR0ZW1wdHM6IG51bWJlcltdID0gW107XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpIC8vIFRoaXMgZW5zdXJlcyB0aGUgaW50ZXJjZXB0b3IgcmVtYWlucyBhY3RpdmUgZm9yIG11bHRpcGxlIHJlcXVlc3RzXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoZnVuY3Rpb24gKF8sIHJlcXVlc3RCb2R5OiBhbnksIGNiKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSByZXF1ZXN0Qm9keVsna2V5c0ZvcldhbGxldFNoYXJlcyddIGFzIEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXTtcbiAgICAgICAgICAgIGJhdGNoU2l6ZUF0dGVtcHRzLnB1c2gocGFyYW1zLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIC8vIFNpbXVsYXRlIDQxMyBmb3IgYmF0Y2hlcyA+IDUsIHN1Y2Nlc3MgZm9yIGJhdGNoZXMgPD0gNVxuICAgICAgICAgICAgaWYgKEJ1ZmZlci5ieXRlTGVuZ3RoKEpTT04uc3RyaW5naWZ5KHJlcXVlc3RCb2R5KSwgJ3V0ZjgnKSA+IDYwMDAwMCkge1xuICAgICAgICAgICAgICAvLyBTaW11bGF0ZSA0MTMgZXJyb3JcbiAgICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFs0MTMsIHsgZXJyb3I6ICdSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UnIH1dKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmV0dXJuIHN1Y2Nlc3MgZm9yIHNtYWxsZXIgYmF0Y2hlc1xuICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFtcbiAgICAgICAgICAgICAgMjAwLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHBhcmFtcy5tYXAoKHBhcmFtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogcGFyYW0ud2FsbGV0U2hhcmVJZCB8fCAndGVzdCcsXG4gICAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcyxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2hvdWxkIHNlZSBwcm9ncmVzc2l2ZSBiYXRjaCBzaXplIHJlZHVjdGlvbjogMjAgLT4gMTAgLT4gNSAoc3VjY2VzcylcbiAgICAgICAgYmF0Y2hTaXplQXR0ZW1wdHMuc2hvdWxkLmNvbnRhaW5EZWVwKFs5LCA0LCA0LCA0LCA0LCA0XSk7XG5cbiAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhY2NlcHRlZFdhbGxldFNoYXJlcycpO1xuICAgICAgICByZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgICAgIHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcy5sZW5ndGguc2hvdWxkLmVxdWFsKDIwKTtcbiAgICAgICAgcmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLmZvckVhY2goKHNoYXJlKSA9PiB7XG4gICAgICAgICAgc2hhcmUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFNoYXJlSWQnKTtcbiAgICAgICAgICBzaGFyZS53YWxsZXRTaGFyZUlkLnNob3VsZC5tYXRjaCgvXnNoYXJlXFxkKyQvKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGJhdGNoIHNpemUgY2Fubm90IGJlIHJlZHVjZWQgZnVydGhlcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzaGFyZUlkcyA9IFsnc2hhcmUxJ107XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjJcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjoga2V5Y2hhaW4sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICAvLyBBbHdheXMgdGhyb3cgNDEzIGVycm9yLCBldmVuIGZvciBiYXRjaCBzaXplIDFcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoZnVuY3Rpb24gKF8sIF9yZXF1ZXN0Qm9keSwgY2IpIHtcbiAgICAgICAgICAgIC8vIEFsd2F5cyByZXNwb25kIHdpdGggNDEzIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2IobnVsbCwgWzQxMywgeyBlcnJvcjogJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZScgfV0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcyxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdFbmNyeXB0aW9uU2Vzc2lvbiAoSEtERiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGFzeW5jIGZ1bmN0aW9uIHN0dWJGb3JTaGFyZXMoc2hhcmVDb3VudDogbnVtYmVyLCBkZWNyeXB0ZWRXYWxsZXRQcnY6IHN0cmluZywgd2FsbGV0UGFzc3BocmFzZTogc3RyaW5nKSB7XG4gICAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgY29uc3Qgc2VuZGVyRW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzZWNyZXQsIGlucHV0OiBkZWNyeXB0ZWRXYWxsZXRQcnYgfSk7XG5cbiAgICAgICAgICBjb25zdCBzaGFyZUlkcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHNoYXJlQ291bnQgfSwgKF8sIGkpID0+IGBoa2RmLXNoYXJlLSR7aX1gKTtcbiAgICAgICAgICBjb25zdCBzaGFyZXMgPSBzaGFyZUlkcy5tYXAoKGlkLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgd2FsbGV0TGFiZWw6IGB3JHtpbmRleH1gLFxuICAgICAgICAgICAgZnJvbVVzZXI6ICdmcm9tJyxcbiAgICAgICAgICAgIHRvVXNlcjogJ3RvJyxcbiAgICAgICAgICAgIHdhbGxldDogYHcke2luZGV4fWAsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiBgZW50LSR7aW5kZXh9YCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScgYXMgY29uc3QsXG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IHNlbmRlckVuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKTtcblxuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7IGluY29taW5nOiBzaGFyZXMsIG91dGdvaW5nOiBbXSB9KTtcblxuICAgICAgICAgIGNvbnN0IGVjZGggPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBlY2RoLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgZGVjcnlwdFN0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICAgIGRlY3J5cHRTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMoZWNkaC54cHJ2KTtcbiAgICAgICAgICBkZWNyeXB0U3R1Yi5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcyhzZWNyZXQpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgc2hhcmVJZHMgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGl0KCdvcGVucyBvbmUgc2Vzc2lvbiBwZXIgcGFzc3BocmFzZSBhbmQgZGVzdHJveXMgdGhlbSBhZnRlciB0aGUgbG9vcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3N0cm9uZy1vdXRlci1wYXNzcGhyYXNlJztcbiAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAncGxhaW50ZXh0LXdhbGxldC1wcnYnO1xuICAgICAgICAgIGNvbnN0IHsgc2hhcmVJZHMgfSA9IGF3YWl0IHN0dWJGb3JTaGFyZXMoMywgZGVjcnlwdGVkV2FsbGV0UHJ2LCB3YWxsZXRQYXNzcGhyYXNlKTtcblxuICAgICAgICAgIGNvbnN0IHJlYWxTZXNzaW9uID0gYXdhaXQgYml0Z28uY3JlYXRlRW5jcnlwdGlvblNlc3Npb24od2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgICAgY29uc3QgZGVzdHJveVNweSA9IHNpbm9uLnNweShyZWFsU2Vzc2lvbiwgJ2Rlc3Ryb3knKTtcbiAgICAgICAgICBjb25zdCBzZXNzaW9uU3R1YiA9IHNpbm9uLnN0dWIoYml0Z28sICdjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbicpLnJlc29sdmVzKHJlYWxTZXNzaW9uKTtcblxuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogc2hhcmVJZHMubWFwKChpZCkgPT4gKHsgd2FsbGV0U2hhcmVJZDogaWQgfSkpLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcywgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSk7XG5cbiAgICAgICAgICBzZXNzaW9uU3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIHNlc3Npb25TdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCh3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgICBkZXN0cm95U3B5LmNhbGxlZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdwcm9kdWNlcyBzdGFuZGFsb25lLWRlY3J5cHRhYmxlIHYyIGVudmVsb3BlcyB3aXRoIHVuaXF1ZSBwZXItZW52ZWxvcGUgaGtkZlNhbHRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnc2Vzc2lvbi1wYXNzcGhyYXNlLTQyJztcbiAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnc2VjcmV0LXdhbGxldC1tYXRlcmlhbCc7XG4gICAgICAgICAgY29uc3QgeyBzaGFyZUlkcyB9ID0gYXdhaXQgc3R1YkZvclNoYXJlcyg0LCBkZWNyeXB0ZWRXYWxsZXRQcnYsIHdhbGxldFBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgbGV0IGNhcHR1cmVkOiB7IGtleXNGb3JXYWxsZXRTaGFyZXM6IEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXSB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgICBjYXB0dXJlZCA9IGJvZHk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkIH0pKSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pO1xuXG4gICAgICAgICAgY29uc3QgZW50cmllcyA9IGNhcHR1cmVkIS5rZXlzRm9yV2FsbGV0U2hhcmVzO1xuICAgICAgICAgIGVudHJpZXMuc2hvdWxkLmhhdmUubGVuZ3RoKDQpO1xuICAgICAgICAgIGNvbnN0IGVudmVsb3BlcyA9IGVudHJpZXMubWFwKChlKSA9PiBKU09OLnBhcnNlKGUuZW5jcnlwdGVkUHJ2IGFzIHN0cmluZykpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBlbnYgb2YgZW52ZWxvcGVzKSB7XG4gICAgICAgICAgICBlbnYuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3YnLCAyKTtcbiAgICAgICAgICAgIGVudi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGtkZlNhbHQnKTtcbiAgICAgICAgICAgIGVudi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2FsdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTYW1lIHNlc3Npb24g4oeSIHNhbWUgQXJnb24yIHNhbHQgYWNyb3NzIGVudmVsb3Blc1xuICAgICAgICAgIGNvbnN0IGFyZ29uU2FsdHMgPSBuZXcgU2V0KGVudmVsb3Blcy5tYXAoKGUpID0+IGUuc2FsdCkpO1xuICAgICAgICAgIGFyZ29uU2FsdHMuc2l6ZS5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgLy8gVW5pcXVlIEhLREYgc2FsdCBwZXIgZW52ZWxvcGUg4oeSIGluZGVwZW5kZW50IEFFUyBrZXlzXG4gICAgICAgICAgY29uc3QgaGtkZlNhbHRzID0gbmV3IFNldChlbnZlbG9wZXMubWFwKChlKSA9PiBlLmhrZGZTYWx0KSk7XG4gICAgICAgICAgaGtkZlNhbHRzLnNpemUuc2hvdWxkLmVxdWFsKDQpO1xuICAgICAgICAgIC8vIENyb3NzLXdhbGxldCBpc29sYXRpb246IGV2ZXJ5IGVudmVsb3BlIGRlY3J5cHRzIGJhY2sgdW5kZXIgdGhlIHNhbWUgcGFzc3BocmFzZVxuICAgICAgICAgIGZvciAoY29uc3QgZW52IG9mIGVudmVsb3Blcykge1xuICAgICAgICAgICAgY29uc3Qgcm91bmRUcmlwID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLCBpbnB1dDogSlNPTi5zdHJpbmdpZnkoZW52KSB9KTtcbiAgICAgICAgICAgIHJvdW5kVHJpcC5zaG91bGQuZXF1YWwoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdvcGVucyBhIHNlY29uZCwgaW5kZXBlbmRlbnQgc2Vzc2lvbiBmb3Igd2ViYXV0aG5JbmZvLnBhc3NwaHJhc2UgYW5kIGJpbmRzIGFkYXRhIHBlciBzaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ291dGVyLXB3JztcbiAgICAgICAgICBjb25zdCB3ZWJhdXRoblBhc3NwaHJhc2UgPSAnd2ViYXV0aG4tcHJmLXB3JztcbiAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnd2FsbGV0LXBydi13ZWJhdXRobi1jYXNlJztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yU2hhcmVzKDIsIGRlY3J5cHRlZFdhbGxldFBydiwgd2FsbGV0UGFzc3BocmFzZSk7XG5cbiAgICAgICAgICBjb25zdCBzZXNzaW9uU3B5ID0gc2lub24uc3B5KGJpdGdvLCAnY3JlYXRlRW5jcnlwdGlvblNlc3Npb24nKTtcbiAgICAgICAgICBsZXQgY2FwdHVyZWQ6IHsga2V5c0ZvcldhbGxldFNoYXJlczogQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdFtdIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgIGNhcHR1cmVkID0gYm9keTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogc2hhcmVJZHMubWFwKChpZCkgPT4gKHsgd2FsbGV0U2hhcmVJZDogaWQgfSkpIH0pO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IHNoYXJlSWRzLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICB3ZWJhdXRobkluZm86IHsgb3RwRGV2aWNlSWQ6ICdkZXYnLCBwcmZTYWx0OiAnc2FsdCcsIHBhc3NwaHJhc2U6IHdlYmF1dGhuUGFzc3BocmFzZSB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc2Vzc2lvblNweS5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICAgIGNvbnN0IHBhc3N3b3JkcyA9IHNlc3Npb25TcHkuZ2V0Q2FsbHMoKS5tYXAoKGMpID0+IGMuYXJnc1swXSk7XG4gICAgICAgICAgcGFzc3dvcmRzLnNob3VsZC5jb250YWluRXFsKHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICAgIHBhc3N3b3Jkcy5zaG91bGQuY29udGFpbkVxbCh3ZWJhdXRoblBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgY29uc3QgZW50cmllcyA9IGNhcHR1cmVkIS5rZXlzRm9yV2FsbGV0U2hhcmVzO1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgd2ViRW52ID0gSlNPTi5wYXJzZShlbnRyaWVzW2ldLndlYmF1dGhuSW5mbyEuZW5jcnlwdGVkUHJ2IGFzIHN0cmluZyk7XG4gICAgICAgICAgICB3ZWJFbnYuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkYXRhJywgYGVudC0ke2l9YCk7XG4gICAgICAgICAgICBjb25zdCBydCA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBwYXNzd29yZDogd2ViYXV0aG5QYXNzcGhyYXNlLCBpbnB1dDogSlNPTi5zdHJpbmdpZnkod2ViRW52KSB9KTtcbiAgICAgICAgICAgIHJ0LnNob3VsZC5lcXVhbChkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2Rlc3Ryb3lzIHRoZSBzZXNzaW9uIGV2ZW4gd2hlbiB0aGUgYWNjZXB0IEFQSSBjYWxsIGZhaWxzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAncHctZXJyb3InO1xuICAgICAgICAgIGNvbnN0IGRlY3J5cHRlZFdhbGxldFBydiA9ICd4JztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yU2hhcmVzKDIsIGRlY3J5cHRlZFdhbGxldFBydiwgd2FsbGV0UGFzc3BocmFzZSk7XG5cbiAgICAgICAgICBjb25zdCByZWFsU2Vzc2lvbiA9IGF3YWl0IGJpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICAgIGNvbnN0IGRlc3Ryb3lTcHkgPSBzaW5vbi5zcHkocmVhbFNlc3Npb24sICdkZXN0cm95Jyk7XG4gICAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2NyZWF0ZUVuY3J5cHRpb25TZXNzaW9uJykucmVzb2x2ZXMocmVhbFNlc3Npb24pO1xuXG4gICAgICAgICAgbm9jayhiZ1VybCkucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKS5yZXBseSg1MDAsIHsgZXJyb3I6ICdib29tJyB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pXG4gICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkKCk7XG5cbiAgICAgICAgICBkZXN0cm95U3B5LmNhbGxlZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd0aHJlYWRzIGVuY3J5cHRpb25WZXJzaW9uPTEgaW50byB0aGUgZmFjdG9yeSBzbyB2MSBlbnZlbG9wZXMgYXJlIHByb2R1Y2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAndjEtY2FsbGVyJztcbiAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAnbGVnYWN5JztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yU2hhcmVzKDIsIGRlY3J5cHRlZFdhbGxldFBydiwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblNweSA9IHNpbm9uLnNweShiaXRnbywgJ2NyZWF0ZUVuY3J5cHRpb25TZXNzaW9uJyk7XG5cbiAgICAgICAgICBsZXQgY2FwdHVyZWQ6IHsga2V5c0ZvcldhbGxldFNoYXJlczogQWNjZXB0U2hhcmVPcHRpb25zUmVxdWVzdFtdIH0gfCB1bmRlZmluZWQ7XG4gICAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICAgIGNhcHR1cmVkID0gYm9keTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogc2hhcmVJZHMubWFwKChpZCkgPT4gKHsgd2FsbGV0U2hhcmVJZDogaWQgfSkpIH0pO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IHNoYXJlSWRzLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICBlbmNyeXB0aW9uVmVyc2lvbjogMSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIEZhY3RvcnkgaXMgc3RpbGwgY2FsbGVkIHVuaWZvcm1seSwgYnV0IHdpdGggZW5jcnlwdGlvblZlcnNpb249MVxuICAgICAgICAgIHNlc3Npb25TcHkuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBzZXNzaW9uU3B5LmZpcnN0Q2FsbC5hcmdzWzFdIS5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgICBjb25zdCBlbnRyaWVzID0gY2FwdHVyZWQhLmtleXNGb3JXYWxsZXRTaGFyZXM7XG4gICAgICAgICAgY29uc3QgZW52ZWxvcGVzID0gZW50cmllcy5tYXAoKGUpID0+IEpTT04ucGFyc2UoZS5lbmNyeXB0ZWRQcnYgYXMgc3RyaW5nKSk7XG4gICAgICAgICAgZm9yIChjb25zdCBlbnYgb2YgZW52ZWxvcGVzKSB7XG4gICAgICAgICAgICBlbnYuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdoa2RmU2FsdCcpO1xuICAgICAgICAgICAgZW52LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpdGVyJyk7IC8vIHYxIFNKQ0xcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnYnVsa1VwZGF0ZVdhbGxldFNoYXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG1pc3Npbmcgc2hhcmVzIHBhcmFtZXRlcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe30pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBzaGFyZXMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG5vbi1hcnJheSBzaGFyZXMgcGFyYW1ldGVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7IHNoYXJlczogJ25vdC1hbi1hcnJheScgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHBhcmFtZXRlciBhcnJheTogc2hhcmVzIGJ1dCBmb3VuZCBzdHJpbmcnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG1pc3Npbmcgd2FsbGV0U2hhcmVJZCBpbiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHN0YXR1czogJ2FjY2VwdCcgfV0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTWlzc2luZyB3YWxsZXRTaGFyZUlkIGluIHNoYXJlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBtaXNzaW5nIHN0YXR1cyBpbiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnIH1dIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3Npbmcgc3RhdHVzIGluIHNoYXJlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBpbnZhbGlkIHN0YXR1cyBpbiBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnLCBzdGF0dXM6ICdpbnZhbGlkJyB9XSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHN0YXR1cyBpbiBzaGFyZTogaW52YWxpZC4gTXVzdCBiZSBlaXRoZXIgXCJhY2NlcHRcIiBvciBcInJlamVjdFwiJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBub24tc3RyaW5nIHdhbGxldFNoYXJlSWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAxMjMsIHN0YXR1czogJ2FjY2VwdCcgfV0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHdhbGxldFNoYXJlSWQgdG8gYmUgYSBzdHJpbmcgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igbm9uLXN0cmluZyB1c2VyTG9naW5QYXNzd29yZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLCB1c2VyTG9naW5QYXNzd29yZDogMTIzIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiB1c2VyTG9naW5QYXNzd29yZCBidXQgZm91bmQgbnVtYmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBub24tc3RyaW5nIG5ld1dhbGxldFBhc3NwaHJhc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJzEyMycsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6IDEyMyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogbmV3V2FsbGV0UGFzc3BocmFzZSBidXQgZm91bmQgbnVtYmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhc3NlcnRpb24gZXJyb3IgZm9yIGVtcHR5IHNoYXJlcyBhcnJheScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6IFtdIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ25vIHNoYXJlcyBhcmUgcGFzc2VkJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3Igbm8gdmFsaWQgd2FsbGV0IHNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ2R1bW15V2FsbGV0SWQnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgd2FsbGV0IHNoYXJlIHByb3ZpZGVkOiA2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkMScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGVjZGgga2V5Y2hhaW4gdW5kZWZpbmVkIHdoZW4gYWNjZXB0aW5nIHNoYXJlIHJlcXVpcmluZyBkZWNyeXB0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnZHVtbXlXYWxsZXRJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICBwdWI6ICdwdWInLFxuICAgICAgICAgICAgICAgIHRvUHViS2V5OiAndG9QdWJLZXknLFxuICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICAgIHBhdGg6ICdwYXRoJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIHBydjogJ3ByaXZhdGUga2V5JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgdXBkYXRlIHNoYXJlcyB3aXRoIGJvdGggYWNjZXB0IGFuZCByZWplY3Qgc3RhdHVzZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gdHdvIHNoYXJlc1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMicsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nMicsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MicsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMiddLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW1xuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9LFxuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUyJywgc3RhdHVzOiAncmVqZWN0JyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUyJ10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFyYW1zID0gYnVsa1VwZGF0ZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuaGF2ZS5sZW5ndGhPZigyKTtcblxuICAgICAgICAvLyBTZWNvbmQgcGFyYW0gc2hvdWxkIGJlIGZvciBzaGFyZTIgd2l0aCByZWplY3Qgc3RhdHVzXG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuY29udGFpbkRlZXAoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICdzaGFyZTInLFxuICAgICAgICAgICAgc3RhdHVzOiAncmVqZWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIGluIGJ1bGsgb3BlcmF0aW9ucycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgdXNlckxvZ2luUGFzc3dvcmQgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgbmV3V2FsbGV0UGFzc3BocmFzZSA9ICduZXdfd2FsbGV0X3Bhc3NwaHJhc2VfNDU2JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZFxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgdXNlciBzZXR0aW5ncyBBUEkgY2FsbCAocmVxdWlyZWQgYnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlKVxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvdXNlci9zZXR0aW5ncycpLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICAgIC8vIE1vY2sgZ2V0RUNESEtleWNoYWluIChyZXF1aXJlZCBieSBidWxrVXBkYXRlV2FsbGV0U2hhcmUgd2hlbiB1c2VyTG9naW5QYXNzd29yZCBpcyBwcm92aWRlZClcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiAnZW5jcnlwdGVkWHBydicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldHVwIGZvciB0aGUgYmFzZUNvaW4ua2V5Y2hhaW5zKCkuY3JlYXRlVXNlcktleWNoYWluXG4gICAgICAgIGNvbnN0IHVzZXJLZXljaGFpbiA9IHtcbiAgICAgICAgICBpZDogJ2tleTEnLFxuICAgICAgICAgIHB1YjogJ3B1YktleScsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJpdmF0ZUtleScsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNyZWF0ZVVzZXJLZXljaGFpblN0dWIgPSBzaW5vblxuICAgICAgICAgIC5zdHViKHdhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCksICdjcmVhdGVVc2VyS2V5Y2hhaW4nKVxuICAgICAgICAgIC5yZXNvbHZlcyh1c2VyS2V5Y2hhaW4pO1xuXG4gICAgICAgIC8vIE1vY2sgZGVjcnlwdCBhbmQgc2lnbk1lc3NhZ2VcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcygnZGVjcnlwdGVkUHJpdmF0ZUtleScpO1xuICAgICAgICBzaW5vbi5zdHViKHdhbGxldHMuYmFzZUNvaW4sICdzaWduTWVzc2FnZScpLnJlc29sdmVzKEJ1ZmZlci5mcm9tKCdzaWduYXR1cmUnKSk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0XG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayByZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzIChjYWxsZWQgZm9yIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZCBjYXNlcylcbiAgICAgICAgY29uc3QgcmVzaGFyZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpLnJlc29sdmVzKCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHVzZXJMb2dpblBhc3N3b3JkLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6IG5ld1dhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBjcmVhdGVVc2VyS2V5Y2hhaW4gd2FzIGNhbGxlZCB3aXRoIG5ld1dhbGxldFBhc3NwaHJhc2UgKG5vdCB1c2VyTG9naW5QYXNzd29yZClcbiAgICAgICAgY3JlYXRlVXNlcktleWNoYWluU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNyZWF0ZVVzZXJLZXljaGFpblN0dWIuY2FsbGVkV2l0aChuZXdXYWxsZXRQYXNzcGhyYXNlKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAvLyBWZXJpZnkgcmVzaGFyZSB3YXMgY2FsbGVkIGZvciBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgY2FzZVxuICAgICAgICByZXNoYXJlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3BlY2lhbCBvdmVycmlkZSBjYXNlcyBhbmQgcmVzaGFyZSB3aXRoIHNwZW5kZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGgga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXR1cCBmb3IgdGhlIGJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZVVzZXJLZXljaGFpblxuICAgICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgICAgaWQ6ICdrZXkxJyxcbiAgICAgICAgICBwdWI6ICdwdWJLZXknLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFByaXZhdGVLZXknLFxuICAgICAgICB9O1xuICAgICAgICBzaW5vbi5zdHViKG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCksICdjcmVhdGVVc2VyS2V5Y2hhaW4nKS5yZXNvbHZlcyh1c2VyS2V5Y2hhaW4pO1xuXG4gICAgICAgIC8vIE1vY2sgZGVjcnlwdCBhbmQgc2lnbk1lc3NhZ2VcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcygnZGVjcnlwdGVkUHJpdmF0ZUtleScpO1xuICAgICAgICBzaW5vbi5zdHViKG9mY1dhbGxldHMuYmFzZUNvaW4sICdzaWduTWVzc2FnZScpLnJlc29sdmVzKEJ1ZmZlci5mcm9tKCdzaWduYXR1cmUnKSk7XG5cbiAgICAgICAgLy8gTW9jayBnZXRFQ0RIS2V5Y2hhaW5cbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiAnZW5jcnlwdGVkWHBydicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVyc1xuICAgICAgICBjb25zdCByZXNoYXJlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdyZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzJykucmVzb2x2ZXMoKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvZmNXYWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoZSByZXN1bHRcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICAvLyBWZXJpZnkgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIHJlc2hhcmVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgcmVzaGFyZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmVxdWFsKCd3YWxsZXQxJyk7XG4gICAgICAgIHJlc2hhcmVTdHViLmZpcnN0Q2FsbC5hcmdzWzFdLnNob3VsZC5lcXVhbCh3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBzaGFyZXMgd2l0aCBubyBrZXljaGFpbiB0byBkZWNyeXB0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCBubyBrZXljaGFpblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3J10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0IHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IHBhcmFtZXRlcnNcbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBjb25zdCB1cGRhdGVQYXJhbXMgPSBidWxrVXBkYXRlU3R1Yi5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5oYXZlLmxlbmd0aE9mKDEpO1xuXG4gICAgICAgIC8vIFBhcmFtIHNob3VsZCBiZSBmb3Igc2hhcmUxIHdpdGggYWNjZXB0IHN0YXR1cyBhbmQgbm8gYWRkaXRpb25hbCBmaWVsZHNcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5jb250YWluRGVlcChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsXG4gICAgICAgICAgICBzdGF0dXM6ICdhY2NlcHQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHNoYXJlcyB3aXRoIGtleWNoYWluIHJlcXVpcmluZyBkZWNyeXB0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcblxuICAgICAgICAvLyBDcmVhdGUgdGVzdCBrZXljaGFpbnNcbiAgICAgICAgY29uc3QgZnJvbUtleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMWRlYWRiZWVmMDFkZWFkYmVlZjAxZGVhZGJlZWYwMScsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcblxuICAgICAgICBjb25zdCBmcm9tUHViS2V5ID0gZnJvbUtleWNoYWluLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHRvUHViS2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGVuY3J5cHRlZCBwcml2YXRlIGtleVxuICAgICAgICBjb25zdCBvcmlnaW5hbFByaXZLZXkgPSAnb3JpZ2luYWxQcml2YXRlS2V5JztcbiAgICAgICAgY29uc3Qgc2hhcmVkU2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGZyb21LZXljaGFpbiwgQnVmZmVyLmZyb20odG9QdWJLZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiBzaGFyZWRTZWNyZXQsXG4gICAgICAgICAgaW5wdXQ6IG9yaWdpbmFsUHJpdktleSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCBrZXljaGFpblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgcHViOiB0b1B1YktleSxcbiAgICAgICAgICAgICAgICB0b1B1YktleTogdG9QdWJLZXksXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogZnJvbVB1YktleSxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBnZXRFQ0RIS2V5Y2hhaW5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXR1cCBkZWNyeXB0IHN0dWJzXG4gICAgICAgIGNvbnN0IGRlY3J5cHRTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgZGVjcnlwdFN0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhteUVjZGhLZXljaGFpbi54cHJ2KTsgLy8gRm9yIHNoYXJpbmcga2V5Y2hhaW5cbiAgICAgICAgZGVjcnlwdFN0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMob3JpZ2luYWxQcml2S2V5KTsgLy8gRm9yIHdhbGxldCBrZXljaGFpblxuXG4gICAgICAgIC8vIE1vY2sgZ2V0U2hhcmVkU2VjcmV0XG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKHNoYXJlZFNlY3JldCkpO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6ICduZXdQYXNzcGhyYXNlJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoZSByZXN1bHRcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFyYW1zID0gYnVsa1VwZGF0ZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuaGF2ZS5sZW5ndGhPZigxKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRTaGFyZUlkJywgJ3NoYXJlMScpO1xuICAgICAgICB1cGRhdGVQYXJhbXNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0YXR1cycsICdhY2NlcHQnKTtcbiAgICAgICAgLy8gZW5jcnlwdGVkUHJ2IGlzIG5vdyBlbWl0dGVkIGJ5IHRoZSBzZXNzaW9uOyB2ZXJpZnkgaXQncyBhIHJlYWwgdjIgZW52ZWxvcGUgdGhhdFxuICAgICAgICAvLyBkZWNyeXB0cyBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwcnYgdW5kZXIgbmV3UGFzc3BocmFzZS5cbiAgICAgICAgY29uc3QgZW52ZWxvcGUgPSBKU09OLnBhcnNlKHVwZGF0ZVBhcmFtc1swXS5lbmNyeXB0ZWRQcnYgYXMgc3RyaW5nKTtcbiAgICAgICAgZW52ZWxvcGUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3YnLCAyKTtcbiAgICAgICAgZW52ZWxvcGUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hrZGZTYWx0Jyk7XG4gICAgICAgIC8vIFNlc3Npb24gZW5jcnlwdCBieXBhc3NlcyBiaXRnby5kZWNyeXB0J3Mgc3R1YiAtLSByZXN0b3JlIHRoZW4gZGVjcnlwdCB0aGUgZW52ZWxvcGVcbiAgICAgICAgZGVjcnlwdFN0dWIucmVzdG9yZSgpO1xuICAgICAgICBjb25zdCBydCA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBwYXNzd29yZDogJ25ld1Bhc3NwaHJhc2UnLCBpbnB1dDogdXBkYXRlUGFyYW1zWzBdLmVuY3J5cHRlZFBydiBhcyBzdHJpbmcgfSk7XG4gICAgICAgIHJ0LnNob3VsZC5lcXVhbChvcmlnaW5hbFByaXZLZXkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHJlamVjdGVkIHByb21pc2VzIGFuZCBhZGQgdGhlbSB0byB3YWxsZXRTaGFyZVVwZGF0ZUVycm9ycycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiB0d28gc2hhcmVzXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MScsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUyJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcyJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQyJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTMnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZzMnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDMnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdHViIHByb2Nlc3NBY2NlcHRTaGFyZSB0byB0aHJvdyBhbiBlcnJvciBmb3Igc2hhcmUyXG4gICAgICAgIC8vIFVzaW5nICdhcyBhbnknIHRvIGJ5cGFzcyBUeXBlU2NyaXB0J3MgcHJpdmF0ZSBtZXRob2QgcmVzdHJpY3Rpb25cbiAgICAgICAgY29uc3QgcHJvY2Vzc0FjY2VwdFNoYXJlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUgYXMgYW55LCAncHJvY2Vzc0FjY2VwdFNoYXJlJyk7XG4gICAgICAgIHByb2Nlc3NBY2NlcHRTaGFyZVN0dWJcbiAgICAgICAgICAud2l0aEFyZ3MoJ3NoYXJlMScsIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSlcbiAgICAgICAgICAucmVzb2x2ZXMoW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0pO1xuICAgICAgICBwcm9jZXNzQWNjZXB0U2hhcmVTdHViXG4gICAgICAgICAgLndpdGhBcmdzKCdzaGFyZTInLCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnkpXG4gICAgICAgICAgLnJlamVjdHMobmV3IEVycm9yKCdGYWlsZWQgdG8gcHJvY2VzcyBzaGFyZTInKSk7XG4gICAgICAgIHByb2Nlc3NBY2NlcHRTaGFyZVN0dWJcbiAgICAgICAgICAud2l0aEFyZ3MoJ3NoYXJlMycsIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSlcbiAgICAgICAgICAucmVzb2x2ZXMoW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMycsIHN0YXR1czogJ2FjY2VwdCcgfV0pO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB0byByZXR1cm4gYSByZXNwb25zZVxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMScsICdzaGFyZTMnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLCAvLyBFbXB0eSBhcnJheSB0aGF0IHNob3VsZCBiZSBwb3B1bGF0ZWRcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW1xuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9LFxuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUyJywgc3RhdHVzOiAnYWNjZXB0JyB9LFxuICAgICAgICAgICAgeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUzJywgc3RhdHVzOiAnYWNjZXB0JyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0IHdhcyBjYWxsZWQgd2l0aCBvbmx5IHRoZSBzdWNjZXNzZnVsIHNoYXJlXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFyYW1zID0gYnVsa1VwZGF0ZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuaGF2ZS5sZW5ndGhPZigyKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzBdLndhbGxldFNoYXJlSWQuc2hvdWxkLmVxdWFsKCdzaGFyZTEnKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzBdLnN0YXR1cy5zaG91bGQuZXF1YWwoJ2FjY2VwdCcpO1xuICAgICAgICB1cGRhdGVQYXJhbXNbMV0ud2FsbGV0U2hhcmVJZC5zaG91bGQuZXF1YWwoJ3NoYXJlMycpO1xuICAgICAgICB1cGRhdGVQYXJhbXNbMV0uc3RhdHVzLnNob3VsZC5lcXVhbCgnYWNjZXB0Jyk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoZSByZXN1bHQgY29udGFpbnMgdGhlIGVycm9yIGluZm9ybWF0aW9uXG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnMnKTtcbiAgICAgICAgcmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzLnNob3VsZC5iZS5hbi5BcnJheSgpO1xuICAgICAgICByZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMSk7XG4gICAgICAgIHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9yc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0U2hhcmVJZCcsICdzaGFyZTInKTtcbiAgICAgICAgcmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWFzb24nLCAnRmFpbGVkIHRvIHByb2Nlc3Mgc2hhcmUyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgc2hhcmUgd2l0aCB2Mi1lbmNyeXB0ZWQgRUNESCBrZXljaGFpbiBhbmQgd2FsbGV0IHBydicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG5cbiAgICAgICAgY29uc3QgZnJvbUtleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMWRlYWRiZWVmMDFkZWFkYmVlZjAxZGVhZGJlZWYwMScsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgdG9QdWJLZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgZnJvbVB1YktleSA9IGZyb21LZXljaGFpbi5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsUHJpdktleSA9ICdvcmlnaW5hbFByaXZhdGVLZXknO1xuICAgICAgICBjb25zdCBzaGFyZWRTZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZnJvbUtleWNoYWluLCBCdWZmZXIuZnJvbSh0b1B1YktleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2hhcmVkU2VjcmV0LCBpbnB1dDogb3JpZ2luYWxQcml2S2V5IH0pO1xuXG4gICAgICAgIC8vIEJvdGggdGhlIEVDREgga2V5Y2hhaW4gYW5kIHNoYXJlIHBydiBhcmUgdjItZW5jcnlwdGVkIGluIHRoaXMgc2NlbmFyaW9cbiAgICAgICAgY29uc3QgdjJFbmNyeXB0ZWRYcHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpdjogJ2FhYmJjYycsIGN0OiAnZGRlZWZmJywgYWRhdGE6ICcwMCcgfSk7XG5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjogeyBwdWI6IHRvUHViS2V5LCB0b1B1YktleSwgZnJvbVB1YktleSwgZW5jcnlwdGVkUHJ2LCBwYXRoIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoeyBlbmNyeXB0ZWRYcHJ2OiB2MkVuY3J5cHRlZFhwcnYgfSk7XG5cbiAgICAgICAgLy8gZGVjcnlwdCBoYW5kbGVzIHYyIHRyYW5zcGFyZW50bHk7IHN0dWIgdG8gcmV0dXJuIGV4cGVjdGVkIHZhbHVlc1xuICAgICAgICBjb25zdCBkZWNyeXB0QXN5bmNTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKG15RWNkaEtleWNoYWluLnhwcnYpOyAvLyBFQ0RIIGtleWNoYWluXG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMob3JpZ2luYWxQcml2S2V5KTsgLy8gd2FsbGV0IHNoYXJlIHBydlxuXG4gICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKHNoYXJlZFNlY3JldCkpO1xuXG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgbmV3V2FsbGV0UGFzc3BocmFzZTogJ25ld1Bhc3NwaHJhc2UnLFxuICAgICAgICB9KTtcblxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEJvdGggZGVjcnlwdCBjYWxscyBtdXN0IGhhdmUgZ29uZSB0aHJvdWdoIGRlY3J5cHRcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGRlY3J5cHRBc3luY1N0dWIuY2FsbENvdW50LCAyKTtcbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAvLyBFbmNyeXB0aW9uIG5vdyBnb2VzIHRocm91Z2ggdGhlIHNlc3Npb247IGFzc2VydCBhIHJlYWwgdjIgZW52ZWxvcGUgcm91bmQtdHJpcHNcbiAgICAgICAgY29uc3QgdXBkYXRlUGFyYW1zID0gYnVsa1VwZGF0ZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZSh1cGRhdGVQYXJhbXNbMF0uZW5jcnlwdGVkUHJ2IGFzIHN0cmluZyk7XG4gICAgICAgIGVudmVsb3BlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd2JywgMik7XG4gICAgICAgIGVudmVsb3BlLnNob3VsZC5oYXZlLnByb3BlcnR5KCdoa2RmU2FsdCcpO1xuICAgICAgICBkZWNyeXB0QXN5bmNTdHViLnJlc3RvcmUoKTtcbiAgICAgICAgY29uc3QgcnQgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgcGFzc3dvcmQ6ICduZXdQYXNzcGhyYXNlJywgaW5wdXQ6IHVwZGF0ZVBhcmFtc1swXS5lbmNyeXB0ZWRQcnYgYXMgc3RyaW5nIH0pO1xuICAgICAgICBydC5zaG91bGQuZXF1YWwob3JpZ2luYWxQcml2S2V5KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnRW5jcnlwdGlvblNlc3Npb24gKEhLREYpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBCdWlsZCBhIHNldCBvZiBhY2NlcHQtc3RhdHVzIHNoYXJlcyB3aXRoIHJlYWxpc3RpYyBFQ0RILWVuY3J5cHRlZCBrZXljaGFpbnMgc29cbiAgICAgICAgLy8gYnVsa1VwZGF0ZVdhbGxldFNoYXJlIHdhbGtzIHRoZSBzdGFuZGFyZCByZS1lbmNyeXB0IHBhdGggZm9yIGV2ZXJ5IHNoYXJlLlxuICAgICAgICBhc3luYyBmdW5jdGlvbiBzdHViRm9yQWNjZXB0U2hhcmVzKHNoYXJlQ291bnQ6IG51bWJlciwgZGVjcnlwdGVkV2FsbGV0UHJ2OiBzdHJpbmcsIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZykge1xuICAgICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAzZGVhZGJlZWYwM2RlYWRiZWVmMDNkZWFkYmVlZjAzJywgJ2hleCcpKTtcbiAgICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICAgIGNvbnN0IHNlbmRlckVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogZGVjcnlwdGVkV2FsbGV0UHJ2IH0pO1xuXG4gICAgICAgICAgY29uc3Qgc2hhcmVJZHMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBzaGFyZUNvdW50IH0sIChfLCBpKSA9PiBgYnVsay11cGRhdGUtc2hhcmUtJHtpfWApO1xuICAgICAgICAgIGNvbnN0IHNoYXJlcyA9IHNoYXJlSWRzLm1hcCgoaWQsIGluZGV4KSA9PiAoe1xuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICB3YWxsZXRMYWJlbDogYHcke2luZGV4fWAsXG4gICAgICAgICAgICBmcm9tVXNlcjogJ2Zyb20nLFxuICAgICAgICAgICAgdG9Vc2VyOiAndG8nLFxuICAgICAgICAgICAgd2FsbGV0OiBgdyR7aW5kZXh9YCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScgYXMgY29uc3QsXG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IHNlbmRlckVuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pKTtcblxuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7IGluY29taW5nOiBzaGFyZXMsIG91dGdvaW5nOiBbXSB9KTtcblxuICAgICAgICAgIGNvbnN0IGVjZGggPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBlY2RoLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgZGVjcnlwdFN0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICAgIGRlY3J5cHRTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMoZWNkaC54cHJ2KTtcbiAgICAgICAgICBkZWNyeXB0U3R1Yi5yZXNvbHZlcyhkZWNyeXB0ZWRXYWxsZXRQcnYpO1xuICAgICAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXR1cm5zKEJ1ZmZlci5mcm9tKHNlY3JldCkpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgc2hhcmVJZHMgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGl0KCdvcGVucyBvbmUgc2Vzc2lvbiBvdmVyIHRoZSBvdXRlciBwYXNzcGhyYXNlIGFuZCBkZXN0cm95cyBpdCBhZnRlciB0aGUgbG9vcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3VwZGF0ZS1wYXNzcGhyYXNlJztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yQWNjZXB0U2hhcmVzKDMsICdwbGFpbnRleHQtcHJ2Jywgd2FsbGV0UGFzc3BocmFzZSk7XG5cbiAgICAgICAgICBjb25zdCByZWFsU2Vzc2lvbiA9IGF3YWl0IGJpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICAgIGNvbnN0IGRlc3Ryb3lTcHkgPSBzaW5vbi5zcHkocmVhbFNlc3Npb24sICdkZXN0cm95Jyk7XG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblN0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnY3JlYXRlRW5jcnlwdGlvblNlc3Npb24nKS5yZXNvbHZlcyhyZWFsU2Vzc2lvbik7XG5cbiAgICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBzaGFyZUlkcyxcbiAgICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogc2hhcmVJZHMubWFwKChpZCkgPT4gKHsgd2FsbGV0U2hhcmVJZDogaWQsIHN0YXR1czogJ2FjY2VwdCcgYXMgY29uc3QgfSkpLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBzZXNzaW9uU3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIHNlc3Npb25TdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCh3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgICBkZXN0cm95U3B5LmNhbGxlZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd0aHJlYWRzIHRoZSBzZXNzaW9uIGludG8gcHJvY2Vzc0FjY2VwdFNoYXJlIHNvIGVudmVsb3BlcyBjYXJyeSB0aGUgc2FtZSBhcmdvbjIgc2FsdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3NoYXJlZC1hcmdvbjItc2FsdC10ZXN0JztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yQWNjZXB0U2hhcmVzKDQsICdwbGFpbnRleHQtcHJ2Jywgd2FsbGV0UGFzc3BocmFzZSk7XG5cbiAgICAgICAgICBsZXQgY2FwdHVyZWRTaGFyZXM6IEJ1bGtVcGRhdGVXYWxsZXRTaGFyZU9wdGlvbnNSZXF1ZXN0W10gPSBbXTtcbiAgICAgICAgICBzaW5vblxuICAgICAgICAgICAgLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JylcbiAgICAgICAgICAgIC5jYWxsc0Zha2UoYXN5bmMgKHNoYXJlczogQnVsa1VwZGF0ZVdhbGxldFNoYXJlT3B0aW9uc1JlcXVlc3RbXSkgPT4ge1xuICAgICAgICAgICAgICBjYXB0dXJlZFNoYXJlcyA9IHNoYXJlcztcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHNoYXJlSWRzLCByZWplY3RlZFdhbGxldFNoYXJlczogW10sIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSB9O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgICBzaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkLCBzdGF0dXM6ICdhY2NlcHQnIGFzIGNvbnN0IH0pKSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2FwdHVyZWRTaGFyZXMuc2hvdWxkLmhhdmUubGVuZ3RoKDQpO1xuICAgICAgICAgIGNvbnN0IGVudmVsb3BlcyA9IGNhcHR1cmVkU2hhcmVzLm1hcCgocykgPT4gSlNPTi5wYXJzZShzLmVuY3J5cHRlZFBydiBhcyBzdHJpbmcpKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGVudiBvZiBlbnZlbG9wZXMpIHtcbiAgICAgICAgICAgIGVudi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndicsIDIpO1xuICAgICAgICAgICAgZW52LnNob3VsZC5oYXZlLnByb3BlcnR5KCdoa2RmU2FsdCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhcmdvblNhbHRzID0gbmV3IFNldChlbnZlbG9wZXMubWFwKChlKSA9PiBlLnNhbHQpKTtcbiAgICAgICAgICBhcmdvblNhbHRzLnNpemUuc2hvdWxkLmVxdWFsKDEpOyAvLyBvbmUgc2Vzc2lvbiAtPiBvbmUgYXJnb24yIHNhbHRcbiAgICAgICAgICBjb25zdCBoa2RmU2FsdHMgPSBuZXcgU2V0KGVudmVsb3Blcy5tYXAoKGUpID0+IGUuaGtkZlNhbHQpKTtcbiAgICAgICAgICBoa2RmU2FsdHMuc2l6ZS5zaG91bGQuZXF1YWwoNCk7IC8vIHBlci1lbnZlbG9wZSBrZXkgaXNvbGF0aW9uXG4gICAgICAgICAgLy8gQ3Jvc3MtZW52ZWxvcGUgcm91bmQtdHJpcDogZWFjaCBlbnZlbG9wZSBkZWNyeXB0cyB1bmRlciB0aGUgc2FtZSBwYXNzcGhyYXNlXG4gICAgICAgICAgZm9yIChjb25zdCBlbnYgb2YgZW52ZWxvcGVzKSB7XG4gICAgICAgICAgICBjb25zdCBydCA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSwgaW5wdXQ6IEpTT04uc3RyaW5naWZ5KGVudikgfSk7XG4gICAgICAgICAgICBydC5zaG91bGQuZXF1YWwoJ3BsYWludGV4dC1wcnYnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdib3VuZHMgY29uY3VycmVudCBwcm9jZXNzQWNjZXB0U2hhcmUgY2FsbHMgYXQgQlVMS19TSEFSRV9CQVRDSF9TSVpFICgxNiknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiYXRjaC1jYXAtcHcnO1xuICAgICAgICAgIGNvbnN0IHsgc2hhcmVJZHMgfSA9IGF3YWl0IHN0dWJGb3JBY2NlcHRTaGFyZXMoMjAsICdwbGFpbnRleHQtcHJ2Jywgd2FsbGV0UGFzc3BocmFzZSk7XG5cbiAgICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBzaGFyZUlkcyxcbiAgICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIFRyYWNrIGNvbmN1cnJlbnQgaW4tZmxpZ2h0IHByb2Nlc3NBY2NlcHRTaGFyZSBpbnZvY2F0aW9ucy4gVGhlIGJhdGNoaW5nIGluXG4gICAgICAgICAgLy8gYnVsa1VwZGF0ZVdhbGxldFNoYXJlIHNob3VsZCBjYXAgdGhpcyBhdCBCVUxLX1NIQVJFX0JBVENIX1NJWkUgKDE2KS5cbiAgICAgICAgICBsZXQgaW5GbGlnaHQgPSAwO1xuICAgICAgICAgIGxldCBtYXhJbkZsaWdodCA9IDA7XG4gICAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSBhcyBhbnksICdwcm9jZXNzQWNjZXB0U2hhcmUnKS5jYWxsc0Zha2UoYXN5bmMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVJZCA9IGFyZ3NbMF0gYXMgc3RyaW5nO1xuICAgICAgICAgICAgaW5GbGlnaHQrKztcbiAgICAgICAgICAgIG1heEluRmxpZ2h0ID0gTWF0aC5tYXgobWF4SW5GbGlnaHQsIGluRmxpZ2h0KTtcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUpKTtcbiAgICAgICAgICAgIGluRmxpZ2h0LS07XG4gICAgICAgICAgICByZXR1cm4gW3sgd2FsbGV0U2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyBhcyBjb25zdCB9XTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogc2hhcmVJZHMubWFwKChpZCkgPT4gKHsgd2FsbGV0U2hhcmVJZDogaWQsIHN0YXR1czogJ2FjY2VwdCcgYXMgY29uc3QgfSkpLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBtYXhJbkZsaWdodC5zaG91bGQuYmUubGVzc1RoYW5PckVxdWFsKDE2KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ2RvZXMgbm90IG9wZW4gYSBzZXNzaW9uIHdoZW4gdGhlIGJ1bGsgY29udGFpbnMgb25seSByZWplY3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyZWplY3QtMScsXG4gICAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICAgIHdhbGxldExhYmVsOiAneCcsXG4gICAgICAgICAgICAgICAgZnJvbVVzZXI6ICdhJyxcbiAgICAgICAgICAgICAgICB0b1VzZXI6ICdiJyxcbiAgICAgICAgICAgICAgICB3YWxsZXQ6ICd3JyxcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3J10sXG4gICAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHNlc3Npb25TdHViID0gc2lub24uc3R1YihiaXRnbywgJ2NyZWF0ZUVuY3J5cHRpb25TZXNzaW9uJyk7XG4gICAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogWydyZWplY3QtMSddLFxuICAgICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAncmVqZWN0LTEnLCBzdGF0dXM6ICdyZWplY3QnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdpcnJlbGV2YW50JyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHNlc3Npb25TdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd0aHJlYWRzIHRoZSBzZXNzaW9uIHRocm91Z2ggY3JlYXRlVXNlcktleWNoYWluIGluIHRoZSBzcGVjaWFsIG92ZXJyaWRlIHBhdGgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdvdmVycmlkZS1wdyc7XG4gICAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICdvdmVycmlkZS1zaGFyZS0xJztcbiAgICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICdvdmVycmlkZS13YWxsZXQnO1xuXG4gICAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3gnLFxuICAgICAgICAgICAgICAgIGZyb21Vc2VyOiAnYScsXG4gICAgICAgICAgICAgICAgdG9Vc2VyOiAnYicsXG4gICAgICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICAgIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgICAvLyBTaG9ydC1jaXJjdWl0IGNyZWF0ZVVzZXJLZXljaGFpbiBzbyB0aGUgdGVzdCBkb2Vzbid0IGhpdCB0aGUgL2tleSBBUEkgZGFuY2U7IHRoZVxuICAgICAgICAgIC8vIHBvaW50IG9mIHRoaXMgdGVzdCBpcyB2ZXJpZnlpbmcgdGhlIHNlc3Npb24gYXJndW1lbnQgdGhyZWFkaW5nLCBub3RoaW5nIG1vcmUuXG4gICAgICAgICAgY29uc3QgY3JlYXRlVXNlcktleWNoYWluU3R1YiA9IHNpbm9uLnN0dWIob2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKSwgJ2NyZWF0ZVVzZXJLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICAgIGlkOiAnbmV3LWtleWNoYWluLWlkJyxcbiAgICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ3N0dWJiZWQtZW5jcnlwdGVkLXBydicsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gc3BlY2lhbE92ZXJyaWRlQ2FzZSBwdWxscyB0aGUgc2hhcmluZyBrZXljaGFpbiB1cCBmcm9udCwgc28gc3R1YiBpdC5cbiAgICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoeyBlbmNyeXB0ZWRYcHJ2OiAnc3R1YmJlZC1lbmNyeXB0ZWQteHBydicgfSk7XG4gICAgICAgICAgc2lub24uc3R1YihvZmNXYWxsZXRzLmJhc2VDb2luLCAnc2lnbk1lc3NhZ2UnKS5yZXNvbHZlcyhCdWZmZXIuZnJvbSgnc2lnbmF0dXJlLWJ5dGVzJykpO1xuICAgICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0JykucmVzb2x2ZXModGVzdEtleWNoYWluLnBydik7XG4gICAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogW3NoYXJlSWRdLFxuICAgICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdyZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzJykucmVzb2x2ZXMoKTtcblxuICAgICAgICAgIGF3YWl0IG9mY1dhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY3JlYXRlVXNlcktleWNoYWluU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgICAvLyAzcmQgcG9zaXRpb25hbCBhcmcgaXMgdGhlIHNlc3Npb25cbiAgICAgICAgICBjb25zdCBzZXNzaW9uQXJnID0gY3JlYXRlVXNlcktleWNoYWluU3R1Yi5maXJzdENhbGwuYXJnc1syXTtcbiAgICAgICAgICBzaG91bGQuZXhpc3Qoc2Vzc2lvbkFyZyk7XG4gICAgICAgICAgKHR5cGVvZiBzZXNzaW9uQXJnIS5lbmNyeXB0KS5zaG91bGQuZXF1YWwoJ2Z1bmN0aW9uJyk7XG4gICAgICAgICAgKHR5cGVvZiBzZXNzaW9uQXJnIS5kZXN0cm95KS5zaG91bGQuZXF1YWwoJ2Z1bmN0aW9uJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gQnVpbGQgYSBtb2NrIHdhbGxldCB3aXRoIE4gc3BlbmRlciB1c2VycyBvbiB0aGUgc2FtZSBlbnRlcnByaXNlLlxuICAgICAgZnVuY3Rpb24gc3R1YkZvclJlc2hhcmUoc3BlbmRlckNvdW50OiBudW1iZXIsIHdhbGxldElkOiBzdHJpbmcsIGVudGVycHJpc2U6IHN0cmluZykge1xuICAgICAgICBjb25zdCB1c2VycyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHNwZW5kZXJDb3VudCB9LCAoXywgaSkgPT4gKHtcbiAgICAgICAgICB1c2VyOiBgc3BlbmRlci0ke2l9YCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgIH0pKTtcblxuICAgICAgICBjb25zdCB3YWxsZXRPYmogPSB7XG4gICAgICAgICAgaWQ6IHdhbGxldElkLFxuICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICBlbnRlcnByaXNlLFxuICAgICAgICAgIHVzZXJzLFxuICAgICAgICAgIGtleXM6IFsndXNlcktleUlkJywgJ2JhY2t1cEtleUlkJywgJ2JpdGdvS2V5SWQnXSxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyB3YWxsZXRzLmdldCh3YWxsZXRJZCkgLT4gV2FsbGV0IHdyYXBwaW5nIHdhbGxldE9ialxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnZ2V0JykucmVzb2x2ZXMobmV3IFdhbGxldChiaXRnbywgYml0Z28uY29pbigndHNvbCcpLCB3YWxsZXRPYmopKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvZW50ZXJwcmlzZS8ke2VudGVycHJpc2V9L3VzZXJgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFkbWluVXNlcnM6IFtdLFxuICAgICAgICAgICAgbm9uQWRtaW5Vc2VyczogdXNlcnMubWFwKCh1LCBpKSA9PiAoeyBpZDogdS51c2VyLCBlbWFpbDogeyBlbWFpbDogYHNwZW5kZXItJHtpfUBleGFtcGxlLmNvbWAgfSB9KSksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHsgd2FsbGV0T2JqLCB1c2VycyB9O1xuICAgICAgfVxuXG4gICAgICBpdCgnZGVjcnlwdHMgdGhlIHdhbGxldCBrZXljaGFpbiBvbmNlIGFuZCB0aHJlYWRzIGl0IGludG8gZXZlcnkgc2hhcmVXYWxsZXQgY2FsbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAncmVzaGFyZS13YWxsZXQtMSc7XG4gICAgICAgIGNvbnN0IGVudGVycHJpc2UgPSAnZW50LTEnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAnc2hhcmVkLXBhc3NwaHJhc2UnO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRLZXljaGFpbiA9IHsgcHJ2OiAncGxhaW50ZXh0LXBydicsIHB1YjogJ3dhbGxldC1wdWInIH07XG5cbiAgICAgICAgY29uc3QgeyB1c2VycyB9ID0gc3R1YkZvclJlc2hhcmUoMywgd2FsbGV0SWQsIGVudGVycHJpc2UpO1xuXG4gICAgICAgIC8vIGdldERlY3J5cHRlZEtleWNoYWluRm9yU2hhcmluZyBpcyB3aGF0IHJ1bnMgQXJnb24yaWQgb24gdGhlIHdhbGxldCdzIGVuY3J5cHRlZFBydi5cbiAgICAgICAgLy8gQXNzZXJ0IGl0IGZpcmVzIGV4YWN0bHkgb25jZSByZWdhcmRsZXNzIG9mIHNwZW5kZXIgY291bnQuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRTdHViID0gc2lub24uc3R1YihXYWxsZXQucHJvdG90eXBlLCAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nJykucmVzb2x2ZXMoZGVjcnlwdGVkS2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IHNoYXJlV2FsbGV0U3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0JykucmVzb2x2ZXMoeyBzaGFyZWQ6IHRydWUgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0cy5yZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzKHdhbGxldElkLCB1c2VyUGFzc3dvcmQpO1xuXG4gICAgICAgIGRlY3J5cHRTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIGRlY3J5cHRTdHViLmZpcnN0Q2FsbC5hcmdzWzBdIS5zaG91bGQuZXF1YWwodXNlclBhc3N3b3JkKTtcblxuICAgICAgICAvLyBzaGFyZVdhbGxldCBjYWxsZWQgb25jZSBwZXIgc3BlbmRlciwgZWFjaCB3aXRoIGRlY3J5cHRlZEtleWNoYWluIHRocmVhZGVkIGluXG4gICAgICAgIHNoYXJlV2FsbGV0U3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKHVzZXJzLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdXNlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBjYWxsID0gc2hhcmVXYWxsZXRTdHViLmdldENhbGwoaSk7XG4gICAgICAgICAgY29uc3Qgc2hhcmVBcmcgPSBjYWxsLmFyZ3NbMF0hO1xuICAgICAgICAgIHNoYXJlQXJnLnNob3VsZC5oYXZlLnByb3BlcnR5KCdkZWNyeXB0ZWRLZXljaGFpbicpLmVxbChkZWNyeXB0ZWRLZXljaGFpbik7XG4gICAgICAgICAgc2hhcmVBcmcuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFBhc3NwaHJhc2UnLCB1c2VyUGFzc3dvcmQpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3J1bnMgc2hhcmVXYWxsZXQgY2FsbHMgc2VxdWVudGlhbGx5IHNvIHBlci1yZWNpcGllbnQgQXJnb24yaWQgaXMgYm91bmRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAncmVzaGFyZS13YWxsZXQtc2VxJztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZSA9ICdlbnQtMic7XG4gICAgICAgIHN0dWJGb3JSZXNoYXJlKDUsIHdhbGxldElkLCBlbnRlcnByaXNlKTtcblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldC5wcm90b3R5cGUsICdnZXREZWNyeXB0ZWRLZXljaGFpbkZvclNoYXJpbmcnKS5yZXNvbHZlcyh7IHBydjogJ3AnLCBwdWI6ICdxJyB9KTtcblxuICAgICAgICAvLyBUcmFjayBjb25jdXJyZW50IGluLWZsaWdodCBzaGFyZVdhbGxldCBjYWxscy4gU2VxdWVudGlhbCAtPiBtYXggY29uY3VycmVudCBpcyAxLlxuICAgICAgICBsZXQgaW5GbGlnaHQgPSAwO1xuICAgICAgICBsZXQgbWF4SW5GbGlnaHQgPSAwO1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaGFyZVdhbGxldCcpLmNhbGxzRmFrZShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaW5GbGlnaHQrKztcbiAgICAgICAgICBtYXhJbkZsaWdodCA9IE1hdGgubWF4KG1heEluRmxpZ2h0LCBpbkZsaWdodCk7XG4gICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgNSkpO1xuICAgICAgICAgIGluRmxpZ2h0LS07XG4gICAgICAgICAgcmV0dXJuIHsgc2hhcmVkOiB0cnVlIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMucmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyh3YWxsZXRJZCwgJ3B3Jyk7XG5cbiAgICAgICAgbWF4SW5GbGlnaHQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdyZXR1cm5zIGVhcmx5IHdoZW4gdGhlIHdhbGxldCBoYXMgbm8gc3BlbmRlciB1c2VycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAncmVzaGFyZS1lbXB0eSc7XG4gICAgICAgIGNvbnN0IGVudGVycHJpc2UgPSAnZW50LWVtcHR5JztcblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnZ2V0JykucmVzb2x2ZXMoXG4gICAgICAgICAgbmV3IFdhbGxldChiaXRnbywgYml0Z28uY29pbigndHNvbCcpLCB7XG4gICAgICAgICAgICBpZDogd2FsbGV0SWQsXG4gICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlLFxuICAgICAgICAgICAgdXNlcnM6IFt7IHVzZXI6ICdhZG1pbi1vbmx5JywgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAndmlldycsICdzcGVuZCddIH1dLFxuICAgICAgICAgICAga2V5czogWyd1c2VyS2V5SWQnLCAnYmFja3VwS2V5SWQnLCAnYml0Z29LZXlJZCddLFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS9lbnRlcnByaXNlLyR7ZW50ZXJwcmlzZX0vdXNlcmApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWRtaW5Vc2VyczogW3sgaWQ6ICdhZG1pbi1vbmx5JywgZW1haWw6IHsgZW1haWw6ICdhZG1pbkBleGFtcGxlLmNvbScgfSB9XSxcbiAgICAgICAgICAgIG5vbkFkbWluVXNlcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRTdHViID0gc2lub24uc3R1YihXYWxsZXQucHJvdG90eXBlLCAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nJyk7XG4gICAgICAgIGNvbnN0IHNoYXJlV2FsbGV0U3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0Jyk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0cy5yZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzKHdhbGxldElkLCAncHcnKTtcblxuICAgICAgICAvLyBObyBkZWNyeXB0IGJ1cm5lZCwgbm8gc2hhcmVzIGF0dGVtcHRlZFxuICAgICAgICBkZWNyeXB0U3R1Yi5jYWxsZWQuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgICAgc2hhcmVXYWxsZXRTdHViLmNhbGxlZC5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdwcm9jZWVkcyB3aXRoIHBlci1yZWNpcGllbnQgc2hhcmVXYWxsZXQgZXZlbiB3aGVuIHRoZSB3YWxsZXQgaXMgY29sZCAobm8gZGVjcnlwdGVkS2V5Y2hhaW4pJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICdyZXNoYXJlLWNvbGQnO1xuICAgICAgICBjb25zdCBlbnRlcnByaXNlID0gJ2VudC1jb2xkJztcbiAgICAgICAgc3R1YkZvclJlc2hhcmUoMiwgd2FsbGV0SWQsIGVudGVycHJpc2UpO1xuXG4gICAgICAgIC8vIFNpbXVsYXRlIGNvbGQgd2FsbGV0OiBnZXREZWNyeXB0ZWRLZXljaGFpbkZvclNoYXJpbmcgdGhyb3dzIE1pc3NpbmdFbmNyeXB0ZWRLZXljaGFpbkVycm9yXG4gICAgICAgIC8vICh3aGljaCB3ZSBjYXRjaCBpbnNpZGUgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyBhbmQgZmFsbCB0aHJvdWdoKS5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXQucHJvdG90eXBlLCAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nJykucmVqZWN0cyhuZXcgTWlzc2luZ0VuY3J5cHRlZEtleWNoYWluRXJyb3IoKSk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmVXYWxsZXRTdHViID0gc2lub24uc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKS5yZXNvbHZlcyh7IHNoYXJlZDogdHJ1ZSB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzLnJlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMod2FsbGV0SWQsICdwdycpO1xuXG4gICAgICAgIC8vIFN0aWxsIGZpcmVzIHBlciByZWNpcGllbnQ7IGVhY2ggY2FsbCBnZXRzIHVuZGVmaW5lZCBkZWNyeXB0ZWRLZXljaGFpbiBhbmQgc2hhcmVXYWxsZXRcbiAgICAgICAgLy8gY2FuIGZhbGwgYmFjayB0byBpdHMgb3duIGRlY3J5cHQgcGF0aCAob3IgYSBuby1vcCBmb3IgY29sZCB3YWxsZXRzIGludGVybmFsbHkpLlxuICAgICAgICBzaGFyZVdhbGxldFN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBzaGFyZUFyZyA9IHNoYXJlV2FsbGV0U3R1Yi5nZXRDYWxsKGkpLmFyZ3NbMF0hO1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaGFyZUFyZy5kZWNyeXB0ZWRLZXljaGFpbiwgdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVCdWxrS2V5U2hhcmVzIHRlc3RzJywgKCkgPT4ge1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB0eXBlOiAnaG90JyxcbiAgICB9O1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdHNvbCwgd2FsbGV0RGF0YSk7XG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG4gICAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICB9KTtcbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICB9KTtcbiAgICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgc2hhcmVPcHRpb25zIGlzIGVtcHR5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtLZXlTaGFyZXMoW10pO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsICdzaGFyZU9wdGlvbnMgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNraXAgc2hhcmVvcHRpb24gaWYga2V5Y2hhaW4gcGFyYW1ldGVycyBhcmUgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHVzZXI6ICd0ZXN0dXNlckBleGFtcGxlLmNvbScsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICBrZXljaGFpbjogeyBwdWI6ICdwdWJrZXknLCBlbmNyeXB0ZWRQcnY6ICcnLCBmcm9tUHViS2V5OiAnJywgdG9QdWJLZXk6ICcnLCBwYXRoOiAnJyB9LFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtLZXlTaGFyZXMocGFyYW1zKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFNoYXJlb3B0aW9ucyB3aXRoIGludmFsaWQga2V5Y2hhaW5zIGFyZSBza2lwcGVkXG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnc2hhcmVPcHRpb25zIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZW5kIHRoZSBjb3JyZWN0IGRhdGEgdG8gQml0R28gQVBJIGlmIHNoYXJlT3B0aW9ucyBhcmUgdmFsaWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIHNoYXJlT3B0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0dXNlckBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcHViOiAncHVia2V5JyxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgICB0b1B1YktleTogJ3RvUHViS2V5JyxcbiAgICAgICAgICAgICAgcGF0aDogJ20vMC8wJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXJhbXNUb1NlbmQgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB1c2VyOiAndGVzdHVzZXJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgIHB1YjogJ3B1YmtleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICBwYXRoOiAnbS8wLzAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0RGF0YS5pZH0vd2FsbGV0c2hhcmVzYCwgcGFyYW1zKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAndXNlcklkJyxcbiAgICAgICAgICAgICAgY29pbjogd2FsbGV0RGF0YS5jb2luLFxuICAgICAgICAgICAgICB3YWxsZXQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZnJvbVVzZXJJZCcsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ3RvVXNlcklkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldycsICdzcGVuZCddLFxuICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgIHB1YjogJ2R1bW15UHViJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdkdW1teUVuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICAgICAgdG9QdWJLZXk6ICdkdW1teVRvUHViS2V5JyxcbiAgICAgICAgICAgICAgICBwYXRoOiAnZHVtbXlQYXRoJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa0tleVNoYXJlcyhwYXJhbXNUb1NlbmQpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0uaWQsICd1c2VySWQnLCAnVGhlIHNoYXJlIElEIHNob3VsZCBtYXRjaCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0uY29pbiwgd2FsbGV0RGF0YS5jb2luLCAnVGhlIGNvaW4gc2hvdWxkIG1hdGNoJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnNoYXJlc1swXS53YWxsZXQsIHdhbGxldERhdGEuaWQsICdUaGUgd2FsbGV0IElEIHNob3VsZCBtYXRjaCcpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5zaGFyZXNbMF0ua2V5Y2hhaW4pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0ua2V5Y2hhaW4ucHViLCAnZHVtbXlQdWInLCAnVGhlIGtleWNoYWluIHB1YiBzaG91bGQgbWF0Y2gnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLnBlcm1pc3Npb25zLmluY2x1ZGVzKCd2aWV3JyksIHRydWUsICdUaGUgcGVybWlzc2lvbnMgc2hvdWxkIGluY2x1ZGUgXCJ2aWV3XCInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgcmVzdWx0LnNoYXJlc1swXS5wZXJtaXNzaW9ucy5pbmNsdWRlcygnc3BlbmQnKSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgJ1RoZSBwZXJtaXNzaW9ucyBzaG91bGQgaW5jbHVkZSBcInNwZW5kXCInXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlQnVsa1dhbGxldFNoYXJlIHRlc3RzJywgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuXG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDAnLFxuICAgICAgY29pbjogJ3RidGMnLFxuICAgICAga2V5czogW1xuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgXSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgIH07XG4gICAgY29uc3QgdHNvbCA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0c29sLCB3YWxsZXREYXRhKTtcbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucGVyc2lzdCgpLmdldCgnL2FwaS92MS9jbGllbnQvY29uc3RhbnRzJykucmVwbHkoMjAwLCB7IHR0bDogMzYwMCwgY29uc3RhbnRzOiB7fSB9KTtcbiAgICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgbm8gc2hhcmUgb3B0aW9ucyBhcmUgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHsgd2FsbGV0UGFzc3BocmFzZTogJ1Rlc3QnLCBrZXlTaGFyZU9wdGlvbnM6IFtdIH0pO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsICdObyBzaGFyZSBvcHRpb25zIHByb3ZpZGVkJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IE5lZWRzVXNlclNpZ251cCBlcnJvciBpZiBwdWJrZXkgaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnVGVzdCcsXG4gICAgICAgICAga2V5U2hhcmVPcHRpb25zOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIHBhdGg6ICdtLzk5OTk5OS8xLzEnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9IGFzIEJ1bGtXYWxsZXRTaGFyZU9wdGlvbnMpO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0Lm9rKGVycm9yIGluc3RhbmNlb2YgTmVlZFVzZXJTaWdudXBFcnJvcik7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5uYW1lLCAnTmVlZFVzZXJTaWdudXBFcnJvcicpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubWVzc2FnZSwgdXNlcklkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgcGF0aCBpcyBtaXNzaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdXNlcklkID0gJ3VzZXJAZXhhbXBsZS5jb20nO1xuICAgICAgY29uc3QgcGVybWlzc2lvbnMgPSBbJ3ZpZXcnLCAnc3BlbmQnXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdUZXN0JyxcbiAgICAgICAgICBrZXlTaGFyZU9wdGlvbnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdXNlcklkOiB1c2VySWQsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgICAgcHViS2V5OiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSBhcyBCdWxrV2FsbGV0U2hhcmVPcHRpb25zKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5uYW1lLCAnRXJyb3InKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsICdNaXNzaW5nIHBhcmFtZXRlcjogcGF0aCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBOZWVkc1VzZXJTaWdudXAgZXJyb3IgaWYgcHVia2V5IGlzIGVtcHR5IHN0cmluZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnVGVzdCcsXG4gICAgICAgICAga2V5U2hhcmVPcHRpb25zOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgICBwdWJLZXk6ICcnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIHBhdGg6ICdtLzk5OTk5OS8xLzEnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5vayhlcnJvciBpbnN0YW5jZW9mIE5lZWRVc2VyU2lnbnVwRXJyb3IpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubmFtZSwgJ05lZWRVc2VyU2lnbnVwRXJyb3InKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsIHVzZXJJZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBwcm9jZXNzIHNoYXJlIG9wdGlvbnMgYW5kIGNhbGwgY3JlYXRlQnVsa0tleVNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICBjb25zdCBwdWIgPSAnWm8xZ2d6VFVLTVk1YlluRHZUNW10VmVaeHpmMkZhTFRiS2ttdkdVaFVRayc7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMva2V5LyR7d2FsbGV0LmtleUlkcygpWzBdfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogd2FsbGV0LmtleUlkcygpWzBdLFxuICAgICAgICAgIHB1YixcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBwYXJhbXM6IEJ1bGtXYWxsZXRTaGFyZU9wdGlvbnMgPSB7XG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgcHViS2V5OiAnMDI3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMyJyxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBydjEgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYxLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgIH07XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0RW5jcnlwdGVkVXNlcktleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleWNoYWluVGVzdC5lbmNyeXB0ZWRQcnYsXG4gICAgICAgIHB1YixcbiAgICAgIH0gYXMgS2V5Y2hhaW5XaXRoRW5jcnlwdGVkUHJ2KTtcblxuICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnY3JlYXRlQnVsa0tleVNoYXJlcycpLnJlc29sdmVzKHtcbiAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0RGF0YS5pZCxcbiAgICAgICAgICAgIGZyb21Vc2VyOiB1c2VySWQsXG4gICAgICAgICAgICB0b1VzZXI6IHVzZXJJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHB1YjogJ2R1bW15UHViJyxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiAnZHVtbXlGcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6ICdkdW1teVRvUHViS2V5JyxcbiAgICAgICAgICAgICAgcGF0aDogJ2R1bW15UGF0aCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZShwYXJhbXMpO1xuXG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdCwge1xuICAgICAgICBzaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogdXNlcklkLFxuICAgICAgICAgICAgY29pbjogd2FsbGV0RGF0YS5jb2luLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXREYXRhLmlkLFxuICAgICAgICAgICAgZnJvbVVzZXI6IHVzZXJJZCxcbiAgICAgICAgICAgIHRvVXNlcjogdXNlcklkLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldycsICdzcGVuZCddLFxuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcHViOiAnZHVtbXlQdWInLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdkdW1teUVuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdkdW1teUZyb21QdWJLZXknLFxuICAgICAgICAgICAgICB0b1B1YktleTogJ2R1bW15VG9QdWJLZXknLFxuICAgICAgICAgICAgICBwYXRoOiAnZHVtbXlQYXRoJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpbiBwcm9jZXNzaW5nIHNoYXJlIG9wdGlvbnMgd2hlbiB3YWxsZXQgcGFzc3dvcmQgaXMgaW5jb3JyZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdXNlcklkID0gJ3VzZXJAZXhhbXBsZS5jb20nO1xuICAgICAgY29uc3QgcGVybWlzc2lvbnMgPSBbJ3ZpZXcnLCAnc3BlbmQnXTtcbiAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgIGNvbnN0IHB1YiA9ICdabzFnZ3pUVUtNWTViWW5EdlQ1bXRWZVp4emYyRmFMVGJLa212R1VoVVFrJztcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy9rZXkvJHt3YWxsZXQua2V5SWRzKClbMF19YClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiB3YWxsZXQua2V5SWRzKClbMF0sXG4gICAgICAgICAgcHViLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IHBhcmFtczogQnVsa1dhbGxldFNoYXJlT3B0aW9ucyA9IHtcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3dyb25nIHBhc3N3b3JkJyxcbiAgICAgICAga2V5U2hhcmVPcHRpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXNlcklkOiB1c2VySWQsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBwdWJLZXk6ICcwMjcwNWE2ZDMzYTI0NTlmZWI1MzdlN2FiZTM2YWFhZDhjMTE1MzJjZGJmZmEzYTJlNGU1ODg2ODQ2N2Q1MWY1MzInLFxuICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJ2MSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoKTtcbiAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydjEsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgfTtcblxuICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRFbmNyeXB0ZWRVc2VyS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgIGVuY3J5cHRlZFBydjoga2V5Y2hhaW5UZXN0LmVuY3J5cHRlZFBydixcbiAgICAgICAgcHViLFxuICAgICAgfSBhcyBLZXljaGFpbldpdGhFbmNyeXB0ZWRQcnYpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhc3NlcnQub2soZXJyb3IgaW5zdGFuY2VvZiBJbmNvcnJlY3RQYXNzd29yZEVycm9yKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGVycm9yLm1lc3NhZ2UsICdQYXNzd29yZCBzaGFyZWQgaXMgaW5jb3JyZWN0IGZvciB0aGlzIHdhbGxldCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmZXRjaCBrZXljaGFpbiBvbmx5IE9OQ0Ugd2hlbiBzaGFyaW5nIHdpdGggbXVsdGlwbGUgdXNlcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICBjb25zdCBwdWIgPSAnWm8xZ2d6VFVLTVk1YlluRHZUNW10VmVaeHpmMkZhTFRiS2ttdkdVaFVRayc7XG4gICAgICBjb25zdCBwcnYxID0gJ3hwcnYxJztcblxuICAgICAgLy8gQ3JlYXRlIG11bHRpcGxlIHVzZXJzIHRvIHNoYXJlIHdpdGhcbiAgICAgIGNvbnN0IHVzZXJzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgdXNlcklkOiAndXNlcjFAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICBwdWJLZXk6ICcwMjcwNWE2ZDMzYTI0NTlmZWI1MzdlN2FiZTM2YWFhZDhjMTE1MzJjZGJmZmEzYTJlNGU1ODg2ODQ2N2Q1MWY1MzInLFxuICAgICAgICAgIHBhdGg6ICdtLzk5OTk5OS8xLzEnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdXNlcklkOiAndXNlcjJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICBwdWJLZXk6ICcwMzcwNWE2ZDMzYTI0NTlmZWI1MzdlN2FiZTM2YWFhZDhjMTE1MzJjZGJmZmEzYTJlNGU1ODg2ODQ2N2Q1MWY1MzMnLFxuICAgICAgICAgIHBhdGg6ICdtLzk5OTk5OS8xLzInLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgdXNlcklkOiAndXNlcjNAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICBwdWJLZXk6ICcwMjgxNWE2ZDMzYTI0NTlmZWI1MzdlN2FiZTM2YWFhZDhjMTE1MzJjZGJmZmEzYTJlNGU1ODg2ODQ2N2Q1MWY1MzQnLFxuICAgICAgICAgIHBhdGg6ICdtLzk5OTk5OS8xLzMnLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgcGFyYW1zOiBCdWxrV2FsbGV0U2hhcmVPcHRpb25zID0ge1xuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBrZXlTaGFyZU9wdGlvbnM6IHVzZXJzLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZ2V0RGVjcnlwdGVkS2V5Y2hhaW5TdHViID0gc2lub24uc3R1Yih3YWxsZXQsICdnZXREZWNyeXB0ZWRLZXljaGFpbkZvclNoYXJpbmcnKS5yZXNvbHZlcyh7XG4gICAgICAgIHBydjogcHJ2MSxcbiAgICAgICAgcHViLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGVuY3J5cHRQcnZGb3JVc2VyU3R1YiA9IHNpbm9uXG4gICAgICAgIC5zdHViKHdhbGxldCwgJ2VuY3J5cHRQcnZGb3JVc2VyJylcbiAgICAgICAgLmNhbGxzRmFrZShhc3luYyAocHJ2LCBwdWJLZXksIHVzZXJQdWJLZXksIHBhdGgpID0+IHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcHViOiBwdWJLZXksXG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdkdW1teUVuY3J5cHRlZFBydicsXG4gICAgICAgICAgICBmcm9tUHViS2V5OiAnZHVtbXlGcm9tUHViS2V5JyxcbiAgICAgICAgICAgIHRvUHViS2V5OiB1c2VyUHViS2V5LFxuICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdjcmVhdGVCdWxrS2V5U2hhcmVzJykucmVzb2x2ZXMoe1xuICAgICAgICBzaGFyZXM6IHVzZXJzLm1hcCgodXNlcikgPT4gKHtcbiAgICAgICAgICBpZDogdXNlci51c2VySWQsXG4gICAgICAgICAgY29pbjogd2FsbGV0RGF0YS5jb2luLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0RGF0YS5pZCxcbiAgICAgICAgICBmcm9tVXNlcjogJ2Zyb21Vc2VyJyxcbiAgICAgICAgICB0b1VzZXI6IHVzZXIudXNlcklkLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiB1c2VyLnBlcm1pc3Npb25zLFxuICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICBwdWI6ICdkdW1teVB1YicsXG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdkdW1teUVuY3J5cHRlZFBydicsXG4gICAgICAgICAgICBmcm9tUHViS2V5OiAnZHVtbXlGcm9tUHViS2V5JyxcbiAgICAgICAgICAgIHRvUHViS2V5OiB1c2VyLnB1YktleSxcbiAgICAgICAgICAgIHBhdGg6IHVzZXIucGF0aCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSksXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZShwYXJhbXMpO1xuXG4gICAgICAvLyBWZXJpZnkga2V5Y2hhaW4gaXMgZmV0Y2hlZCBvbmx5IE9OQ0UsIG5vdCBvbmNlIHBlciB1c2VyXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIGdldERlY3J5cHRlZEtleWNoYWluU3R1Yi5jYWxsQ291bnQsXG4gICAgICAgIDEsXG4gICAgICAgICdnZXREZWNyeXB0ZWRLZXljaGFpbkZvclNoYXJpbmcgc2hvdWxkIGJlIGNhbGxlZCBleGFjdGx5IG9uY2UsIG5vdCBvbmNlIHBlciB1c2VyJ1xuICAgICAgKTtcblxuICAgICAgLy8gVmVyaWZ5IGVuY3J5cHRpb24gaGFwcGVucyBmb3IgRUFDSCB1c2VyIChvbmNlIHBlciB1c2VyKVxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICBlbmNyeXB0UHJ2Rm9yVXNlclN0dWIuY2FsbENvdW50LFxuICAgICAgICB1c2Vycy5sZW5ndGgsXG4gICAgICAgIGBlbmNyeXB0UHJ2Rm9yVXNlciBzaG91bGQgYmUgY2FsbGVkIG9uY2UgcGVyIHVzZXIgKCR7dXNlcnMubGVuZ3RofSB0aW1lcylgXG4gICAgICApO1xuXG4gICAgICAvLyBWZXJpZnkgZWFjaCBjYWxsIGhhZCB0aGUgY29ycmVjdCB1c2VyJ3MgcHViS2V5IGFuZCBwYXRoXG4gICAgICB1c2Vycy5mb3JFYWNoKCh1c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxsID0gZW5jcnlwdFBydkZvclVzZXJTdHViLmdldENhbGwoaW5kZXgpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FsbC5hcmdzWzBdLCBwcnYxLCAnU2hvdWxkIHVzZSB0aGUgc2FtZSBkZWNyeXB0ZWQgcHJpdmF0ZSBrZXkgZm9yIGFsbCB1c2VycycpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FsbC5hcmdzWzFdLCBwdWIsICdTaG91bGQgdXNlIHRoZSBzYW1lIHB1YmxpYyBrZXkgZm9yIGFsbCB1c2VycycpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY2FsbC5hcmdzWzJdLCB1c2VyLnB1YktleSwgYFNob3VsZCB1c2UgdXNlciR7aW5kZXggKyAxfSdzIHB1YmxpYyBrZXlgKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1szXSwgdXNlci5wYXRoLCBgU2hvdWxkIHVzZSB1c2VyJHtpbmRleCArIDF9J3MgcGF0aGApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdkb3dubG9hZEtleWNhcmQnLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxCaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMicsXG4gICAgICBjb2luOiAndGJ0YycsXG4gICAgICBrZXlzOiBbXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICBdLFxuICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ29uY2hhaW4nLFxuICAgICAgdHlwZTogJ2hvdCcsXG4gICAgfTtcbiAgICBjb25zdCB0YnRjID0gbG9jYWxCaXRnby5jb2luKCd0YnRjJyk7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChsb2NhbEJpdGdvLCB0YnRjLCB3YWxsZXREYXRhKTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiBjYWxsZWQgaW4gTm9kZS5qcyAobm8gYnJvd3NlciB3aW5kb3cpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gSW4gTm9kZS5qcywgYWNjZXNzaW5nIGB3aW5kb3dgIHRocm93cyBSZWZlcmVuY2VFcnJvcjsgdGhlIG1ldGhvZCByZWplY3RzLlxuICAgICAgYXdhaXQgd2FsbGV0LmRvd25sb2FkS2V5Y2FyZCgpLnNob3VsZC5iZS5yZWplY3RlZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2Rvd25sb2FkS2V5Y2FyZCAoc3luYykgc2hvdWxkIHRocm93IHdoZW4gY2FsbGVkIGluIE5vZGUuanMgKG5vIGJyb3dzZXIgd2luZG93KScsICgpID0+IHtcbiAgICAgIHNob3VsZC50aHJvd3MoKCkgPT4gd2FsbGV0LmRvd25sb2FkS2V5Y2FyZCgpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2VuY3J5cHRQcnZGb3JVc2VyJywgKCkgPT4ge1xuICAgIGNvbnN0IGxvY2FsQml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDEnLFxuICAgICAgY29pbjogJ3RidGMnLFxuICAgICAga2V5czogW1xuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgXSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgIH07XG4gICAgY29uc3QgdGJ0YyA9IGxvY2FsQml0Z28uY29pbigndGJ0YycpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQobG9jYWxCaXRnbywgdGJ0Yywgd2FsbGV0RGF0YSk7XG5cbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucGVyc2lzdCgpLmdldCgnL2FwaS92MS9jbGllbnQvY29uc3RhbnRzJykucmVwbHkoMjAwLCB7IHR0bDogMzYwMCwgY29uc3RhbnRzOiB7fSB9KTtcbiAgICAgIGxvY2FsQml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNyeXB0IHBydiBmb3IgdXNlciBhbmQgcmV0dXJuIHRoZSBjb3JyZWN0IG91dHB1dCBzaGFwZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9XG4gICAgICAgICd4cHJ2OXMyMVpyUUgxNDNLMmZKOTFTNEJSc3VwY1lyRTZtbVk5NmZjWDVIa2hvVHJyd213amQxNkNuODdjV2luSmpCeXJmcG9qang3ZXpzSkx4N1RBS0xUOG04aE01S2F4OVljb3huQmVKWjN0MmsnO1xuICAgICAgY29uc3QgcHViID1cbiAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGOU5jN1RiQm8xclpBYWdpV0VWUFdLYkRLVGhORzh6cWprNzZIQUtMa2FTYlRuNmRLMmRRUGZ1RDd4amljeENaVld2ajY3ZlA1blE5VzdRVVJtb01WQVg4bTZqWnNHcCc7XG4gICAgICAvLyBBIHZhbGlkIDMzLWJ5dGUgY29tcHJlc3NlZCBFQyBwb2ludCBvbiBzZWNwMjU2azFcbiAgICAgIGNvbnN0IHVzZXJQdWJrZXkgPSAnMDI3OWJlNjY3ZWY5ZGNiYmFjNTVhMDYyOTVjZTg3MGIwNzAyOWJmY2RiMmRjZTI4ZDk1OWYyODE1YjE2ZjgxNzk4JztcbiAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMC8xJztcblxuICAgICAgc2lub24uc3R1Yihsb2NhbEJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKCdlbmNyeXB0ZWRQcnZGb3JVc2VyJyk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5lbmNyeXB0UHJ2Rm9yVXNlcihkZWNyeXB0ZWRQcnYsIHB1YiwgdXNlclB1YmtleSwgcGF0aCk7XG5cbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHViJywgcHViKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2JywgJ2VuY3J5cHRlZFBydkZvclVzZXInKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZnJvbVB1YktleScpLndoaWNoLmlzLmEuU3RyaW5nKCk7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RvUHViS2V5JywgdXNlclB1YmtleSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhdGgnLCBwYXRoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0xpc3QgV2FsbGV0czonLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBsaXN0IHdhbGxldHMgd2l0aCBza2lwUmVjZWl2ZUFkZHJlc3MgPSB0cnVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgIGNvbnN0IHdhbGxldHMgPSBiYXNlY29pbi53YWxsZXRzKCk7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLmdldCgnL2FwaS92Mi90YnRjL3dhbGxldCcpXG4gICAgICAgIC5xdWVyeSh7IHNraXBSZWNlaXZlQWRkcmVzczogdHJ1ZSB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgd2FsbGV0czogW1xuICAgICAgICAgICAgeyBpZDogJ3dhbGxldDEnLCBsYWJlbDogJ1Rlc3QgV2FsbGV0IDEnIH0sXG4gICAgICAgICAgICB7IGlkOiAnd2FsbGV0MicsIGxhYmVsOiAnVGVzdCBXYWxsZXQgMicgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5saXN0KHsgc2tpcFJlY2VpdmVBZGRyZXNzOiB0cnVlIH0pO1xuICAgICAgcmVzdWx0LndhbGxldHMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXN1bHQud2FsbGV0c1swXS5yZWNlaXZlQWRkcmVzcygpKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QocmVzdWx0LndhbGxldHNbMV0ucmVjZWl2ZUFkZHJlc3MoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGxpc3Qgd2FsbGV0cyB3aXRob3V0IHNraXBSZWNlaXZlQWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICBjb25zdCB3YWxsZXRzID0gYmFzZWNvaW4ud2FsbGV0cygpO1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvdGJ0Yy93YWxsZXQnKVxuICAgICAgICAucXVlcnkoe30pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICB3YWxsZXRzOiBbXG4gICAgICAgICAgICB7IGlkOiAnd2FsbGV0MScsIGxhYmVsOiAnVGVzdCBXYWxsZXQgMScsIHJlY2VpdmVBZGRyZXNzOiB7IGFkZHJlc3M6ICdhZGRyZXNzMScgfSB9LFxuICAgICAgICAgICAgeyBpZDogJ3dhbGxldDInLCBsYWJlbDogJ1Rlc3QgV2FsbGV0IDInLCByZWNlaXZlQWRkcmVzczogeyBhZGRyZXNzOiAnYWRkcmVzczInIH0gfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5saXN0KCk7XG4gICAgICByZXN1bHQud2FsbGV0cy5zaG91bGQuaGF2ZS5sZW5ndGgoMik7XG4gICAgICBzaG91bGQuZXhpc3QocmVzdWx0LndhbGxldHNbMF0ucmVjZWl2ZUFkZHJlc3MoKSk7XG4gICAgICBzaG91bGQuZXhpc3QocmVzdWx0LndhbGxldHNbMV0ucmVjZWl2ZUFkZHJlc3MoKSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=