bitgo
Version:
BitGo JavaScript SDK
1,095 lines • 213 kB
JavaScript
"use strict";
//
// Test for Keychains
//
Object.defineProperty(exports, "__esModule", { value: true });
const statics_1 = require("@bitgo/statics");
const assert = require("assert");
const _ = require("lodash");
const nock = require("nock");
const should = require("should");
const sinon = require("sinon");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("../../../src/bitgo");
describe('V2 Keychains', function () {
let bitgo;
let basecoin;
let keychains;
let bgUrl;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'mock' });
bitgo.initializeTestVars();
bitgo.setValidate(false);
basecoin = bitgo.coin('tltc');
keychains = basecoin.keychains();
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
});
describe('Add Keychain', function () {
it('should add a keychain', async function () {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', function (body) {
body.pub.should.equal('pub');
body.derivedFromParentWithSeed.should.equal('derivedFromParentWithSeed');
return true;
})
.reply(200, {});
await keychains.add({ pub: 'pub', derivedFromParentWithSeed: 'derivedFromParentWithSeed' });
scope.done();
});
});
/**
* This section's intention is to provide some key generation sanity checking. generateKeyPair is a general surface
* for key generation but the keys are treated the same by BitGo down the line. Any SECP256K1 based coins key-pairs can
* be re-used so need to be the same.
**/
describe('Key generation enforcement for SECP256K1', function () {
// iterate over non-fiat crypto secp coins
const coinFamilyValues = Object.keys(statics_1.CoinFamily).map((n) => n.toLowerCase());
const cryptoSecpCoins = statics_1.coins.filter((n) => n.primaryKeyCurve === statics_1.KeyCurve.Secp256k1 &&
n.kind === statics_1.CoinKind.CRYPTO &&
n.asset !== statics_1.UnderlyingAsset.USD &&
n.asset !== statics_1.UnderlyingAsset.AVAXP &&
n.asset !== statics_1.UnderlyingAsset.APECHAIN &&
n.asset !== statics_1.UnderlyingAsset.DOGE &&
n.asset !== statics_1.UnderlyingAsset.ETHW &&
n.asset !== statics_1.UnderlyingAsset.KAVACOSMOS &&
n.asset !== statics_1.UnderlyingAsset.COREUM &&
n.asset !== statics_1.UnderlyingAsset.BERA &&
n.asset !== statics_1.UnderlyingAsset.ISLM &&
n.asset !== statics_1.UnderlyingAsset.ARBETH && // TODO(WIN-692): remove this once coin-specific module for arbeth is added
n.asset !== statics_1.UnderlyingAsset.OPETH && // TODO(WIN-692): remove this once coin-specific module for opeth is added
n.asset !== statics_1.UnderlyingAsset.ZKETH && // TODO(WIN-1427): remove this once coin-specific module for zketh is added
n.asset !== statics_1.UnderlyingAsset.OAS && // TODO(WIN-3696): remove this once coin-specific module for oas is added
n.asset !== statics_1.UnderlyingAsset.COREDAO && // TODO(WIN-3696): remove this once coin-specific module for coredao is added
n.asset !== statics_1.UnderlyingAsset.FLR && // TODO(WIN-4215): remove this once coin-specific module for FLR is added
n.asset !== statics_1.UnderlyingAsset.SGB && // TODO(WIN-4216): remove this once coin-specific module for SGB is added
n.asset !== statics_1.UnderlyingAsset.WEMIX && // TODO(WIN-4177): remove this once coin-specific module for WEMIX is added
n.asset !== statics_1.UnderlyingAsset.XDC && // TODO(WIN-4173): remove this once coin-specific module for XDC is added
n.asset !== statics_1.UnderlyingAsset.RUNE &&
n.asset !== statics_1.UnderlyingAsset.BABY &&
n.asset !== statics_1.UnderlyingAsset.ICP &&
n.asset !== statics_1.UnderlyingAsset.MANTRA &&
n.asset !== statics_1.UnderlyingAsset.MON &&
n.asset !== statics_1.UnderlyingAsset.OG &&
n.asset !== statics_1.UnderlyingAsset.WORLD &&
n.asset !== statics_1.UnderlyingAsset.PHRS &&
n.asset !== statics_1.UnderlyingAsset.CTC &&
n.asset !== statics_1.UnderlyingAsset.HYPEEVM &&
n.asset !== statics_1.UnderlyingAsset.XPL &&
n.asset !== statics_1.UnderlyingAsset.SONEIUM &&
n.asset !== statics_1.UnderlyingAsset.VET &&
n.asset !== statics_1.UnderlyingAsset.CRONOS &&
n.asset !== statics_1.UnderlyingAsset.FETCHAI &&
n.asset !== statics_1.UnderlyingAsset.INITIA &&
n.asset !== statics_1.UnderlyingAsset.ASI &&
n.asset !== statics_1.UnderlyingAsset.SONIC &&
n.asset !== statics_1.UnderlyingAsset.SEIEVM &&
n.asset !== statics_1.UnderlyingAsset.KAIA &&
n.asset !== statics_1.UnderlyingAsset.IRYS &&
n.asset !== statics_1.UnderlyingAsset.LINEAETH &&
n.asset !== statics_1.UnderlyingAsset.IP && // Story Chain
n.asset !== statics_1.UnderlyingAsset.BASEETH &&
n.asset !== statics_1.UnderlyingAsset.SOMI &&
n.asset !== statics_1.UnderlyingAsset.FLRP &&
n.asset !== statics_1.UnderlyingAsset.FLUENTETH &&
n.asset !== statics_1.UnderlyingAsset.MANTLE &&
n.asset !== statics_1.UnderlyingAsset.H &&
n.asset !== statics_1.UnderlyingAsset.HOODETH &&
n.asset !== statics_1.UnderlyingAsset.HPPETH &&
n.asset !== statics_1.UnderlyingAsset.JOVAYETH &&
n.asset !== statics_1.UnderlyingAsset.OKBXLAYER &&
n.asset !== statics_1.UnderlyingAsset.UNIETH &&
n.asset !== statics_1.UnderlyingAsset.MORPH &&
n.asset !== statics_1.UnderlyingAsset.MORPHETH &&
n.asset !== statics_1.UnderlyingAsset.DOGEOS &&
n.asset !== statics_1.UnderlyingAsset.MEGAETH &&
n.asset !== statics_1.UnderlyingAsset.ARCUSDC &&
n.asset !== statics_1.UnderlyingAsset.ZKSYNCERA &&
n.asset !== statics_1.UnderlyingAsset.HYPERLIQUID &&
n.asset !== statics_1.UnderlyingAsset.BOBAETH &&
coinFamilyValues.includes(n.name));
const expectedXpub = 'xpub661MyMwAqRbcGpZf8mxNWhSPdWaLGvQzzage6vq2oQFzq8toVzmkjygYZ3HcZw6eCzAfn9ZdyGjKoKkcpKwackdgznVbiunpq7rkxDu7quS';
const expectedXprv = 'xprv9s21ZrQH143K4LVC2kRN9ZVf5UjqsTh9dMm3JYRRF4j1xLZexTTWCBN4hmdZUHeT3vCJPL181ErVaY489ArBKSWaB7Du7vyVS6XC43WtK7A';
const seed = Buffer.from('this is some random seed we will use', 'utf-8');
cryptoSecpCoins.forEach((coin) => {
it(`should create the same ${coin.name} key with the same seed`, function () {
const currentCoin = bitgo.coin(coin.name);
const keyPair = currentCoin.generateKeyPair(seed);
should.exist(keyPair.pub);
should.exist(keyPair.prv);
keyPair.pub.should.equal(expectedXpub);
keyPair.prv.should.equal(expectedXprv);
});
});
});
describe('Update Password', function () {
const oldPassword = 'oldPassword';
const newPassword = 'newPassword';
const otherPassword = 'otherPassword';
describe('should fail', function () {
let sandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
});
it('to update the password', async function () {
await keychains
.updatePassword({ newPassword: '5678' })
.should.be.rejectedWith('Missing parameter: oldPassword');
await keychains
.updatePassword({ oldPassword: 1234, newPassword: '5678' })
.should.be.rejectedWith('Expecting parameter string: oldPassword but found number');
await keychains
.updatePassword({ oldPassword: '1234' })
.should.be.rejectedWith('Missing parameter: newPassword');
await keychains
.updatePassword({ oldPassword: '1234', newPassword: 5678 })
.should.be.rejectedWith('Expecting parameter string: newPassword but found number');
});
it('to update the password for a single keychain', async function () {
(() => keychains.updateSingleKeychainPassword({ newPassword: '5678' })).should.throw('expected old password to be a string');
(() => keychains.updateSingleKeychainPassword({ oldPassword: 1234, newPassword: '5678' })).should.throw('expected old password to be a string');
(() => keychains.updateSingleKeychainPassword({ oldPassword: '1234' })).should.throw('expected new password to be a string');
(() => keychains.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: 5678 })).should.throw();
(() => keychains.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: '5678' })).should.throw('expected keychain to be an object with an encryptedPrv property');
(() => keychains.updateSingleKeychainPassword({
oldPassword: '1234',
newPassword: '5678',
keychain: {},
})).should.throw('expected keychain to be an object with an encryptedPrv property');
(() => keychains.updateSingleKeychainPassword({
oldPassword: '1234',
newPassword: '5678',
keychain: { encryptedPrv: 123 },
})).should.throw('expected keychain to be an object with an encryptedPrv property');
const keychain = { encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: otherPassword }) };
(() => keychains.updateSingleKeychainPassword({ oldPassword, newPassword, keychain })).should.throw('password used to decrypt keychain private key is incorrect');
});
it('to update the password for a single keychain (async)', async function () {
await keychains
.updateSingleKeychainPassword({ newPassword: '5678' })
.should.be.rejectedWith('expected old password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: 1234, newPassword: '5678' })
.should.be.rejectedWith('expected old password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234' })
.should.be.rejectedWith('expected new password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: 5678 })
.should.be.rejectedWith('expected new password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: '5678' })
.should.be.rejectedWith('expected keychain to be an object with an encryptedPrv property');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: '5678', keychain: {} })
.should.be.rejectedWith('expected keychain to be an object with an encryptedPrv property');
await keychains
.updateSingleKeychainPassword({
oldPassword: '1234',
newPassword: '5678',
keychain: { encryptedPrv: 123 },
})
.should.be.rejectedWith('expected keychain to be an object with an encryptedPrv property');
// wrong password — decrypt fails
const keychain = { encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: otherPassword }) };
await keychains
.updateSingleKeychainPassword({ oldPassword, newPassword, keychain })
.should.be.rejectedWith('failed to update keychain password: incorrect password');
// invalid JSON in encryptedPrv
await keychains
.updateSingleKeychainPassword({ oldPassword, newPassword, keychain: { encryptedPrv: 'not-valid-json' } })
.should.be.rejectedWith('failed to update keychain password: decrypt: ciphertext is not valid JSON');
// unknown envelope version
const unknownVersionEnvelope = JSON.stringify({ v: 99, ct: 'abc' });
await keychains
.updateSingleKeychainPassword({
oldPassword,
newPassword,
keychain: { encryptedPrv: unknownVersionEnvelope },
})
.should.be.rejectedWith('failed to update keychain password: decrypt: unknown envelope version 99');
});
it('on any other error', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
pub: 'xpub1',
encryptedPrv: encXprv1,
},
],
});
sandbox.stub(keychains, 'updateSingleKeychainPassword').throws('error', 'some random error');
await keychains.updatePassword({ oldPassword, newPassword }).should.be.rejectedWith('some random error');
});
});
describe('successful password update', function () {
const validateKeys = async function (keys, newPassword, expectedLength) {
assert.ok(Object.keys(keys).length === expectedLength, 'should have the expected number of keys');
for (const [key, value] of Object.entries(keys)) {
assert.ok(key.includes('xpub') || key.includes('randomid'), 'key should be xpub or randomid');
const decryptedPrv = await bitgo.decrypt({ input: value, password: newPassword });
decryptedPrv.should.startWith('xprv');
}
};
it('receive only one page when listing keychains', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
const encXprv3 = await bitgo.encrypt({ input: 'xprv3', password: oldPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
pub: 'xpub1',
encryptedPrv: encXprv1,
},
{
pub: 'xpub2',
encryptedPrv: encXprv2,
},
{
id: 'randomid1',
type: 'tss',
encryptedPrv: encXprv3,
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 2);
});
it('receive multiple pages when listing keychains', async function () {
const prevId = 'prevId';
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
const encXprv3a = await bitgo.encrypt({ input: 'xprv3', password: oldPassword });
const encXprv3b = await bitgo.encrypt({ input: 'xprv3', password: oldPassword });
const encXprv4 = await bitgo.encrypt({ input: 'xprv4', password: otherPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
nextBatchPrevId: prevId,
keys: [
{
pub: 'xpub1',
encryptedPrv: encXprv1,
},
{
pub: 'xpub2',
encryptedPrv: encXprv2,
},
{
id: 'randomid1',
type: 'tss',
encryptedPrv: encXprv3a,
},
],
});
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(function queryNextPageMatch(queryObject) {
return queryObject.prevId === prevId;
})
.reply(200, {
keys: [
{
pub: 'xpub3',
encryptedPrv: encXprv3b,
},
{
pub: 'xpub4',
encryptedPrv: encXprv4,
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 3);
});
it('single keychain password update', async () => {
const prv = 'xprvtest';
const keychain = {
xpub: 'xpub123',
encryptedPrv: await bitgo.encrypt({ input: prv, password: oldPassword }),
};
const newKeychain = await keychains.updateSingleKeychainPassword({ keychain, oldPassword, newPassword });
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv);
});
it('single keychain password update emits a v2 (Argon2id) envelope for a v2 input', async () => {
const prv = 'xprvtest-v2';
const encryptedPrv = await bitgo.encrypt({ input: prv, password: oldPassword, encryptionVersion: 2 });
const envelope = JSON.parse(encryptedPrv);
envelope.v.should.equal(2, 'pre-condition: keychain must be v2-encrypted');
const keychain = { xpub: 'xpub123', encryptedPrv };
const newKeychain = await keychains.updateSingleKeychainPassword({ keychain, oldPassword, newPassword });
const newEnvelope = JSON.parse(newKeychain.encryptedPrv);
newEnvelope.v.should.equal(2, 're-encrypted keychain must still be v2');
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv, 'new password must decrypt to original prv');
await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: oldPassword }).should.be.rejected();
});
it('single keychain password update preserves a v1 (SJCL) envelope by default', async () => {
const prv = 'xprvtest-v1';
const encryptedPrv = await bitgo.encrypt({ input: prv, password: oldPassword, encryptionVersion: 1 });
JSON.parse(encryptedPrv).should.not.have.property('v', 2, 'pre-condition: input must not be v2');
const keychain = { xpub: 'xpub123', encryptedPrv };
const newKeychain = await keychains.updateSingleKeychainPassword({ keychain, oldPassword, newPassword });
JSON.parse(newKeychain.encryptedPrv).should.not.have.property('v', 2, 'v1 keychain must stay v1 by default');
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv, 'new password must decrypt to original prv');
await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: oldPassword }).should.be.rejected();
});
it('single keychain password update upgrades a v1 envelope to v2 when encryptionVersion: 2 is passed', async () => {
const prv = 'xprvtest-v1-opt-in';
const encryptedPrv = await bitgo.encrypt({ input: prv, password: oldPassword, encryptionVersion: 1 });
const keychain = { xpub: 'xpub123', encryptedPrv };
const newKeychain = await keychains.updateSingleKeychainPassword({
keychain,
oldPassword,
newPassword,
encryptionVersion: 2,
});
JSON.parse(newKeychain.encryptedPrv).v.should.equal(2, 'v2 opt-in must emit a v2 envelope');
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv, 'new password must decrypt to original prv');
});
it("updatePassword preserves each keychain's existing envelope version by default", async function () {
const v1Prv = 'xprv-v1';
const v2Prv = 'xprv-v2';
const encV1 = await bitgo.encrypt({ input: v1Prv, password: oldPassword, encryptionVersion: 1 });
const encV2 = await bitgo.encrypt({ input: v2Prv, password: oldPassword, encryptionVersion: 2 });
const encOther = await bitgo.encrypt({ input: 'xprv-other', password: 'different-password' });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
pub: 'xpub-v1',
encryptedPrv: encV1,
},
{
pub: 'xpub-v2',
encryptedPrv: encV2,
},
{
pub: 'xpub-other',
encryptedPrv: encOther,
},
],
});
const updatedKeys = await keychains.updatePassword({ oldPassword, newPassword });
assert.strictEqual(Object.keys(updatedKeys).length, 2, 'only the two matching keychains should be updated');
const updatedV1 = updatedKeys['xpub-v1'];
const updatedV2 = updatedKeys['xpub-v2'];
assert.ok(updatedV1, 'v1 keychain must be in the result');
assert.ok(updatedV2, 'v2 keychain must be in the result');
JSON.parse(updatedV1).should.not.have.property('v', 2, 'v1 keychain must stay v1 by default');
const decryptedV1 = await bitgo.decrypt({ input: updatedV1, password: newPassword });
decryptedV1.should.equal(v1Prv);
JSON.parse(updatedV2).v.should.equal(2, 'v2 keychain must remain v2 after password change');
const decryptedV2 = await bitgo.decrypt({ input: updatedV2, password: newPassword });
decryptedV2.should.equal(v2Prv);
});
it('should return the updated keys with ids', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
id: 'randomid1',
type: 'tss',
encryptedPrv: encXprv1,
},
{
id: 'randomid2',
type: 'tss',
encryptedPrv: encXprv2,
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 1);
});
it('should update multi-user-ofc keys', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
id: 'randomid1',
encryptedPrv: encXprv1,
coinSpecific: {
ofc: {
features: ['multi-user-key'],
},
},
},
{
id: 'randomid2',
encryptedPrv: encXprv2,
coinSpecific: {
ofc: {
features: ['multi-user-key'],
},
},
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 1);
});
});
describe('Create TSS Keychains', function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
},
backupKeychain: {
id: '2',
pub: 'userPub',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
},
};
let sandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
});
['tsol', 'tdot', 'tnear'].forEach((coin) => {
it('should create EDDSA TSS Keychains', async function () {
sandbox.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const keychains = await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
keychains.should.deepEqual(stubbedKeychainsTriplet);
});
});
['tbsc'].forEach((coin) => {
it('should create ECDSA TSS Keychains', async function () {
nock(bgUrl).get('/api/v2/tss/settings').reply(200, {
coinSettings: {},
});
sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const keychains = await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
keychains.should.deepEqual(stubbedKeychainsTriplet);
});
});
['tsol'].forEach((coin) => {
it('should pass webauthnInfo to createKeychains for EDDSA TSS', async function () {
const webauthnInfo = {
otpDeviceId: 'device-1',
prfSalt: 'salt-1',
passphrase: 'prf-derived-passphrase',
};
const createKeychains = sandbox
.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
webauthnInfo,
});
createKeychains.calledOnce.should.be.true();
createKeychains.firstCall.args[0].should.have.property('webauthnInfo', webauthnInfo);
});
});
['tbsc'].forEach((coin) => {
it('should reject safe root creation when the resolved ceremony is legacy MPCv1', async function () {
nock(bgUrl).get('/api/v2/tss/settings').reply(200, {
coinSettings: {},
});
const createKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
await bitgo
.coin(coin)
.keychains()
.createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
safeId: 'safeId',
})
.should.be.rejectedWith(/legacy MPCv1 ceremony/);
createKeychains.called.should.be.false();
});
});
['tbsc'].forEach((coin) => {
it('should pass webauthnInfo to createKeychains for ECDSA TSS', async function () {
nock(bgUrl).get('/api/v2/tss/settings').reply(200, {
coinSettings: {},
});
const webauthnInfo = {
otpDeviceId: 'device-1',
prfSalt: 'salt-1',
passphrase: 'prf-derived-passphrase',
};
const createKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
webauthnInfo,
});
createKeychains.calledOnce.should.be.true();
createKeychains.firstCall.args[0].should.have.property('webauthnInfo', webauthnInfo);
});
});
});
describe('Recreate Keychains from MPCV1 to MPCV2', async function () {
const coin = 'hteth';
const walletId = 'walletId';
const otp = '000000';
const sandbox = sinon.createSandbox();
const decryptResult = JSON.stringify({ key: 'decrypted' });
beforeEach(function () {
nock(bgUrl)
.get('/api/v2/tss/settings')
.reply(200, {
coinSettings: {
eth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
},
},
},
});
sandbox.stub(bitgo, 'decrypt').resolves(decryptResult);
});
afterEach(function () {
sandbox.restore();
nock.cleanAll();
});
it('should fail if empty strings are provided', async function () {
const params = {
coin,
walletId,
otp,
passphrase: 'password',
enterprise: 'enterprise',
encryptedMaterial: {
encryptedUserKey: 'encrypted',
encryptedBackupKey: 'encrypted',
encryptedWalletPassphrase: 'passphrase',
},
};
await keychains.recreateMpc({ ...params, coin: '' }).should.be.rejectedWith('missing required param coin');
await keychains
.recreateMpc({ ...params, walletId: '' })
.should.be.rejectedWith('missing required param walletId');
await keychains.recreateMpc({ ...params, otp: '' }).should.be.rejectedWith('missing required param otp');
await keychains
.recreateMpc({ ...params, passphrase: '' })
.should.be.rejectedWith('missing required param passphrase');
await keychains
.recreateMpc({
...params,
encryptedMaterial: {
...params.encryptedMaterial,
encryptedWalletPassphrase: '',
},
})
.should.be.rejectedWith('missing required param encryptedWalletPassphrase');
await keychains
.recreateMpc({
...params,
encryptedMaterial: {
...params.encryptedMaterial,
encryptedUserKey: '',
},
})
.should.be.rejectedWith('missing required param encryptedUserKey');
await keychains
.recreateMpc({
...params,
encryptedMaterial: {
...params.encryptedMaterial,
encryptedBackupKey: '',
},
})
.should.be.rejectedWith('missing required param encryptedBackupKey');
});
it('should fail if otp unlock fails', async function () {
nock(bgUrl).post('/api/v1/user/unlock').replyWithError('otp error');
const params = {
coin,
walletId,
otp,
passphrase: 'password',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
await keychains.recreateMpc(params).should.be.rejectedWith('otp error');
});
it('should fail if passcode recovery api call fails', async function () {
nock(bgUrl).post('/api/v1/user/unlock').reply(200, { otp });
nock(bgUrl)
.post(`/api/v2/${coin}/wallet/${walletId}/passcoderecovery`)
.replyWithError('passcode recovery error');
const params = {
coin,
walletId,
otp,
passphrase: 'password',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
await keychains.recreateMpc(params).should.be.rejectedWith('passcode recovery error');
});
it('should fail if passcode recovery api call returns invalid recovery info', async function () {
nock(bgUrl).post('/api/v1/user/unlock').reply(200, { otp });
nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/passcoderecovery`).reply(200, { recoveryInfo: {} });
const params = {
coin,
walletId,
otp,
passphrase: 'password',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
await keychains.recreateMpc(params).should.be.rejectedWith('failed to get recovery info');
});
it('should call createMpc with the correct parameters', async function () {
nock(bgUrl).post('/api/v1/user/unlock').reply(200, { otp });
nock(bgUrl)
.post(`/api/v2/${coin}/wallet/${walletId}/passcoderecovery`)
.reply(200, { recoveryInfo: { passcodeEncryptionCode: '123' } });
const params = {
coin,
walletId: 'walletId',
otp,
passphrase: 'password',
enterprise: 'enterprise',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
const createMpcStub = sinon.stub(keychains, 'createMpc').resolves();
await keychains.recreateMpc(params);
assert.ok(createMpcStub.calledOnceWith({
...params,
multisigType: 'tss',
retrofit: {
decryptedUserKey: decryptResult,
decryptedBackupKey: decryptResult,
walletId: params.walletId,
},
}));
});
});
after(function afterUpdatePassword() {
nock.pendingMocks().should.be.empty();
});
});
describe('Create BitGo Key from OVC JSON', function () {
const bitGoKeyResult = {
id: '6421eb755fea9e0006c2c040072f74bb',
commonKeychain: '123',
walletHSMGPGPublicKeySigs: '123',
verifiedVssProof: true,
keyShares: [
{
from: 'bitgo',
to: 'user',
publicShare: 'ccc',
privateShare: 'ccc private',
paillierPublicKey: 'ccc paillier',
vssProof: 'ccc vss proof',
},
{
from: 'bitgo',
to: 'backup',
publicShare: 'fff',
privateShare: 'fff private',
paillierPublicKey: 'fff paillier',
vssProof: 'fff vss proof',
},
],
};
const ovcOutputJson = {
tssVersion: '0.0.1',
walletType: 'tss',
coin: 'sol',
state: 1,
ovc: {
1: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7o\n=vjgl\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7ozjMEZBsq\n9RYJKwYBBAHaRw8BAQdAS1534LdCC60ASpEgnEBC8pWPSOWWBLXyWaBhEOW2\n/ijCeAQYEwgACQUCZBsq9QIbIAAhCRDlHgu0Kxi/thYhBIzerz1BUcHlbQyh\nWeUeC7QrGL+2FUYA/AgMU4V7C7I/5HwK73mctaGXNdfVr/muRMNOGW/CAxVL\nAP9KaBr95o32oEN5eo7tWFByoOCCk9JMjs36Cq7o+sR31A==\n=eZ3B\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
2: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh2w==\n=Ettu\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEe1nYNv9DnHl8HX8jNs3reGs5nPT2bNzGMCFL0N3P\nKLwGd8DBkDJIMpoClaAS/HTUTPTRzj4U1GShV79I+bbfTDBV6uhyfZ7a88dV\nRDTXl6rchFl/fmwLoXnqH+BDPEXytpAvKwDrAg55T/H7aop5QbfSsQErEv7X\nTpTLHHHflEEQL62p1Rnnq2kKvwJK7TY1g5RtPgYXH6GEs33DLulPeUs8UkKq\nTPLf2+1KCLYyzMwmSi8KEC8HJb0vAkXZAlZ1+DoZ2PfiIJcVnz7a3omjiP77\nhmC8phTcJ718UxIB09f8uic0/fM7FNu0JHFgRDA69zzeFYnZc2XNQg5hs/dZ\nZ8AitP4rnaAfprsq4rAEE/c3Trm9tzQHZPCqr/2s4LluyUMVJw==\n=IJZH\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 3,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQIVTmlt8a/fjJCY9UyP8J51eTPX9PMRF3/Hr\nBYwtfOZYwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZcthAQD4ek3aqUDEbhfRHolm4jFhIPIbb9hUJwuBR0R4\n+gvaeAEAk8uk5cEACeqmpdEF52oGx7jmGCoX73AIILYVcf9iMkI=\n=92Hf\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
ovcToOvcShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4D+F3vI962zVMSAgMENy2X9xDIOm1gwOfMdL/1vZjeMW/ile/f2dRIP2GV\nv4w60K92+mHI9yooU1VT77jZrVOcNK41DFNCF/fuoUU+VzBON0I1hHyXm2QJ\nwL+nNdvAXwRv7nSFD3ABUmRYdG71AFIWjW2L+1C2hxpsNlmdxffSsQHHT9uP\nBNpFYgQN77OUxcgrweSVrPyer1rCQ8o+QnoK2/hIx9PlJZkcl3uwF6TpBtjs\nqvRxThomoHyo0hJHG0vmI42Gq5u0tcSeU902efpCDaeJhPVOiqISoJ96wn0r\nFB3lYLSflOpCLAE7nsZJRoXA6akU7xMCMNA++d4tv6p98FQ+MZ6e9x6kiSw1\nM+VWj+PvN1dtQ8fNYwpJf7KBfD1w6ISMFDmewkDE7iBOXF6FLw==\n=+3Yc\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 1,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQNVGg0vPsfK1yJjFuDYB8Tj7CQRHKGAVEDcj\nh/QIqr0KwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZS9oAQCe2zJD5ItW2GEgAitnY+NrLBjbXI6+LY29GjRa\nf6yFTQD/cP0E1DleqXMjgfR+ewt6quVFMZebhr3tBr/H0Zv/9EA=\n=8ai+\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
},
};
const expectedBitGoOutput = {
wallet: {
...ovcOutputJson,
state: 2,
platform: {
commonKeychain: bitGoKeyResult.commonKeychain,
walletGpgPubKeySigs: bitGoKeyResult.walletHSMGPGPublicKeySigs,
ovc: {
1: {
bitgoToOvcShare: {
i: 1,
j: 3,
publicShare: bitGoKeyResult.keyShares[0].publicShare,
privateShare: bitGoKeyResult.keyShares[0].privateShare,
paillierPublicKey: bitGoKeyResult.keyShares[0].paillierPublicKey,
vssProof: bitGoKeyResult.keyShares[0].vssProof,
},
},
2: {
bitgoToOvcShare: {
i: 2,
j: 3,
publicShare: bitGoKeyResult.keyShares[1].publicShare,
privateShare: bitGoKeyResult.keyShares[1].privateShare,
paillierPublicKey: bitGoKeyResult.keyShares[1].paillierPublicKey,
vssProof: bitGoKeyResult.keyShares[1].vssProof,
},
},
},
},
},
};
it('Parses the OVC JSON file properly and creates the next input for OVC', async function () {
nock(bgUrl)
.post('/api/v2/tsol/key', _.matches({ source: 'bitgo', keyType: 'tss' }))
.reply(200, bitGoKeyResult);
const platformOutput = await bitgo.coin('tsol').keychains().createTssBitGoKeyFromOvcShares(ovcOutputJson);
should.equal(platformOutput.bitGoKeyId, bitGoKeyResult.id);
should.deepEqual(platformOutput.bitGoOutputJsonForOvc, expectedBitGoOutput);
});
it('Passes the enterprise with correct value to bitgo if provided by caller', async function () {
const bitgoNock = nock(bgUrl)
.post('/api/v2/tsol/key', _.matches({ source: 'bitgo', keyType: 'tss' }))
.reply(200, (uri, body) => {
body.should.have.property('enterprise');
body.enterprise.should.equal('enterpriseId');
return bitGoKeyResult;
});
const platformOutput = await bitgo
.coin('tsol')
.keychains()
.createTssBitGoKeyFromOvcShares(ovcOutputJson, 'enterpriseId');
should.equal(platformOutput.bitGoKeyId, bitGoKeyResult.id);
should.deepEqual(platformOutput.bitGoOutputJsonForOvc, expectedBitGoOutput);
bitgoNock.isDone();
});
it('Should fail if the state is not 1', async function () {
const ovcOutputJson = {
tssVersion: '0.0.1',
walletType: 'tss',
coin: 'sol',
state: 0,
ovc: {
1: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7o\n=vjgl\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7ozjMEZBsq\n9RYJKwYBBAHaRw8BAQdAS1534LdCC60ASpEgnEBC8pWPSOWWBLXyWaBhEOW2\n/ijCeAQYEwgACQUCZBsq9QIbIAAhCRDlHgu0Kxi/thYhBIzerz1BUcHlbQyh\nWeUeC7QrGL+2FUYA/AgMU4V7C7I/5HwK73mctaGXNdfVr/muRMNOGW/CAxVL\nAP9KaBr95o32oEN5eo7tWFByoOCCk9JMjs36Cq7o+sR31A==\n=eZ3B\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
2: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh2w==\n=Ettu\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEe1nYNv9DnHl8HX8jNs3reGs5nPT2bNzGMCFL0N3P\nKLwGd8DBkDJIMpoClaAS/HTUTPTRzj4U1GShV79I+bbfTDBV6uhyfZ7a88dV\nRDTXl6rchFl/fmwLoXnqH+BDPEXytpAvKwDrAg55T/H7aop5QbfSsQErEv7X\nTpTLHHHflEEQL62p1Rnnq2kKvwJK7TY1g5RtPgYXH6GEs33DLulPeUs8UkKq\nTPLf2+1KCLYyzMwmSi8KEC8HJb0vAkXZAlZ1+DoZ2PfiIJcVnz7a3omjiP77\nhmC8phTcJ718UxIB09f8uic0/fM7FNu0JHFgRDA69zzeFYnZc2XNQg5hs/dZ\nZ8AitP4rnaAfprsq4rAEE/c3Trm9tzQHZPCqr/2s4LluyUMVJw==\n=IJZH\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 3,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQIVTmlt8a/fjJCY9UyP8J51eTPX9PMRF3/Hr\nBYwtfOZYwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZcthAQD4ek3aqUDEbhfRHolm4jFhIPIbb9hUJwuBR0R4\n+gvaeAEAk8uk5cEACeqmpdEF52oGx7jmGCoX73AIILYVcf9iMkI=\n=92Hf\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
ovcToOvcShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4D+F3vI962zVMSAgMENy2X9xDIOm1gwOfMdL/1vZjeMW/ile/f2dRIP2GV\nv4w60K92+mHI9yooU1VT77jZrVOcNK41DFNCF/fuoUU+VzBON0I1hHyXm2QJ\nwL+nNdvAXwRv7nSFD3ABUmRYdG71AFIWjW2L+1C2hxpsNlmdxffSsQHHT9uP\nBNpFYgQN77OUxcgrweSVrPyer1rCQ8o+QnoK2/hIx9PlJZkcl3uwF6TpBtjs\nqvRxThomoHyo0hJHG0vmI42Gq5u0tcSeU902efpCDaeJhPVOiqISoJ96wn0r\nFB3lYLSflOpCLAE7nsZJRoXA6akU7xMCMNA++d4tv6p98FQ+MZ6e9x6kiSw1\nM+VWj+PvN1dtQ8fNYwpJf7KBfD1w6ISMFDmewkDE7iBOXF6FLw==\n=+3Yc\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 1,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQNVGg0vPsfK1yJjFuDYB8Tj7CQRHKGAVEDcj\nh/QIqr0KwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZS9oAQCe2zJD5ItW2GEgAitnY+NrLBjbXI6+LY29GjRa\nf6yFTQD/cP0E1DleqXMjgfR+ewt6quVFMZebhr3tBr/H0Zv/9EA=\n=8ai+\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
},
};
await bitgo
.coin('tsol')
.keychains()
.createTssBitGoKeyFromOvcShares(ovcOutputJson)
.should.be.rejectedWith('State expected to be "1". Please complete the first two OVC operations');
});
it('Fails to decode if the OVC json is missing fields', async function () {
const ovcOutputJson = {
tssVersion: '0.0.1',
state: 1,
coin: 'tsol',
ovc: {
1: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7o\n=vjgl\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7ozjMEZBsq\n9RYJKwYBBAHaRw8BAQdAS1534LdCC60ASpEgnEBC8pWPSOWWBLXyWaBhEOW2\n/ijCeAQYEwgACQUCZBsq9QIbIAAhCRDlHgu0Kxi/thYhBIzerz1BUcHlbQyh\nWeUeC7QrGL+2FUYA/AgMU4V7C7I/5HwK73mctaGXNdfVr/muRMNOGW/CAxVL\nAP9KaBr95o32oEN5eo7tWFByoOCCk9JMjs36Cq7o+sR31A==\n=eZ3B\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
},
};
await bitgo.coin('tsol').keychains().createTssBitGoKeyFromOvcShares(ovcOutputJson).should.be.rejected();
});
it('OvcShare codec decodes correctly', async function () {
const test = {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
};
const decodedRes = (0, sdk_core_1.decodeOrElse)(sdk_core_1.OvcShare.name, sdk_core_1.OvcShare, test, (errors) => {
throw new Error(`error(s) parsing parsing json: ${errors}`);
});
assert.ok(decodedRes);
});
});
it('should generate backup without encryptedPrv when passphrase not provided', async () => {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', (body) => {
return body.encryptedPrv === undefined && body.prv === undefined;
})
.reply(200);
const backup = await keychains.createBackup({});
scope.isDone().should.be.true();
backup.should.not.have.property('encryptedPrv');
backup.should.have.property('prv');
});
it('should generate backup and call endpoint with encryptedPrv when passphrase is provided', async () => {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', (body) => {
return body.encryptedPrv !== undefined && body.prv === undefined;
})
.reply(200);
const backup = await keychains.createBackup({ passphrase: 't3stSicretly!' });
scope.isDone().should.be.true();
backup.should.have.property('encryptedPrv');
const decryptedPrv = await bitgo.decrypt({ input: backup.encryptedPrv, password: 't3stSicretly!' });
decryptedPrv.should.startWith('xprv');
});
describe('Rotate OFC multi-user-key keychains', function () {
let ofcBaseCoin;
let ofcKeychains;
const mockOfcKeychain = {
id: 'ofcKeychainId',
pub: 'ofcKeychainPub',
encryptedPrv: 'ofcEncryptedPrv',
source: 'user',
coinSpecific: {
ofc: {
features: ['multi-user-key'],
},
},
type: 'tss',
};
let nonOfcBaseCoin;
let nonOfcKeychains;
const mockNonOfcKeychain = {
id: 'nonOfcKeychainId',
pub: 'nonOfcKeychainPub',
source: 'user',
type: 'tss',
};
const mockNewKeypair = {
pub: 'newPub',
prv: 'newPrv',
};
let sandbox;
let updateKeychainStub;
let createKeypairStub;
let encryptionStub;
beforeEach(function () {
ofcBaseCoin = bitgo.coin('ofc');
ofcKeychains = ofcBaseCoin.keychains();
nonOfcBaseCoin = bitgo.coin('hteth');
nonOfcKeychains = nonOfcBaseCoin.keychains();
sandbox = sinon.createSandbox();
updateKeychainStub = sandbox.stub().returns({ result: sandbox.stub().resolves() });
sandbox.stub(bitgo_1.BitGo.prototype, 'put').returns({ send: updateKeychainStub });
createKeypairStub = sandbox.stub(ofcKeychains, 'create').returns(mockNewKeypair);
encryptionStub = sandbox.stub(bitgo_1.BitGo.prototype, 'encrypt').resolves('newEncryptedPrv');
});
afterEach(function () {
sandbox.restore();
});
it('should rotate ofc multi-user-key properly', async function () {
nock(bgUrl).get(`/api/v2/ofc/key/${mockOfcKeychain.id}`).query(true).reply(200, mockOfcKeychain);
await ofcKeychains.rotateKeychain({ id: mockOfcKeychain.id, password: '1234' });
sinon.assert.called(createKeypairStub);
sinon.assert.calledWith(encryptionStub, { input: mockNewKeypair.prv, password: '1234', encryptionVersion: 2 });
sinon.assert.calledWith(updateKeychainStub, {
pub: mockNewKeypair.pub,
encryptedPrv: 'newEncryptedPrv',
reqId: undefined,
});
});
it('should allow user to supply pub and encryptedPrv directly', async function () {
nock(bgUrl).get(`/api/v2/ofc/key/${mockOfcKeychain.id}`).query(true).reply(200, mockOfcKeychain);
await ofcKeychains.rotateKeychain({ id: mockOfcKeychain.id, pub: 'pub', encryptedPrv: 'encryptedPrv' });
sinon.assert.notCalled(createKeypairStub);
sinon.assert.notCalled(encryptionStub);
sinon.assert.calledWith(updateKeychainStub, {
pub: 'pub',
encryptedPrv: 'encryptedPrv',
reqId: undefined,
});
});
it('should throw when trying to rotate non-ofc keychain', async function () {
nock(bgUrl).get(`/api/v2/hteth/key/${mockNonOfcKeychain.id}`).query(true).reply(200, mockNonOfcKeychain);
await assert.rejects(async () => await nonOfcKeychains.rotateKeychain({ id: mockNonOfcKeychain.id, password: '1234' }), (err) => err.message === 'rotateKeychain is only permitted for ofc multi-user-key wallet');
});
});
describe('getEncryptionVersion', function () {
it('returns 1 when the v field is absent', function () {
const envelope = JSON.stringify({ ct: 'cipher', iv: 'iv', s: 'salt' });
keychains.getEncryptionVersion(envelope).should.equal(1);
});
it('returns 1 when v is explicitly 1', function () {
keychains.getEncryptionVersion(JSON.stringify({ v: 1, ct: 'abc' })).should.equal(1);
});
it('returns 2 when v is 2', function () {
keychains.getEncryptionVersion(JSON.stringify({ v: 2, ct: 'abc' })).should.equal(2);
});
it('throws on an unrecognized version number', function () {
assert.throws(() => keychains.getEncryptionVersion(JSON.stringify({ v: 3, ct: 'abc' })), /Unrecognized encryption version: 3/);
});
it('throws when the input is not valid JSON', function () {
assert.throws(() => keychains.getEncryptionVersion('not-json'), /Failed to parse ciphertext envelope/);
});
it('throws when the input is an empty string', function () {
assert.throws(() => keychains.getEncryptionVersion(''), /Failed to parse ciphertext envelope/);
});
it('handles a real SJCL v1 envelope', function () {
const sjcl = JSON.stringify({
iv: 'aaaa',
v: 1,
iter: 10000,
ks: 256,
ts: 64,
mode: 'ccm',
adata: '',
cipher: 'aes',
salt: 'ssss',
ct: 'cccc',
});
keychains.getEncryptionVersion(sjcl).should.equal(1);
});
it('handles a real Argon2id v2 envelope', function () {
const argon2 = JSON.stringify({
v: 2,
ct: 'cccc',
iv: 'iiii',
tag: 'tttt',
salt: 'ssss',
m: 65536,
t: 3,
p: 4,
});
keychains.getEncryptionVersion(argon2).should.equal(2);
});
});
describe('reencryptAsV2', function () {
it('decrypts a v1 envelope with the passphrase and re-encrypts as v2', async function () {
const prv = 'thePrivateKey';
const encryptedV1 = await bitgo.encrypt({ input: prv, password: 'myPass', encryptionVersion: 1 });
JSON.parse(encryptedV1).v.should.equal(1);
const result = await keychains.reencryptAsV2(encryptedV1, 'myPass');
JSON.parse(result).v.should.equal(2);
(await bitgo.decrypt({ input: result, password: 'myPass' })).should.equal(prv);
});
it('accepts a v2 envelope and re-encrypts it as v2 (idempotent)', async function () {
const prv = 'xprv-v2';
const encryptedV2 = await bitgo.encrypt({ input: prv, password: 'pass', encryptionVersion: 2 });
JSON.parse(encryptedV2).v.should.equal(2);
const result = await keychains.reencryptAsV2(encryptedV2, 'pass');
JSON.parse(result).v.should.equal(2);
(await bitgo.decrypt({ input: result, password: 'pass' })).should.equal(prv);
});
it('surfaces decrypt errors directly (no fallback logic in the primitive)', async function () {
const encrypted = await bitgo.encrypt({ input: 'prv', password: 'realPass', encryptionVersion: 1 });
await keychains.reencryptAsV2(encrypted, 'wrongPass').should.be.rejected();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2hhaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2tleWNoYWlucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLHFCQUFxQjtBQUNyQixFQUFFOztBQUVGLDRDQUF3RjtBQUN4RixpQ0FBaUM7QUFDakMsNEJBQTRCO0FBQzVCLDZCQUE4QjtBQUM5QixpQ0FBa0M7QUFDbEMsK0JBQStCO0FBRS9CLDhDQUE4RztBQUM5Ryw4Q0FBNEM7QUFDNUMsOENBQTJDO0FBRzNDLFFBQVEsQ0FBQyxjQUFjLEVBQUU7SUFDdkIsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksU0FBUyxDQUFDO0lBQ2QsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWpDLEtBQUssR0FBRyxpQkFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLO1lBQy9CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ3RCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLElBQUk7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLHlCQUF5QixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztnQkFDekUsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQixNQUFNLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLHlCQUF5QixFQUFFLDJCQUEyQixFQUFFLENBQUMsQ0FBQztZQUM1RixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDZixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUg7Ozs7UUFJSTtJQUNKLFFBQVEsQ0FBQywwQ0FBMEMsRUFBRTtRQUNuRCwwQ0FBMEM7UUFDMUMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLG9CQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sZUFBZSxHQUFHLGVBQUssQ0FBQyxNQUFNLENBQ2xDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDSixDQUFDLENBQUMsZUFBZSxLQUFLLGtCQUFRLENBQUMsU0FBUztZQUN4QyxDQUFDLENBQUMsSUFBSSxLQUFLLGtCQUFRLENBQUMsTUFBTTtZQUMxQixDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRztZQUMvQixDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsS0FBSztZQUNqQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsUUFBUTtZQUNwQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsSUFBSTtZQUNoQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsSUFBSTtZQUNoQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsVUFBVTtZQUN0QyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsTUFBTTtZQUNsQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsSUFBSTtZQUNoQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsSUFBSTtZQUNoQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsTUFBTSxJQUFJLDJFQUEyRTtZQUNqSCxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsS0FBSyxJQUFJLDBFQUEwRTtZQUMvRyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsS0FBSyxJQUFJLDJFQUEyRTtZQUNoSCxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRyxJQUFJLHlFQUF5RTtZQUM1RyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsT0FBTyxJQUFJLDZFQUE2RTtZQUNwSCxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRyxJQUFJLHlFQUF5RTtZQUM1RyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRyxJQUFJLHlFQUF5RTtZQUM1RyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsS0FBSyxJQUFJLDJFQUEyRTtZQUNoSCxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRyxJQUFJLHlFQUF5RTtZQUM1RyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsSUFBSTtZQUNoQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsSUFBSTtZQUNoQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRztZQUMvQixDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsTUFBTTtZQUNsQyxDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsR0FBRztZQUMvQixDQUFDLENBQUMsS0FBSyxLQUFLLHlCQUFlLENBQUMsRUFBRTtZQUM5QixDQUFDLENB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QUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUUxQyxNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1RUFBdUUsRUFBRSxLQUFLO1lBQy9FLE1BQU0sU0FBUyxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3BHLE1BQU0sU0FBUyxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsV0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUM3RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvL1xuLy8gVGVzdCBmb3IgS2V5Y2hhaW5zXG4vL1xuXG5pbXBvcnQgeyBDb2luRmFtaWx5LCBDb2luS2luZCwgY29pbnMsIEtleUN1cnZlLCBVbmRlcmx5aW5nQXNzZXQgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBub2NrID0gcmVxdWlyZSgnbm9jaycpO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuXG5pbXBvcnQgeyBjb21tb24sIGRlY29kZU9yRWxzZSwgRUNEU0FVdGlscywgRUREU0FVdGlscywgS2V5Y2hhaW4sIEtleWNoYWlucywgT3ZjU2hhcmUgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2JpdGdvJztcbmltcG9ydCB7IFNpbm9uU3R1YiB9IGZyb20gJ3Npbm9uJztcblxuZGVzY3JpYmUoJ1YyIEtleWNoYWlucycsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvO1xuICBsZXQgYmFzZWNvaW47XG4gIGxldCBrZXljaGFpbnM7XG4gIGxldCBiZ1VybDtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJpdGdvLnNldFZhbGlkYXRlKGZhbHNlKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RsdGMnKTtcbiAgICBrZXljaGFpbnMgPSBiYXNlY29pbi5rZXljaGFpbnMoKTtcblxuICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkIEtleWNoYWluJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgYWRkIGEga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RsdGMva2V5JywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnB1Yi5zaG91bGQuZXF1YWwoJ3B1YicpO1xuICAgICAgICAgIGJvZHkuZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZC5zaG91bGQuZXF1YWwoJ2Rlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQga2V5Y2hhaW5zLmFkZCh7IHB1YjogJ3B1YicsIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6ICdkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkJyB9KTtcbiAgICAgIHNjb3BlLmRvbmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqIFRoaXMgc2VjdGlvbidzIGludGVudGlvbiBpcyB0byBwcm92aWRlIHNvbWUga2V5IGdlbmVyYXRpb24gc2FuaXR5IGNoZWNraW5nLiBnZW5lcmF0ZUtleVBhaXIgaXMgYSBnZW5lcmFsIHN1cmZhY2VcbiAgICogZm9yIGtleSBnZW5lcmF0aW9uIGJ1dCB0aGUga2V5cyBhcmUgdHJlYXRlZCB0aGUgc2FtZSBieSBCaXRHbyBkb3duIHRoZSBsaW5lLiBBbnkgU0VDUDI1NksxIGJhc2VkIGNvaW5zIGtleS1wYWlycyBjYW5cbiAgICogYmUgcmUtdXNlZCBzbyBuZWVkIHRvIGJlIHRoZSBzYW1lLlxuICAgKiovXG4gIGRlc2NyaWJlKCdLZXkgZ2VuZXJhdGlvbiBlbmZvcmNlbWVudCBmb3IgU0VDUDI1NksxJywgZnVuY3Rpb24gKCkge1xuICAgIC8vIGl0ZXJhdGUgb3ZlciBub24tZmlhdCBjcnlwdG8gc2VjcCBjb2luc1xuICAgIGNvbnN0IGNvaW5GYW1pbHlWYWx1ZXMgPSBPYmplY3Qua2V5cyhDb2luRmFtaWx5KS5tYXAoKG4pID0+IG4udG9Mb3dlckNhc2UoKSk7XG4gICAgY29uc3QgY3J5cHRvU2VjcENvaW5zID0gY29pbnMuZmlsdGVyKFxuICAgICAgKG4pID0+XG4gICAgICAgIG4ucHJpbWFyeUtleUN1cnZlID09PSBLZXlDdXJ2ZS5TZWNwMjU2azEgJiZcbiAgICAgICAgbi5raW5kID09PSBDb2luS2luZC5DUllQVE8gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlVTRCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQVZBWFAgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkFQRUNIQUlOICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5ET0dFICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5FVEhXICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5LQVZBQ09TTU9TICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5DT1JFVU0gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkJFUkEgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LklTTE0gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkFSQkVUSCAmJiAvLyBUT0RPKFdJTi02OTIpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBhcmJldGggaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk9QRVRIICYmIC8vIFRPRE8oV0lOLTY5Mik6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIG9wZXRoIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5aS0VUSCAmJiAvLyBUT0RPKFdJTi0xNDI3KTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgemtldGggaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk9BUyAmJiAvLyBUT0RPKFdJTi0zNjk2KTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3Igb2FzIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5DT1JFREFPICYmIC8vIFRPRE8oV0lOLTM2OTYpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBjb3JlZGFvIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5GTFIgJiYgLy8gVE9ETyhXSU4tNDIxNSk6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIEZMUiBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuU0dCICYmIC8vIFRPRE8oV0lOLTQyMTYpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBTR0IgaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LldFTUlYICYmIC8vIFRPRE8oV0lOLTQxNzcpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBXRU1JWCBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuWERDICYmIC8vIFRPRE8oV0lOLTQxNzMpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBYREMgaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlJVTkUgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkJBQlkgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LklDUCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuTUFOVFJBICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5NT04gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk9HICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5XT1JMRCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuUEhSUyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQ1RDICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5IWVBFRVZNICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5YUEwgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlNPTkVJVU0gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlZFVCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQ1JPTk9TICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5GRVRDSEFJICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5JTklUSUEgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkFTSSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuU09OSUMgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlNFSUVWTSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuS0FJQSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSVJZUyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuTElORUFFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LklQICYmIC8vIFN0b3J5IENoYWluXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5CQVNFRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5TT01JICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5GTFJQICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5GTFVFTlRFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1BTlRMRSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSE9PREVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSFBQRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5KT1ZBWUVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuT0tCWExBWUVSICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5VTklFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1PUlBIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5NT1JQSEVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuRE9HRU9TICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5NRUdBRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5BUkNVU0RDICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5aS1NZTkNFUkEgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkhZUEVSTElRVUlEICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5CT0JBRVRIICYmXG4gICAgICAgIGNvaW5GYW1pbHlWYWx1ZXMuaW5jbHVkZXMobi5uYW1lKVxuICAgICk7XG5cbiAgICBjb25zdCBleHBlY3RlZFhwdWIgPVxuICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHcFpmOG14TldoU1BkV2FMR3ZRenphZ2U2dnEyb1FGenE4dG9Wem1ranlnWVozSGNadzZlQ3pBZm45WmR5R2pLb0trY3BLd2Fja2Rnem5WYml1bnBxN3JreER1N3F1Uyc7XG4gICAgY29uc3QgZXhwZWN0ZWRYcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLNExWQzJrUk45WlZmNVVqcXNUaDlkTW0zSllSUkY0ajF4TFpleFRUV0NCTjRobWRaVUhlVDN2Q0pQTDE4MUVyVmFZNDg5QXJCS1NXYUI3RHU3dnlWUzZYQzQzV3RLN0EnO1xuXG4gICAgY29uc3Qgc2VlZCA9IEJ1ZmZlci5mcm9tKCd0aGlzIGlzIHNvbWUgcmFuZG9tIHNlZWQgd2Ugd2lsbCB1c2UnLCAndXRmLTgnKTtcblxuICAgIGNyeXB0b1NlY3BDb2lucy5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSB0aGUgc2FtZSAke2NvaW4ubmFtZX0ga2V5IHdpdGggdGhlIHNhbWUgc2VlZGAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudENvaW4gPSBiaXRnby5jb2luKGNvaW4ubmFtZSk7XG4gICAgICAgIGNvbnN0IGtleVBhaXIgPSBjdXJyZW50Q29pbi5nZW5lcmF0ZUtleVBhaXIoc2VlZCk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGtleVBhaXIucHViKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KGtleVBhaXIucHJ2KTtcblxuICAgICAgICBrZXlQYWlyLnB1Yi5zaG91bGQuZXF1YWwoZXhwZWN0ZWRYcHViKTtcbiAgICAgICAga2V5UGFpci5wcnYuc2hvdWxkLmVxdWFsKGV4cGVjdGVkWHBydik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1VwZGF0ZSBQYXNzd29yZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvbGRQYXNzd29yZCA9ICdvbGRQYXNzd29yZCc7XG4gICAgY29uc3QgbmV3UGFzc3dvcmQgPSAnbmV3UGFzc3dvcmQnO1xuICAgIGNvbnN0IG90aGVyUGFzc3dvcmQgPSAnb3RoZXJQYXNzd29yZCc7XG5cbiAgICBkZXNjcmliZSgnc2hvdWxkIGZhaWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgc2FuZGJveDtcbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd0byB1cGRhdGUgdGhlIHBhc3N3b3JkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlUGFzc3dvcmQoeyBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBvbGRQYXNzd29yZCcpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAxMjM0LCBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiBvbGRQYXNzd29yZCBidXQgZm91bmQgbnVtYmVyJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHBhcmFtZXRlcjogbmV3UGFzc3dvcmQnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnLCBuZXdQYXNzd29yZDogNTY3OCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogbmV3UGFzc3dvcmQgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd0byB1cGRhdGUgdGhlIHBhc3N3b3JkIGZvciBhIHNpbmdsZSBrZXljaGFpbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKCgpID0+IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KSkuc2hvdWxkLnRocm93KFxuICAgICAgICAgICdleHBlY3RlZCBvbGQgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnXG4gICAgICAgICk7XG5cbiAgICAgICAgKCgpID0+IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6IDEyMzQsIG5ld1Bhc3N3b3JkOiAnNTY3OCcgfSkpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAnZXhwZWN0ZWQgb2xkIHBhc3N3b3JkIHRvIGJlIGEgc3RyaW5nJ1xuICAgICAgICApO1xuXG4gICAgICAgICgoKSA9PiBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcgfSkpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAnZXhwZWN0ZWQgbmV3IHBhc3N3b3JkIHRvIGJlIGEgc3RyaW5nJ1xuICAgICAgICApO1xuXG4gICAgICAgICgoKSA9PiBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiA1Njc4IH0pKS5zaG91bGQudGhyb3coKTtcblxuICAgICAgICAoKCkgPT4ga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnLCBuZXdQYXNzd29yZDogJzU2NzgnIH0pKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgJ2V4cGVjdGVkIGtleWNoYWluIHRvIGJlIGFuIG9iamVjdCB3aXRoIGFuIGVuY3J5cHRlZFBydiBwcm9wZXJ0eSdcbiAgICAgICAgKTtcblxuICAgICAgICAoKCkgPT5cbiAgICAgICAgICBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZDogJzEyMzQnLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQ6ICc1Njc4JyxcbiAgICAgICAgICAgIGtleWNoYWluOiB7fSxcbiAgICAgICAgICB9KSkuc2hvdWxkLnRocm93KCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICAoKCkgPT5cbiAgICAgICAgICBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZDogJzEyMzQnLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQ6ICc1Njc4JyxcbiAgICAgICAgICAgIGtleWNoYWluOiB7IGVuY3J5cHRlZFBydjogMTIzIH0sXG4gICAgICAgICAgfSkpLnNob3VsZC50aHJvdygnZXhwZWN0ZWQga2V5Y2hhaW4gdG8gYmUgYW4gb2JqZWN0IHdpdGggYW4gZW5jcnlwdGVkUHJ2IHByb3BlcnR5Jyk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KSB9O1xuICAgICAgICAoKCkgPT4ga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQsIGtleWNoYWluIH0pKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgJ3Bhc3N3b3JkIHVzZWQgdG8gZGVjcnlwdCBrZXljaGFpbiBwcml2YXRlIGtleSBpcyBpbmNvcnJlY3QnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3RvIHVwZGF0ZSB0aGUgcGFzc3dvcmQgZm9yIGEgc2luZ2xlIGtleWNoYWluIChhc3luYyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBvbGQgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAxMjM0LCBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIG9sZCBwYXNzd29yZCB0byBiZSBhIHN0cmluZycpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBuZXcgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiA1Njc4IH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIG5ldyBwYXNzd29yZCB0byBiZSBhIHN0cmluZycpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JywgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiAnNTY3OCcsIGtleWNoYWluOiB7fSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZDogJzEyMzQnLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQ6ICc1Njc4JyxcbiAgICAgICAgICAgIGtleWNoYWluOiB7IGVuY3J5cHRlZFBydjogMTIzIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZXhwZWN0ZWQga2V5Y2hhaW4gdG8gYmUgYW4gb2JqZWN0IHdpdGggYW4gZW5jcnlwdGVkUHJ2IHByb3BlcnR5Jyk7XG5cbiAgICAgICAgLy8gd3JvbmcgcGFzc3dvcmQg4oCUIGRlY3J5cHQgZmFpbHNcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KSB9O1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCwga2V5Y2hhaW4gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmFpbGVkIHRvIHVwZGF0ZSBrZXljaGFpbiBwYXNzd29yZDogaW5jb3JyZWN0IHBhc3N3b3JkJyk7XG5cbiAgICAgICAgLy8gaW52YWxpZCBKU09OIGluIGVuY3J5cHRlZFBydlxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCwga2V5Y2hhaW46IHsgZW5jcnlwdGVkUHJ2OiAnbm90LXZhbGlkLWpzb24nIH0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmFpbGVkIHRvIHVwZGF0ZSBrZXljaGFpbiBwYXNzd29yZDogZGVjcnlwdDogY2lwaGVydGV4dCBpcyBub3QgdmFsaWQgSlNPTicpO1xuXG4gICAgICAgIC8vIHVua25vd24gZW52ZWxvcGUgdmVyc2lvblxuICAgICAgICBjb25zdCB1bmtub3duVmVyc2lvbkVudmVsb3BlID0gSlNPTi5zdHJpbmdpZnkoeyB2OiA5OSwgY3Q6ICdhYmMnIH0pO1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZCxcbiAgICAgICAgICAgIG5ld1Bhc3N3b3JkLFxuICAgICAgICAgICAga2V5Y2hhaW46IHsgZW5jcnlwdGVkUHJ2OiB1bmtub3duVmVyc2lvbkVudmVsb3BlIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmFpbGVkIHRvIHVwZGF0ZSBrZXljaGFpbiBwYXNzd29yZDogZGVjcnlwdDogdW5rbm93biBlbnZlbG9wZSB2ZXJzaW9uIDk5Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ29uIGFueSBvdGhlciBlcnJvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZW5jWHBydjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViMScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWlucywgJ3VwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQnKS50aHJvd3MoJ2Vycm9yJywgJ3NvbWUgcmFuZG9tIGVycm9yJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3NvbWUgcmFuZG9tIGVycm9yJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzdWNjZXNzZnVsIHBhc3N3b3JkIHVwZGF0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRlS2V5cyA9IGFzeW5jIGZ1bmN0aW9uIChrZXlzLCBuZXdQYXNzd29yZCwgZXhwZWN0ZWRMZW5ndGgpIHtcbiAgICAgICAgYXNzZXJ0Lm9rKE9iamVjdC5rZXlzKGtleXMpLmxlbmd0aCA9PT0gZXhwZWN0ZWRMZW5ndGgsICdzaG91bGQgaGF2ZSB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIGtleXMnKTtcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoa2V5cykpIHtcbiAgICAgICAgICBhc3NlcnQub2soa2V5LmluY2x1ZGVzKCd4cHViJykgfHwga2V5LmluY2x1ZGVzKCdyYW5kb21pZCcpLCAna2V5IHNob3VsZCBiZSB4cHViIG9yIHJhbmRvbWlkJyk7XG4gICAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiB2YWx1ZSBhcyBzdHJpbmcsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLnN0YXJ0V2l0aCgneHBydicpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpdCgncmVjZWl2ZSBvbmx5IG9uZSBwYWdlIHdoZW4gbGlzdGluZyBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjInLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjMgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MycsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViMScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWIyJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYyLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyYW5kb21pZDEnLFxuICAgICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjMsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgYXdhaXQgdmFsaWRhdGVLZXlzKGtleXMsIG5ld1Bhc3N3b3JkLCAyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmVjZWl2ZSBtdWx0aXBsZSBwYWdlcyB3aGVuIGxpc3Rpbmcga2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwcmV2SWQgPSAncHJldklkJztcbiAgICAgICAgY29uc3QgZW5jWHBydjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MicsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2M2EgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MycsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjNiID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjMnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnY0ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjQnLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBuZXh0QmF0Y2hQcmV2SWQ6IHByZXZJZCxcbiAgICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWIxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMScsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2M2EsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi90bHRjL2tleScpXG4gICAgICAgICAgLnF1ZXJ5KGZ1bmN0aW9uIHF1ZXJ5TmV4dFBhZ2VNYXRjaChxdWVyeU9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIHF1ZXJ5T2JqZWN0LnByZXZJZCA9PT0gcHJldklkO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjMnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjNiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjQnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgYXdhaXQgdmFsaWRhdGVLZXlzKGtleXMsIG5ld1Bhc3N3b3JkLCAzKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlIGtleWNoYWluIHBhc3N3b3JkIHVwZGF0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcHJ2ID0gJ3hwcnZ0ZXN0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgeHB1YjogJ3hwdWIxMjMnLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBuZXdLZXljaGFpbiA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsga2V5Y2hhaW4sIG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCB9KTtcblxuICAgICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IG5ld0tleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLmVxdWFsKHBydik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3NpbmdsZSBrZXljaGFpbiBwYXNzd29yZCB1cGRhdGUgZW1pdHMgYSB2MiAoQXJnb24yaWQpIGVudmVsb3BlIGZvciBhIHYyIGlucHV0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBwcnYgPSAneHBydnRlc3QtdjInO1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBlbmNyeXB0aW9uVmVyc2lvbjogMiB9KTtcbiAgICAgICAgY29uc3QgZW52ZWxvcGUgPSBKU09OLnBhcnNlKGVuY3J5cHRlZFBydik7XG4gICAgICAgIGVudmVsb3BlLnYuc2hvdWxkLmVxdWFsKDIsICdwcmUtY29uZGl0aW9uOiBrZXljaGFpbiBtdXN0IGJlIHYyLWVuY3J5cHRlZCcpO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWluID0geyB4cHViOiAneHB1YjEyMycsIGVuY3J5cHRlZFBydiB9O1xuICAgICAgICBjb25zdCBuZXdLZXljaGFpbiA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsga2V5Y2hhaW4sIG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCB9KTtcblxuICAgICAgICBjb25zdCBuZXdFbnZlbG9wZSA9IEpTT04ucGFyc2UobmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KTtcbiAgICAgICAgbmV3RW52ZWxvcGUudi5zaG91bGQuZXF1YWwoMiwgJ3JlLWVuY3J5cHRlZCBrZXljaGFpbiBtdXN0IHN0aWxsIGJlIHYyJyk7XG5cbiAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgZGVjcnlwdGVkUHJ2LnNob3VsZC5lcXVhbChwcnYsICduZXcgcGFzc3dvcmQgbXVzdCBkZWNyeXB0IHRvIG9yaWdpbmFsIHBydicpO1xuXG4gICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogbmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSkuc2hvdWxkLmJlLnJlamVjdGVkKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3NpbmdsZSBrZXljaGFpbiBwYXNzd29yZCB1cGRhdGUgcHJlc2VydmVzIGEgdjEgKFNKQ0wpIGVudmVsb3BlIGJ5IGRlZmF1bHQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBydiA9ICd4cHJ2dGVzdC12MSc7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogcHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQsIGVuY3J5cHRpb25WZXJzaW9uOiAxIH0pO1xuICAgICAgICBKU09OLnBhcnNlKGVuY3J5cHRlZFBydikuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCd2JywgMiwgJ3ByZS1jb25kaXRpb246IGlucHV0IG11c3Qgbm90IGJlIHYyJyk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IHhwdWI6ICd4cHViMTIzJywgZW5jcnlwdGVkUHJ2IH07XG4gICAgICAgIGNvbnN0IG5ld0tleWNoYWluID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBrZXljaGFpbiwgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pO1xuXG4gICAgICAgIEpTT04ucGFyc2UobmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ3YnLCAyLCAndjEga2V5Y2hhaW4gbXVzdCBzdGF5IHYxIGJ5IGRlZmF1bHQnKTtcblxuICAgICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IG5ld0tleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLmVxdWFsKHBydiwgJ25ldyBwYXNzd29yZCBtdXN0IGRlY3J5cHQgdG8gb3JpZ2luYWwgcHJ2Jyk7XG5cbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlIGtleWNoYWluIHBhc3N3b3JkIHVwZGF0ZSB1cGdyYWRlcyBhIHYxIGVudmVsb3BlIHRvIHYyIHdoZW4gZW5jcnlwdGlvblZlcnNpb246IDIgaXMgcGFzc2VkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBwcnYgPSAneHBydnRlc3QtdjEtb3B0LWluJztcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCwgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IHhwdWI6ICd4cHViMTIzJywgZW5jcnlwdGVkUHJ2IH07XG4gICAgICAgIGNvbnN0IG5ld0tleWNoYWluID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoe1xuICAgICAgICAgIGtleWNoYWluLFxuICAgICAgICAgIG9sZFBhc3N3b3JkLFxuICAgICAgICAgIG5ld1Bhc3N3b3JkLFxuICAgICAgICAgIGVuY3J5cHRpb25WZXJzaW9uOiAyLFxuICAgICAgICB9KTtcblxuICAgICAgICBKU09OLnBhcnNlKG5ld0tleWNoYWluLmVuY3J5cHRlZFBydikudi5zaG91bGQuZXF1YWwoMiwgJ3YyIG9wdC1pbiBtdXN0IGVtaXQgYSB2MiBlbnZlbG9wZScpO1xuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogbmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGRlY3J5cHRlZFBydi5zaG91bGQuZXF1YWwocHJ2LCAnbmV3IHBhc3N3b3JkIG11c3QgZGVjcnlwdCB0byBvcmlnaW5hbCBwcnYnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChcInVwZGF0ZVBhc3N3b3JkIHByZXNlcnZlcyBlYWNoIGtleWNoYWluJ3MgZXhpc3RpbmcgZW52ZWxvcGUgdmVyc2lvbiBieSBkZWZhdWx0XCIsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdjFQcnYgPSAneHBydi12MSc7XG4gICAgICAgIGNvbnN0IHYyUHJ2ID0gJ3hwcnYtdjInO1xuXG4gICAgICAgIGNvbnN0IGVuY1YxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiB2MVBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBlbmNyeXB0aW9uVmVyc2lvbjogMSB9KTtcbiAgICAgICAgY29uc3QgZW5jVjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHYyUHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQsIGVuY3J5cHRpb25WZXJzaW9uOiAyIH0pO1xuICAgICAgICBjb25zdCBlbmNPdGhlciA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYtb3RoZXInLCBwYXNzd29yZDogJ2RpZmZlcmVudC1wYXNzd29yZCcgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViLXYxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1YxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1Yi12MicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNWMixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWItb3RoZXInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jT3RoZXIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHVwZGF0ZWRLZXlzID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pO1xuXG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChPYmplY3Qua2V5cyh1cGRhdGVkS2V5cykubGVuZ3RoLCAyLCAnb25seSB0aGUgdHdvIG1hdGNoaW5nIGtleWNoYWlucyBzaG91bGQgYmUgdXBkYXRlZCcpO1xuXG4gICAgICAgIGNvbnN0IHVwZGF0ZWRWMSA9IHVwZGF0ZWRLZXlzWyd4cHViLXYxJ107XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRWMiA9IHVwZGF0ZWRLZXlzWyd4cHViLXYyJ107XG4gICAgICAgIGFzc2VydC5vayh1cGRhdGVkVjEsICd2MSBrZXljaGFpbiBtdXN0IGJlIGluIHRoZSByZXN1bHQnKTtcbiAgICAgICAgYXNzZXJ0Lm9rKHVwZGF0ZWRWMiwgJ3YyIGtleWNoYWluIG11c3QgYmUgaW4gdGhlIHJlc3VsdCcpO1xuXG4gICAgICAgIEpTT04ucGFyc2UodXBkYXRlZFYxKS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ3YnLCAyLCAndjEga2V5Y2hhaW4gbXVzdCBzdGF5IHYxIGJ5IGRlZmF1bHQnKTtcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkVjEgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHVwZGF0ZWRWMSwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRWMS5zaG91bGQuZXF1YWwodjFQcnYpO1xuXG4gICAgICAgIEpTT04ucGFyc2UodXBkYXRlZFYyKS52LnNob3VsZC5lcXVhbCgyLCAndjIga2V5Y2hhaW4gbXVzdCByZW1haW4gdjIgYWZ0ZXIgcGFzc3dvcmQgY2hhbmdlJyk7XG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFYyID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiB1cGRhdGVkVjIsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgZGVjcnlwdGVkVjIuc2hvdWxkLmVxdWFsKHYyUHJ2KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgdXBkYXRlZCBrZXlzIHdpdGggaWRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBlbmNYcHJ2MSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2MiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYyJywgcGFzc3dvcmQ6IG90aGVyUGFzc3dvcmQgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi90bHRjL2tleScpXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyYW5kb21pZDEnLFxuICAgICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMicsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUtleXMoa2V5cywgbmV3UGFzc3dvcmQsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXBkYXRlIG11bHRpLXVzZXItb2ZjIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjInLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgICAgIG9mYzoge1xuICAgICAgICAgICAgICAgICAgICBmZWF0dXJlczogWydtdWx0aS11c2VyLWtleSddLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyYW5kb21pZDInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjIsXG4gICAgICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgICAgICBvZmM6IHtcbiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXM6IFsnbXVsdGktdXNlci1rZXknXSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUtleXMoa2V5cywgbmV3UGFzc3dvcmQsIDEpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQ3JlYXRlIFRTUyBLZXljaGFpbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGxldCBzYW5kYm94O1xuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgWyd0c29sJywgJ3Rkb3QnLCAndG5lYXInXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgY3JlYXRlIEVERFNBIFRTUyBLZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2FuZGJveC5zdHViKEVERFNBVXRpbHMuZGVmYXVsdC5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKS5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGtleWNoYWlucy5zaG91bGQuZGVlcEVxdWFsKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0YnNjJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBFQ0RTQSBUU1MgS2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvaW5TZXR0aW5nczoge30sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKS5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGtleWNoYWlucy5zaG91bGQuZGVlcEVxdWFsKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0c29sJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHBhc3Mgd2ViYXV0aG5JbmZvIHRvIGNyZWF0ZUtleWNoYWlucyBmb3IgRUREU0EgVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdlYmF1dGhuSW5mbyA9IHtcbiAgICAgICAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTEnLFxuICAgICAgICAgICAgcHJmU2FsdDogJ3NhbHQtMScsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiAncHJmLWRlcml2ZWQtcGFzc3BocmFzZScsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjcmVhdGVLZXljaGFpbnMgPSBzYW5kYm94XG4gICAgICAgICAgICAuc3R1YihFRERTQVV0aWxzLmRlZmF1bHQucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJylcbiAgICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICB3ZWJhdXRobkluZm8sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY3JlYXRlS2V5Y2hhaW5zLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICBjcmVhdGVLZXljaGFpbnMuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dlYmF1dGhuSW5mbycsIHdlYmF1dGhuSW5mbyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIFsndGJzYyddLmZvckVhY2goKGNvaW4pID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3Qgc2FmZSByb290IGNyZWF0aW9uIHdoZW4gdGhlIHJlc29sdmVkIGNlcmVtb255IGlzIGxlZ2FjeSBNUEN2MScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjIvdHNzL3NldHRpbmdzJykucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb2luU2V0dGluZ3M6IHt9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBhd2FpdCBiaXRnb1xuICAgICAgICAgICAgLmNvaW4oY29pbilcbiAgICAgICAgICAgIC5rZXljaGFpbnMoKVxuICAgICAgICAgICAgLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgICAgc2FmZUlkOiAnc2FmZUlkJyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvbGVnYWN5IE1QQ3YxIGNlcmVtb255Lyk7XG4gICAgICAgICAgY3JlYXRlS2V5Y2hhaW5zLmNhbGxlZC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0YnNjJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHBhc3Mgd2ViYXV0aG5JbmZvIHRvIGNyZWF0ZUtleWNoYWlucyBmb3IgRUNEU0EgVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvaW5TZXR0aW5nczoge30sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3Qgd2ViYXV0aG5JbmZvID0ge1xuICAgICAgICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMScsXG4gICAgICAgICAgICBwcmZTYWx0OiAnc2FsdC0xJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBhd2FpdCBiaXRnby5jb2luKGNvaW4pLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgIHdlYmF1dGhuSW5mbyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIGNyZWF0ZUtleWNoYWlucy5maXJzdENhbGwuYXJnc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2ViYXV0aG5JbmZvJywgd2ViYXV0aG5JbmZvKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdSZWNyZWF0ZSBLZXljaGFpbnMgZnJvbSBNUENWMSB0byBNUENWMicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSAnaHRldGgnO1xuICAgICAgY29uc3Qgd2FsbGV0SWQgPSAnd2FsbGV0SWQnO1xuICAgICAgY29uc3Qgb3RwID0gJzAwMDAwMCc7XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgICBjb25zdCBkZWNyeXB0UmVzdWx0ID0gSlNPTi5zdHJpbmdpZnkoeyBrZXk6ICdkZWNyeXB0ZWQnIH0pO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY29pblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIGV0aDoge1xuICAgICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKGRlY3J5cHRSZXN1bHQpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIGVtcHR5IHN0cmluZ3MgYXJlIHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXM6IFBhcmFtZXRlcnM8S2V5Y2hhaW5zWydyZWNyZWF0ZU1wYyddPlswXSA9IHtcbiAgICAgICAgICBjb2luLFxuICAgICAgICAgIHdhbGxldElkLFxuICAgICAgICAgIG90cCxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZCcsXG4gICAgICAgICAgICBlbmNyeXB0ZWRCYWNrdXBLZXk6ICdlbmNyeXB0ZWQnLFxuICAgICAgICAgICAgZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZTogJ3Bhc3NwaHJhc2UnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnJlY3JlYXRlTXBjKHsgLi4ucGFyYW1zLCBjb2luOiAnJyB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGNvaW4nKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAucmVjcmVhdGVNcGMoeyAuLi5wYXJhbXMsIHdhbGxldElkOiAnJyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIHdhbGxldElkJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnJlY3JlYXRlTXBjKHsgLi4ucGFyYW1zLCBvdHA6ICcnIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0gb3RwJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnJlY3JlYXRlTXBjKHsgLi4ucGFyYW1zLCBwYXNzcGhyYXNlOiAnJyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIHBhc3NwaHJhc2UnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAucmVjcmVhdGVNcGMoe1xuICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgICAgLi4ucGFyYW1zLmVuY3J5cHRlZE1hdGVyaWFsLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyk7XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC5yZWNyZWF0ZU1wYyh7XG4gICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgICAuLi5wYXJhbXMuZW5jcnlwdGVkTWF0ZXJpYWwsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFVzZXJLZXk6ICcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGVuY3J5cHRlZFVzZXJLZXknKTtcbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnJlY3JlYXRlTXBjKHtcbiAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgIGVuY3J5cHRlZE1hdGVyaWFsOiB7XG4gICAgICAgICAgICAgIC4uLnBhcmFtcy5lbmNyeXB0ZWRNYXRlcmlhbCxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBlbmNyeXB0ZWRCYWNrdXBLZXknKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgb3RwIHVubG9jayBmYWlscycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS91c2VyL3VubG9jaycpLnJlcGx5V2l0aEVycm9yKCdvdHAgZXJyb3InKTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGNvaW4sXG4gICAgICAgICAgd2FsbGV0SWQsXG4gICAgICAgICAgb3RwLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFVzZXJLZXk6ICdlbmNyeXB0ZWRVc2VyS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZEJhY2t1cEtleTogJ2VuY3J5cHRlZEJhY2t1cEtleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAnZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdvdHAgZXJyb3InKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgcGFzc2NvZGUgcmVjb3ZlcnkgYXBpIGNhbGwgZmFpbHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvdXNlci91bmxvY2snKS5yZXBseSgyMDAsIHsgb3RwIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0vd2FsbGV0LyR7d2FsbGV0SWR9L3Bhc3Njb2RlcmVjb3ZlcnlgKVxuICAgICAgICAgIC5yZXBseVdpdGhFcnJvcigncGFzc2NvZGUgcmVjb3ZlcnkgZXJyb3InKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgY29pbixcbiAgICAgICAgICB3YWxsZXRJZCxcbiAgICAgICAgICBvdHAsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZFVzZXJLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnZW5jcnlwdGVkQmFja3VwS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICdlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWlucy5yZWNyZWF0ZU1wYyhwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3Bhc3Njb2RlIHJlY292ZXJ5IGVycm9yJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHBhc3Njb2RlIHJlY292ZXJ5IGFwaSBjYWxsIHJldHVybnMgaW52YWxpZCByZWNvdmVyeSBpbmZvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL3VzZXIvdW5sb2NrJykucmVwbHkoMjAwLCB7IG90cCB9KTtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC8ke3dhbGxldElkfS9wYXNzY29kZXJlY292ZXJ5YCkucmVwbHkoMjAwLCB7IHJlY292ZXJ5SW5mbzoge30gfSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGNvaW4sXG4gICAgICAgICAgd2FsbGV0SWQsXG4gICAgICAgICAgb3RwLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFVzZXJLZXk6ICdlbmNyeXB0ZWRVc2VyS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZEJhY2t1cEtleTogJ2VuY3J5cHRlZEJhY2t1cEtleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAnZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdmYWlsZWQgdG8gZ2V0IHJlY292ZXJ5IGluZm8nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgY3JlYXRlTXBjIHdpdGggdGhlIGNvcnJlY3QgcGFyYW1ldGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS91c2VyL3VubG9jaycpLnJlcGx5KDIwMCwgeyBvdHAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvJHt3YWxsZXRJZH0vcGFzc2NvZGVyZWNvdmVyeWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyByZWNvdmVyeUluZm86IHsgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJzEyMycgfSB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgY29pbixcbiAgICAgICAgICB3YWxsZXRJZDogJ3dhbGxldElkJyxcbiAgICAgICAgICBvdHAsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZFVzZXJLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnZW5jcnlwdGVkQmFja3VwS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICdlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjcmVhdGVNcGNTdHViID0gc2lub24uc3R1YihrZXljaGFpbnMsICdjcmVhdGVNcGMnKS5yZXNvbHZlcygpO1xuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMocGFyYW1zKTtcblxuICAgICAgICBhc3NlcnQub2soXG4gICAgICAgICAgY3JlYXRlTXBjU3R1Yi5jYWxsZWRPbmNlV2l0aCh7XG4gICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcmV0cm9maXQ6IHtcbiAgICAgICAgICAgICAgZGVjcnlwdGVkVXNlcktleTogZGVjcnlwdFJlc3VsdCxcbiAgICAgICAgICAgICAgZGVjcnlwdGVkQmFja3VwS2V5OiBkZWNyeXB0UmVzdWx0LFxuICAgICAgICAgICAgICB3YWxsZXRJZDogcGFyYW1zLndhbGxldElkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcihmdW5jdGlvbiBhZnRlclVwZGF0ZVBhc3N3b3JkKCkge1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0NyZWF0ZSBCaXRHbyBLZXkgZnJvbSBPVkMgSlNPTicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiaXRHb0tleVJlc3VsdCA9IHtcbiAgICAgIGlkOiAnNjQyMWViNzU1ZmVhOWUwMDA2YzJjMDQwMDcyZjc0YmInLFxuICAgICAgY29tbW9uS2V5Y2hhaW46ICcxMjMnLFxuICAgICAgd2FsbGV0SFNNR1BHUHVibGljS2V5U2lnczogJzEyMycsXG4gICAgICB2ZXJpZmllZFZzc1Byb29mOiB0cnVlLFxuICAgICAga2V5U2hhcmVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBmcm9tOiAnYml0Z28nLFxuICAgICAgICAgIHRvOiAndXNlcicsXG4gICAgICAgICAgcHVibGljU2hhcmU6ICdjY2MnLFxuICAgICAgICAgIHByaXZhdGVTaGFyZTogJ2NjYyBwcml2YXRlJyxcbiAgICAgICAgICBwYWlsbGllclB1YmxpY0tleTogJ2NjYyBwYWlsbGllcicsXG4gICAgICAgICAgdnNzUHJvb2Y6ICdjY2MgdnNzIHByb29mJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiaXRnbycsXG4gICAgICAgICAgdG86ICdiYWNrdXAnLFxuICAgICAgICAgIHB1YmxpY1NoYXJlOiAnZmZmJyxcbiAgICAgICAgICBwcml2YXRlU2hhcmU6ICdmZmYgcHJpdmF0ZScsXG4gICAgICAgICAgcGFpbGxpZXJQdWJsaWNLZXk6ICdmZmYgcGFpbGxpZXInLFxuICAgICAgICAgIHZzc1Byb29mOiAnZmZmIHZzcyBwcm9vZicsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBjb25zdCBvdmNPdXRwdXRKc29uID0ge1xuICAgICAgdHNzVmVyc2lvbjogJzAuMC4xJyxcbiAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgY29pbjogJ3NvbCcsXG4gICAgICBzdGF0ZTogMSxcbiAgICAgIG92Yzoge1xuICAgICAgICAxOiB7XG4gICAgICAgICAgZ3BnUHViS2V5OlxuICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N29cXG49dmpnbFxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIG92Y1RvQml0Z29TaGFyZToge1xuICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWQvd1EvQWh3SVJzU2YvNmlId21IS3ZFWUF3ZmFMdFRRb3RTNkJ3Wm1cXG5hWDAwVDdMdW1HSXJOWnpCZ2NnZ0JLTWwrOE9tb204bVg1c1A4RlVFNDUxaVpqQm1YbGtwSGxwQXFza1NcXG5FaTVTZmpsc1QzMXV0b0xhQkxBN05qTlNteVlISWl5Zmg2WW53ZlY1VTcyazZoaGZwdURTc1FHeThZeHBcXG5NMmRWbE40dW9PMzF6Z1FQZitmZ0prWnZBUHd2allMQkw0TzhoczIxSEdmMFZ2Rzk5YnJrNHhsRlZSaHdcXG5RbnVQcE01MUdPczR2VXRiTE5TWW5BdWhVNFJlWHd3RFY5WHUwTVhBamZRTWsyRTN3UUxHUSs4MnV2MkJcXG4xaFBEOW5ESFR0QWRXclhkNlpqWEZyRzRNZjJNUUJ4eVNGdlZTbkZpNnlTdGpmWmVpS2NENVZnMzhQakdcXG5XZzFPNU4zL3BhcTk4SGZIMFE0cU5LR1psandvM29FUVp6bFltMmtWbkkwUFVMb01ZZz09XFxuPW92QXhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgICAgICBpOiAzLFxuICAgICAgICAgICAgajogMSxcbiAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzcTlSTUZLNEVFQUFvQ0F3UmdEcGdtMWJwdFJUNXlMT01hZGNHQUh1dmt4SVNMOC8zeFB5L0RcXG5ZQSsxTmdCcUlGSy8zT09YeHA3M1R2ODZidDFkZ0g3T0QxQUNPMG1WWEFvWDVFYVZ6V1p2ZG1NdE1TMTFcXG5jMlZ5TFdSbU1qUXdPV1kwTldOaE1UWm1OVFUzT0dOa016QXhNeUE4YjNaakxURXRkWE5sY2kxa1pqSTBcXG5NRGxtTkRWallURTJaalUxTnpoalpETXdNVE5BWkdZeU5EQTVaalExWTJFeE5tWTFOVGM0WTJRek1ERXpcXG5MbU52YlQ3Q2pBUVFFd2dBSFFVQ1pCc3E5UVFMQ1FjSUF4VUlDZ1FXQUFJQkFoa0JBaHNEQWg0QkFDRUpcXG5FT1VlQzdRckdMKzJGaUVFak42dlBVRlJ3ZVZ0REtGWjVSNEx0Q3NZdjdaN29BRUF2TkthSnJUSXMza3lcXG5ieGprVWljc3V4T3lBMm9XR2FySkg2VEdsV0Y2V0Q4QS8zRUllWnpQS1NMYVcrM2VucGJDUGlVOFJWRHBcXG5DNnlvNk5NQXFLcDRYbHlRemxNRVpCc3E5UklGSzRFRUFBb0NBd1FXbFdQTk1wazNhZkV6ZmdHMHhGZzRcXG5DRWpZN2ZHTzM1bjQ3blo0cXhqRVh6MlhONEkyM3hGTWl3WmJYYnB0RFhscW03VzlaQUhLaTg5MmgrWXRcXG5VNEI2QXdFSUI4SjRCQmdUQ0FBSkJRSmtHeXIxQWhzTUFDRUpFT1VlQzdRckdMKzJGaUVFak42dlBVRlJcXG53ZVZ0REtGWjVSNEx0Q3NZdjdZcVp3RDhETFJ1bmVCMEhFekJDeXJFNFlMK1VIYW9mb0hRWDErblJoMGpcXG44MnFhRHpBQS9pM1UxU29FSWkzMllNcm9yTkc1MHZiNHZhRVBiYlltZmdsYitKUTFZeDdvempNRVpCc3FcXG45UllKS3dZQkJBSGFSdzhCQVFkQVMxNTM0TGRDQzYwQVNwRWduRUJDOHBXUFNPV1dCTFh5V2FCaEVPVzJcXG4vaWpDZUFRWUV3Z0FDUVVDWkJzcTlRSWJJQUFoQ1JEbEhndTBLeGkvdGhZaEJJemVyejFCVWNIbGJReWhcXG5XZVVlQzdRckdMKzJGVVlBL0FnTVU0VjdDN0kvNUh3SzczbWN0YUdYTmRmVnIvbXVSTU5PR1cvQ0F4VkxcXG5BUDlLYUJyOTVvMzJvRU41ZW83dFdGQnlvT0NDazlKTWpzMzZDcTdvK3NSMzFBPT1cXG49ZVozQlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIDI6IHtcbiAgICAgICAgICBncGdQdWJLZXk6XG4gICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgydz09XFxuPUV0dHVcXG4tLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuJyxcbiAgICAgICAgICBvdmNUb0JpdGdvU2hhcmU6IHtcbiAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAnZWNmOTVlOWJhNmYwMmMwYmM0YzJhYjI1NDU2NWQyMWExNTYyMDU5YzhhMWFiNzBkMjg2ZmEwNGFlMmM1MTFlMDQ5MTQxMGI2ZDZmYThhYjIyZTY5MWJlZDc5MzhhN2FkYWFiZmE4ZDlkNTlhYWI5Y2MyYzA3OGNkMzdkZGUwMWInLFxuICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVlMW5ZTnY5RG5IbDhIWDhqTnMzcmVHczVuUFQyYk56R01DRkwwTjNQXFxuS0x3R2Q4REJrREpJTXBvQ2xhQVMvSFRVVFBUUnpqNFUxR1NoVjc5SStiYmZUREJWNnVoeWZaN2E4OGRWXFxuUkRUWGw2cmNoRmwvZm13TG9YbnFIK0JEUEVYeXRwQXZLd0RyQWc1NVQvSDdhb3A1UWJmU3NRRXJFdjdYXFxuVHBUTEhISGZsRUVRTDYycDFSbm5xMmtLdndKSzdUWTFnNVJ0UGdZWEg2R0VzMzNETHVsUGVVczhVa0txXFxuVFBMZjIrMUtDTFl5ek13bVNpOEtFQzhISmIwdkFrWFpBbFoxK0RvWjJQZmlJSmNWbno3YTNvbWppUDc3XFxuaG1DOHBoVGNKNzE4VXhJQjA5Zjh1aWMwL2ZNN0ZOdTBKSEZnUkRBNjl6emVGWW5aYzJYTlFnNWhzL2RaXFxuWjhBaXRQNHJuYUFmcHJzcTRyQUVFL2MzVHJtOXR6UUhaUENxci8yczRMbHV5VU1WSnc9PVxcbj1JSlpIXFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICB2c3NQcm9vZjogJzMwOWQyZmVmMjI3MmFkMzEzNzU5NTRiOTlhODYyNzQyZjIyZDgwMjNlZWY5ODU1YjhhZTI2ZWE4NGUwOGJmNWUnLFxuICAgICAgICAgICAgaTogMyxcbiAgICAgICAgICAgIGo6IDIsXG4gICAgICAgICAgICB1U2lnOiAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgyODR6XFxuQkdRYkt6UVdDU3NHQVFRQjJrY1BBUUVIUUlWVG1sdDhhL2ZqSkNZOVV5UDhKNTFlVFBYOVBNUkYzL0hyXFxuQll3dGZPWll3bmdFR0JNSUFBa0ZBbVFiS3pRQ0d5QUFJUWtRdGdKT1J0a3BPMlVXSVFTMDZVcEJUbnQyXFxubzI2cUxucTJBazVHMlNrN1pjdGhBUUQ0ZWszYXFVREViaGZSSG9sbTRqRmhJUEliYjloVUp3dUJSMFI0XFxuK2d2YWVBRUFrOHVrNWNFQUNlcW1wZEVGNTJvR3g3am1HQ29YNzNBSUlMWVZjZjlpTWtJPVxcbj05MkhmXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvdmNUb092Y1NoYXJlOiB7XG4gICAgICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAgICAgJ2VjZjk1ZTliYTZmMDJjMGJjNGMyYWIyNTQ1NjVkMjFhMTU2MjA1OWM4YTFhYjcwZDI4NmZhMDRhZTJjNTExZTA0OTE0MTBiNmQ2ZmE4YWIyMmU2OTFiZWQ3OTM4YTdhZGFhYmZhOGQ5ZDU5YWFiOWNjMmMwNzhjZDM3ZGRlMDFiJyxcbiAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNEQrRjN2STk2MnpWTVNBZ01FTnkyWDl4RElPbTFnd09mTWRMLzF2WmplTVcvaWxlL2YyZFJJUDJHVlxcbnY0dzYwSzkyK21ISTl5b29VMVZUNzdqWnJWT2NOSzQxREZOQ0YvZnVvVVUrVnpCT04wSTFoSHlYbTJRSlxcbndMK25OZHZBWHdSdjduU0ZEM0FCVW1SWWRHNzFBRklXalcyTCsxQzJoeHBzTmxtZHhmZlNzUUhIVDl1UFxcbkJOcEZZZ1FONzdPVXhjZ3J3ZVNWclB5ZXIxckNROG8rUW5vSzIvaEl4OVBsSlprY2wzdXdGNlRwQnRqc1xcbnF2UnhUaG9tb0h5bzBoSkhHMHZtSTQyR3E1dTB0Y1NlVTkwMmVmcENEYWVKaFBWT2lxSVNvSjk2d24wclxcbkZCM2xZTFNmbE9wQ0xBRTduc1pKUm9YQTZha1U3eE1DTU5BKytkNHR2NnA5OEZRK01aNmU5eDZraVN3MVxcbk0rVldqK1B2TjFkdFE4Zk5Zd3BKZjdLQmZEMXc2SVNNRkRtZXdrREU3aUJPWEY2Rkx3PT1cXG49KzNZY1xcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICAgICAgdnNzUHJvb2Y6ICczMDlkMmZlZjIyNzJhZDMxMzc1OTU0Yjk5YTg2Mjc0MmYyMmQ4MDIzZWVmOTg1NWI4YWUyNmVhODRlMDhiZjVlJyxcbiAgICAgICAgICAgIGk6IDEsXG4gICAgICAgICAgICBqOiAyLFxuICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMjg0elxcbkJHUWJLelFXQ1NzR0FRUUIya2NQQVFFSFFOVkdnMHZQc2ZLMXlKakZ1RFlCOFRqN0NRUkhLR0FWRURjalxcbmgvUUlxcjBLd25nRUdCTUlBQWtGQW1RYkt6UUNHeUFBSVFrUXRnSk9SdGtwTzJVV0lRUzA2VXBCVG50Mlxcbm8yNnFMbnEyQWs1RzJTazdaUzlvQVFDZTJ6SkQ1SXRXMkdFZ0FpdG5ZK05yTEJqYlhJNitMWTI5R2pSYVxcbmY2eUZUUUQvY1AwRTFEbGVxWE1qZ2ZSK2V3dDZxdVZGTVplYmhyM3RCci9IMFp2LzlFQT1cXG49OGFpK1xcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgZXhwZWN0ZWRCaXRHb091dHB1dCA9IHtcbiAgICAgIHdhbGxldDoge1xuICAgICAgICAuLi5vdmNPdXRwdXRKc29uLFxuICAgICAgICBzdGF0ZTogMixcbiAgICAgICAgcGxhdGZvcm06IHtcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogYml0R29LZXlSZXN1bHQuY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgd2FsbGV0R3BnUHViS2V5U2lnczogYml0R29LZXlSZXN1bHQud2FsbGV0SFNNR1BHUHVibGljS2V5U2lncyxcbiAgICAgICAgICBvdmM6IHtcbiAgICAgICAgICAgIDE6IHtcbiAgICAgICAgICAgICAgYml0Z29Ub092Y1NoYXJlOiB7XG4gICAgICAgICAgICAgICAgaTogMSxcbiAgICAgICAgICAgICAgICBqOiAzLFxuICAgICAgICAgICAgICAgIHB1YmxpY1NoYXJlOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMF0ucHVibGljU2hhcmUsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMF0ucHJpdmF0ZVNoYXJlLFxuICAgICAgICAgICAgICAgIHBhaWxsaWVyUHVibGljS2V5OiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMF0ucGFpbGxpZXJQdWJsaWNLZXksXG4gICAgICAgICAgICAgICAgdnNzUHJvb2Y6IGJpdEdvS2V5UmVzdWx0LmtleVNoYXJlc1swXS52c3NQcm9vZixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAyOiB7XG4gICAgICAgICAgICAgIGJpdGdvVG9PdmNTaGFyZToge1xuICAgICAgICAgICAgICAgIGk6IDIsXG4gICAgICAgICAgICAgICAgajogMyxcbiAgICAgICAgICAgICAgICBwdWJsaWNTaGFyZTogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzFdLnB1YmxpY1NoYXJlLFxuICAgICAgICAgICAgICAgIHByaXZhdGVTaGFyZTogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzFdLnByaXZhdGVTaGFyZSxcbiAgICAgICAgICAgICAgICBwYWlsbGllclB1YmxpY0tleTogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzFdLnBhaWxsaWVyUHVibGljS2V5LFxuICAgICAgICAgICAgICAgIHZzc1Byb29mOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMV0udnNzUHJvb2YsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gICAgaXQoJ1BhcnNlcyB0aGUgT1ZDIEpTT04gZmlsZSBwcm9wZXJseSBhbmQgY3JlYXRlcyB0aGUgbmV4dCBpbnB1dCBmb3IgT1ZDJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycsIGtleVR5cGU6ICd0c3MnIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCBiaXRHb0tleVJlc3VsdCk7XG4gICAgICBjb25zdCBwbGF0Zm9ybU91dHB1dCA9IGF3YWl0IGJpdGdvLmNvaW4oJ3Rzb2wnKS5rZXljaGFpbnMoKS5jcmVhdGVUc3NCaXRHb0tleUZyb21PdmNTaGFyZXMob3ZjT3V0cHV0SnNvbik7XG4gICAgICBzaG91bGQuZXF1YWwocGxhdGZvcm1PdXRwdXQuYml0R29LZXlJZCwgYml0R29LZXlSZXN1bHQuaWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChwbGF0Zm9ybU91dHB1dC5iaXRHb091dHB1dEpzb25Gb3JPdmMsIGV4cGVjdGVkQml0R29PdXRwdXQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Bhc3NlcyB0aGUgZW50ZXJwcmlzZSB3aXRoIGNvcnJlY3QgdmFsdWUgdG8gYml0Z28gaWYgcHJvdmlkZWQgYnkgY2FsbGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z29Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycsIGtleVR5cGU6ICd0c3MnIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCAodXJpLCBib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbnRlcnByaXNlJyk7XG4gICAgICAgICAgYm9keS5lbnRlcnByaXNlLnNob3VsZC5lcXVhbCgnZW50ZXJwcmlzZUlkJyk7XG4gICAgICAgICAgcmV0dXJuIGJpdEdvS2V5UmVzdWx0O1xuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IHBsYXRmb3JtT3V0cHV0ID0gYXdhaXQgYml0Z29cbiAgICAgICAgLmNvaW4oJ3Rzb2wnKVxuICAgICAgICAua2V5Y2hhaW5zKClcbiAgICAgICAgLmNyZWF0ZVRzc0JpdEdvS2V5RnJvbU92Y1NoYXJlcyhvdmNPdXRwdXRKc29uLCAnZW50ZXJwcmlzZUlkJyk7XG4gICAgICBzaG91bGQuZXF1YWwocGxhdGZvcm1PdXRwdXQuYml0R29LZXlJZCwgYml0R29LZXlSZXN1bHQuaWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChwbGF0Zm9ybU91dHB1dC5iaXRHb091dHB1dEpzb25Gb3JPdmMsIGV4cGVjdGVkQml0R29PdXRwdXQpO1xuICAgICAgYml0Z29Ob2NrLmlzRG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBmYWlsIGlmIHRoZSBzdGF0ZSBpcyBub3QgMScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG92Y091dHB1dEpzb24gPSB7XG4gICAgICAgIHRzc1ZlcnNpb246ICcwLjAuMScsXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICBjb2luOiAnc29sJyxcbiAgICAgICAgc3RhdGU6IDAsXG4gICAgICAgIG92Yzoge1xuICAgICAgICAgIDE6IHtcbiAgICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N29cXG49dmpnbFxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgb3ZjVG9CaXRnb1NoYXJlOiB7XG4gICAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVkL3dRL0Fod0lSc1NmLzZpSHdtSEt2RVlBd2ZhTHRUUW90UzZCd1ptXFxuYVgwMFQ3THVtR0lyTlp6QmdjZ2dCS01sKzhPbW9tOG1YNXNQOEZVRTQ1MWlaakJtWGxrcEhscEFxc2tTXFxuRWk1U2ZqbHNUMzF1dG9MYUJMQTdOak5TbXlZSElpeWZoNllud2ZWNVU3Mms2aGhmcHVEU3NRR3k4WXhwXFxuTTJkVmxONHVvTzMxemdRUGYrZmdKa1p2QVB3dmpZTEJMNE84aHMyMUhHZjBWdkc5OWJyazR4bEZWUmh3XFxuUW51UHBNNTFHT3M0dlV0YkxOU1luQXVoVTRSZVh3d0RWOVh1ME1YQWpmUU1rMkUzd1FMR1ErODJ1djJCXFxuMWhQRDluREhUdEFkV3JYZDZaalhGckc0TWYyTVFCeHlTRnZWU25GaTZ5U3RqZlplaUtjRDVWZzM4UGpHXFxuV2cxTzVOMy9wYXE5OEhmSDBRNHFOS0dabGp3bzNvRVFaemxZbTJrVm5JMFBVTG9NWWc9PVxcbj1vdkF4XFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgICAgICAgIGk6IDMsXG4gICAgICAgICAgICAgIGo6IDEsXG4gICAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzcTlSTUZLNEVFQUFvQ0F3UmdEcGdtMWJwdFJUNXlMT01hZGNHQUh1dmt4SVNMOC8zeFB5L0RcXG5ZQSsxTmdCcUlGSy8zT09YeHA3M1R2ODZidDFkZ0g3T0QxQUNPMG1WWEFvWDVFYVZ6V1p2ZG1NdE1TMTFcXG5jMlZ5TFdSbU1qUXdPV1kwTldOaE1UWm1OVFUzT0dOa016QXhNeUE4YjNaakxURXRkWE5sY2kxa1pqSTBcXG5NRGxtTkRWallURTJaalUxTnpoalpETXdNVE5BWkdZeU5EQTVaalExWTJFeE5tWTFOVGM0WTJRek1ERXpcXG5MbU52YlQ3Q2pBUVFFd2dBSFFVQ1pCc3E5UVFMQ1FjSUF4VUlDZ1FXQUFJQkFoa0JBaHNEQWg0QkFDRUpcXG5FT1VlQzdRckdMKzJGaUVFak42dlBVRlJ3ZVZ0REtGWjVSNEx0Q3NZdjdaN29BRUF2TkthSnJUSXMza3lcXG5ieGprVWljc3V4T3lBMm9XR2FySkg2VEdsV0Y2V0Q4QS8zRUllWnpQS1NMYVcrM2VucGJDUGlVOFJWRHBcXG5DNnlvNk5NQXFLcDRYbHlRemxNRVpCc3E5UklGSzRFRUFBb0NBd1FXbFdQTk1wazNhZkV6ZmdHMHhGZzRcXG5DRWpZN2ZHTzM1bjQ3blo0cXhqRVh6MlhONEkyM3hGTWl3WmJYYnB0RFhscW03VzlaQUhLaTg5MmgrWXRcXG5VNEI2QXdFSUI4SjRCQmdUQ0FBSkJRSmtHeXIxQWhzTUFDRUpFT1VlQzdRckdMKzJGaUVFak42dlBVRlJcXG53ZVZ0REtGWjVSNEx0Q3NZdjdZcVp3RDhETFJ1bmVCMEhFekJDeXJFNFlMK1VIYW9mb0hRWDErblJoMGpcXG44MnFhRHpBQS9pM1UxU29FSWkzMllNcm9yTkc1MHZiNHZhRVBiYlltZmdsYitKUTFZeDdvempNRVpCc3FcXG45UllKS3dZQkJBSGFSdzhCQVFkQVMxNTM0TGRDQzYwQVNwRWduRUJDOHBXUFNPV1dCTFh5V2FCaEVPVzJcXG4vaWpDZUFRWUV3Z0FDUVVDWkJzcTlRSWJJQUFoQ1JEbEhndTBLeGkvdGhZaEJJemVyejFCVWNIbGJReWhcXG5XZVVlQzdRckdMKzJGVVlBL0FnTVU0VjdDN0kvNUh3SzczbWN0YUdYTmRmVnIvbXVSTU5PR1cvQ0F4VkxcXG5BUDlLYUJyOTVvMzJvRU41ZW83dFdGQnlvT0NDazlKTWpzMzZDcTdvK3NSMzFBPT1cXG49ZVozQlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIDI6IHtcbiAgICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMnc9PVxcbj1FdHR1XFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICBvdmNUb0JpdGdvU2hhcmU6IHtcbiAgICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICAgJ2VjZjk1ZTliYTZmMDJjMGJjNGMyYWIyNTQ1NjVkMjFhMTU2MjA1OWM4YTFhYjcwZDI4NmZhMDRhZTJjNTExZTA0OTE0MTBiNmQ2ZmE4YWIyMmU2OTFiZWQ3OTM4YTdhZGFhYmZhOGQ5ZDU5YWFiOWNjMmMwNzhjZDM3ZGRlMDFiJyxcbiAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWUxbllOdjlEbkhsOEhYOGpOczNyZUdzNW5QVDJiTnpHTUNGTDBOM1BcXG5LTHdHZDhEQmtESklNcG9DbGFBUy9IVFVUUFRSemo0VTFHU2hWNzlJK2JiZlREQlY2dWh5Zlo3YTg4ZFZcXG5SRFRYbDZyY2hGbC9mbXdMb1hucUgrQkRQRVh5dHBBdkt3RHJBZzU1VC9IN2FvcDVRYmZTc1FFckV2N1hcXG5UcFRMSEhIZmxFRVFMNjJwMVJubnEya0t2d0pLN1RZMWc1UnRQZ1lYSDZHRXMzM0RMdWxQZVVzOFVrS3FcXG5UUExmMisxS0NMWXl6TXdtU2k4S0VDOEhKYjB2QWtYWkFsWjErRG9aMlBmaUlKY1ZuejdhM29tamlQNzdcXG5obUM4cGhUY0o3MThVeElCMDlmOHVpYzAvZk03Rk51MEpIRmdSREE2OXp6ZUZZblpjMlhOUWc1aHMvZFpcXG5aOEFpdFA0cm5hQWZwcnNxNHJBRUUvYzNUcm05dHpRSFpQQ3FyLzJzNExsdXlVTVZKdz09XFxuPUlKWkhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgICAgdnNzUHJvb2Y6ICczMDlkMmZlZjIyNzJhZDMxMzc1OTU0Yjk5YTg2Mjc0MmYyMmQ4MDIzZWVmOTg1NWI4YWUyNmVhODRlMDhiZjVlJyxcbiAgICAgICAgICAgICAgaTogMyxcbiAgICAgICAgICAgICAgajogMixcbiAgICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMjg0elxcbkJHUWJLelFXQ1NzR0FRUUIya2NQQVFFSFFJVlRtbHQ4YS9makpDWTlVeVA4SjUxZVRQWDlQTVJGMy9IclxcbkJZd3RmT1pZd25nRUdCTUlBQWtGQW1RYkt6UUNHeUFBSVFrUXRnSk9SdGtwTzJVV0lRUzA2VXBCVG50Mlxcbm8yNnFMbnEyQWs1RzJTazdaY3RoQVFENGVrM2FxVURFYmhmUkhvbG00akZoSVBJYmI5aFVKd3VCUjBSNFxcbitndmFlQUVBazh1azVjRUFDZXFtcGRFRjUyb0d4N2ptR0NvWDczQUlJTFlWY2Y5aU1rST1cXG49OTJIZlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG92Y1RvT3ZjU2hhcmU6IHtcbiAgICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICAgJ2VjZjk1ZTliYTZmMDJjMGJjNGMyYWIyNTQ1NjVkMjFhMTU2MjA1OWM4YTFhYjcwZDI4NmZhMDRhZTJjNTExZTA0OTE0MTBiNmQ2ZmE4YWIyMmU2OTFiZWQ3OTM4YTdhZGFhYmZhOGQ5ZDU5YWFiOWNjMmMwNzhjZDM3ZGRlMDFiJyxcbiAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREK0Yzdkk5NjJ6Vk1TQWdNRU55Mlg5eERJT20xZ3dPZk1kTC8xdlpqZU1XL2lsZS9mMmRSSVAyR1ZcXG52NHc2MEs5MittSEk5eW9vVTFWVDc3alpyVk9jTks0MURGTkNGL2Z1b1VVK1Z6Qk9OMEkxaEh5WG0yUUpcXG53TCtuTmR2QVh3UnY3blNGRDNBQlVtUllkRzcxQUZJV2pXMkwrMUMyaHhwc05sbWR4ZmZTc1FISFQ5dVBcXG5CTnBGWWdRTjc3T1V4Y2dyd2VTVnJQeWVyMXJDUThvK1Fub0syL2hJeDlQbEpaa2NsM3V3RjZUcEJ0anNcXG5xdlJ4VGhvbW9IeW8waEpIRzB2bUk0MkdxNXUwdGNTZVU5MDJlZnBDRGFlSmhQVk9pcUlTb0o5NnduMHJcXG5GQjNsWUxTZmxPcENMQUU3bnNaSlJvWEE2YWtVN3hNQ01OQSsrZDR0djZwOThGUStNWjZlOXg2a2lTdzFcXG5NK1ZXaitQdk4xZHRROGZOWXdwSmY3S0JmRDF3NklTTUZEbWV3a0RFN2lCT1hGNkZMdz09XFxuPSszWWNcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgICAgdnNzUHJvb2Y6ICczMDlkMmZlZjIyNzJhZDMxMzc1OTU0Yjk5YTg2Mjc0MmYyMmQ4MDIzZWVmOTg1NWI4YWUyNmVhODRlMDhiZjVlJyxcbiAgICAgICAgICAgICAgaTogMSxcbiAgICAgICAgICAgICAgajogMixcbiAgICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMjg0elxcbkJHUWJLelFXQ1NzR0FRUUIya2NQQVFFSFFOVkdnMHZQc2ZLMXlKakZ1RFlCOFRqN0NRUkhLR0FWRURjalxcbmgvUUlxcjBLd25nRUdCTUlBQWtGQW1RYkt6UUNHeUFBSVFrUXRnSk9SdGtwTzJVV0lRUzA2VXBCVG50Mlxcbm8yNnFMbnEyQWs1RzJTazdaUzlvQVFDZTJ6SkQ1SXRXMkdFZ0FpdG5ZK05yTEJqYlhJNitMWTI5R2pSYVxcbmY2eUZUUUQvY1AwRTFEbGVxWE1qZ2ZSK2V3dDZxdVZGTVplYmhyM3RCci9IMFp2LzlFQT1cXG49OGFpK1xcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYml0Z29cbiAgICAgICAgLmNvaW4oJ3Rzb2wnKVxuICAgICAgICAua2V5Y2hhaW5zKClcbiAgICAgICAgLmNyZWF0ZVRzc0JpdEdvS2V5RnJvbU92Y1NoYXJlcyhvdmNPdXRwdXRKc29uKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnU3RhdGUgZXhwZWN0ZWQgdG8gYmUgXCIxXCIuIFBsZWFzZSBjb21wbGV0ZSB0aGUgZmlyc3QgdHdvIE9WQyBvcGVyYXRpb25zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnRmFpbHMgdG8gZGVjb2RlIGlmIHRoZSBPVkMganNvbiBpcyBtaXNzaW5nIGZpZWxkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG92Y091dHB1dEpzb24gPSB7XG4gICAgICAgIHRzc1ZlcnNpb246ICcwLjAuMScsXG4gICAgICAgIHN0YXRlOiAxLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgIG92Yzoge1xuICAgICAgICAgIDE6IHtcbiAgICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N29cXG49dmpnbFxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgb3ZjVG9CaXRnb1NoYXJlOiB7XG4gICAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVkL3dRL0Fod0lSc1NmLzZpSHdtSEt2RVlBd2ZhTHRUUW90UzZCd1ptXFxuYVgwMFQ3THVtR0lyTlp6QmdjZ2dCS01sKzhPbW9tOG1YNXNQOEZVRTQ1MWlaakJtWGxrcEhscEFxc2tTXFxuRWk1U2ZqbHNUMzF1dG9MYUJMQTdOak5TbXlZSElpeWZoNllud2ZWNVU3Mms2aGhmcHVEU3NRR3k4WXhwXFxuTTJkVmxONHVvTzMxemdRUGYrZmdKa1p2QVB3dmpZTEJMNE84aHMyMUhHZjBWdkc5OWJyazR4bEZWUmh3XFxuUW51UHBNNTFHT3M0dlV0YkxOU1luQXVoVTRSZVh3d0RWOVh1ME1YQWpmUU1rMkUzd1FMR1ErODJ1djJCXFxuMWhQRDluREhUdEFkV3JYZDZaalhGckc0TWYyTVFCeHlTRnZWU25GaTZ5U3RqZlplaUtjRDVWZzM4UGpHXFxuV2cxTzVOMy9wYXE5OEhmSDBRNHFOS0dabGp3bzNvRVFaemxZbTJrVm5JMFBVTG9NWWc9PVxcbj1vdkF4XFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgICAgICAgIGk6IDMsXG4gICAgICAgICAgICAgIGo6IDEsXG4gICAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzcTlSTUZLNEVFQUFvQ0F3UmdEcGdtMWJwdFJUNXlMT01hZGNHQUh1dmt4SVNMOC8zeFB5L0RcXG5ZQSsxTmdCcUlGSy8zT09YeHA3M1R2ODZidDFkZ0g3T0QxQUNPMG1WWEFvWDVFYVZ6V1p2ZG1NdE1TMTFcXG5jMlZ5TFdSbU1qUXdPV1kwTldOaE1UWm1OVFUzT0dOa016QXhNeUE4YjNaakxURXRkWE5sY2kxa1pqSTBcXG5NRGxtTkRWallURTJaalUxTnpoalpETXdNVE5BWkdZeU5EQTVaalExWTJFeE5tWTFOVGM0WTJRek1ERXpcXG5MbU52YlQ3Q2pBUVFFd2dBSFFVQ1pCc3E5UVFMQ1FjSUF4VUlDZ1FXQUFJQkFoa0JBaHNEQWg0QkFDRUpcXG5FT1VlQzdRckdMKzJGaUVFak42dlBVRlJ3ZVZ0REtGWjVSNEx0Q3NZdjdaN29BRUF2TkthSnJUSXMza3lcXG5ieGprVWljc3V4T3lBMm9XR2FySkg2VEdsV0Y2V0Q4QS8zRUllWnpQS1NMYVcrM2VucGJDUGlVOFJWRHBcXG5DNnlvNk5NQXFLcDRYbHlRemxNRVpCc3E5UklGSzRFRUFBb0NBd1FXbFdQTk1wazNhZkV6ZmdHMHhGZzRcXG5DRWpZN2ZHTzM1bjQ3blo0cXhqRVh6MlhONEkyM3hGTWl3WmJYYnB0RFhscW03VzlaQUhLaTg5MmgrWXRcXG5VNEI2QXdFSUI4SjRCQmdUQ0FBSkJRSmtHeXIxQWhzTUFDRUpFT1VlQzdRckdMKzJGaUVFak42dlBVRlJcXG53ZVZ0REtGWjVSNEx0Q3NZdjdZcVp3RDhETFJ1bmVCMEhFekJDeXJFNFlMK1VIYW9mb0hRWDErblJoMGpcXG44MnFhRHpBQS9pM1UxU29FSWkzMllNcm9yTkc1MHZiNHZhRVBiYlltZmdsYitKUTFZeDdvempNRVpCc3FcXG45UllKS3dZQkJBSGFSdzhCQVFkQVMxNTM0TGRDQzYwQVNwRWduRUJDOHBXUFNPV1dCTFh5V2FCaEVPVzJcXG4vaWpDZUFRWUV3Z0FDUVVDWkJzcTlRSWJJQUFoQ1JEbEhndTBLeGkvdGhZaEJJemVyejFCVWNIbGJReWhcXG5XZVVlQzdRckdMKzJGVVlBL0FnTVU0VjdDN0kvNUh3SzczbWN0YUdYTmRmVnIvbXVSTU5PR1cvQ0F4VkxcXG5BUDlLYUJyOTVvMzJvRU41ZW83dFdGQnlvT0NDazlKTWpzMzZDcTdvK3NSMzFBPT1cXG49ZVozQlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IGJpdGdvLmNvaW4oJ3Rzb2wnKS5rZXljaGFpbnMoKS5jcmVhdGVUc3NCaXRHb0tleUZyb21PdmNTaGFyZXMob3ZjT3V0cHV0SnNvbikuc2hvdWxkLmJlLnJlamVjdGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnT3ZjU2hhcmUgY29kZWMgZGVjb2RlcyBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0ID0ge1xuICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAnMDdiZmJiMDUyYTFmNGIxMDZiMzE1YmQ1YTlkNmE3MTYwNDY1MzI4OWY4NjEzMjBkOTgwMTg4MWU5NTJmODU1MDc1M2M4OTUxMWEzNjBlM2I1OTlkOWYyMzlhOGQzNmE0OTU2NDM3ZWQwYjE1MjE4MGUyMmNiOTRmYjA4ZmRjODEnLFxuICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNERVUThYaEdWR2NUSVNBZ01FZC93US9BaHdJUnNTZi82aUh3bUhLdkVZQXdmYUx0VFFvdFM2QndabVxcbmFYMDBUN0x1bUdJck5aekJnY2dnQktNbCs4T21vbThtWDVzUDhGVUU0NTFpWmpCbVhsa3BIbHBBcXNrU1xcbkVpNVNmamxzVDMxdXRvTGFCTEE3TmpOU215WUhJaXlmaDZZbndmVjVVNzJrNmhoZnB1RFNzUUd5OFl4cFxcbk0yZFZsTjR1b08zMXpnUVBmK2ZnSmtadkFQd3ZqWUxCTDRPOGhzMjFIR2YwVnZHOTlicms0eGxGVlJod1xcblFudVBwTTUxR09zNHZVdGJMTlNZbkF1aFU0UmVYd3dEVjlYdTBNWEFqZlFNazJFM3dRTEdRKzgydXYyQlxcbjFoUEQ5bkRIVHRBZFdyWGQ2WmpYRnJHNE1mMk1RQnh5U0Z2VlNuRmk2eVN0amZaZWlLY0Q1VmczOFBqR1xcbldnMU81TjMvcGFxOThIZkgwUTRxTktHWmxqd28zb0VRWnpsWW0ya1ZuSTBQVUxvTVlnPT1cXG49b3ZBeFxcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICB2c3NQcm9vZjogJ2JlODE5OGMyY2VmOTRjYjM4MWFhOGFhOTI3N2EwYTQ2YmE1YTU0YjBhYzk5MzAwMzRiNGFmNjZiMWI4MDUyMzQnLFxuICAgICAgICBpOiAzLFxuICAgICAgICBqOiAxLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGRlY29kZWRSZXMgPSBkZWNvZGVPckVsc2UoT3ZjU2hhcmUubmFtZSwgT3ZjU2hhcmUsIHRlc3QsIChlcnJvcnMpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBlcnJvcihzKSBwYXJzaW5nIHBhcnNpbmcganNvbjogJHtlcnJvcnN9YCk7XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5vayhkZWNvZGVkUmVzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBiYWNrdXAgd2l0aG91dCBlbmNyeXB0ZWRQcnYgd2hlbiBwYXNzcGhyYXNlIG5vdCBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIChib2R5KSA9PiB7XG4gICAgICAgIHJldHVybiBib2R5LmVuY3J5cHRlZFBydiA9PT0gdW5kZWZpbmVkICYmIGJvZHkucHJ2ID09PSB1bmRlZmluZWQ7XG4gICAgICB9KVxuICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICBjb25zdCBiYWNrdXAgPSBhd2FpdCBrZXljaGFpbnMuY3JlYXRlQmFja3VwKHt9KTtcbiAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIGJhY2t1cC5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgIGJhY2t1cC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJ2Jyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZ2VuZXJhdGUgYmFja3VwIGFuZCBjYWxsIGVuZHBvaW50IHdpdGggZW5jcnlwdGVkUHJ2IHdoZW4gcGFzc3BocmFzZSBpcyBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIChib2R5KSA9PiB7XG4gICAgICAgIHJldHVybiBib2R5LmVuY3J5cHRlZFBydiAhPT0gdW5kZWZpbmVkICYmIGJvZHkucHJ2ID09PSB1bmRlZmluZWQ7XG4gICAgICB9KVxuICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICBjb25zdCBiYWNrdXAgPSBhd2FpdCBrZXljaGFpbnMuY3JlYXRlQmFja3VwKHsgcGFzc3BocmFzZTogJ3Qzc3RTaWNyZXRseSEnIH0pO1xuICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgYmFja3VwLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRQcnYnKTtcbiAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IGJhY2t1cC5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiAndDNzdFNpY3JldGx5IScgfSk7XG4gICAgZGVjcnlwdGVkUHJ2LnNob3VsZC5zdGFydFdpdGgoJ3hwcnYnKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JvdGF0ZSBPRkMgbXVsdGktdXNlci1rZXkga2V5Y2hhaW5zJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBvZmNCYXNlQ29pbjtcbiAgICBsZXQgb2ZjS2V5Y2hhaW5zO1xuICAgIGNvbnN0IG1vY2tPZmNLZXljaGFpbjogS2V5Y2hhaW4gPSB7XG4gICAgICBpZDogJ29mY0tleWNoYWluSWQnLFxuICAgICAgcHViOiAnb2ZjS2V5Y2hhaW5QdWInLFxuICAgICAgZW5jcnlwdGVkUHJ2OiAnb2ZjRW5jcnlwdGVkUHJ2JyxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgIG9mYzoge1xuICAgICAgICAgIGZlYXR1cmVzOiBbJ211bHRpLXVzZXIta2V5J10sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdHlwZTogJ3RzcycsXG4gICAgfTtcbiAgICBsZXQgbm9uT2ZjQmFzZUNvaW47XG4gICAgbGV0IG5vbk9mY0tleWNoYWlucztcbiAgICBjb25zdCBtb2NrTm9uT2ZjS2V5Y2hhaW46IEtleWNoYWluID0ge1xuICAgICAgaWQ6ICdub25PZmNLZXljaGFpbklkJyxcbiAgICAgIHB1YjogJ25vbk9mY0tleWNoYWluUHViJyxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgdHlwZTogJ3RzcycsXG4gICAgfTtcblxuICAgIGNvbnN0IG1vY2tOZXdLZXlwYWlyID0ge1xuICAgICAgcHViOiAnbmV3UHViJyxcbiAgICAgIHBydjogJ25ld1BydicsXG4gICAgfTtcblxuICAgIGxldCBzYW5kYm94O1xuICAgIGxldCB1cGRhdGVLZXljaGFpblN0dWI6IFNpbm9uU3R1YjtcbiAgICBsZXQgY3JlYXRlS2V5cGFpclN0dWI6IFNpbm9uU3R1YjtcbiAgICBsZXQgZW5jcnlwdGlvblN0dWI6IFNpbm9uU3R1YjtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgb2ZjQmFzZUNvaW4gPSBiaXRnby5jb2luKCdvZmMnKTtcbiAgICAgIG9mY0tleWNoYWlucyA9IG9mY0Jhc2VDb2luLmtleWNoYWlucygpO1xuXG4gICAgICBub25PZmNCYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBub25PZmNLZXljaGFpbnMgPSBub25PZmNCYXNlQ29pbi5rZXljaGFpbnMoKTtcblxuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICAgIHVwZGF0ZUtleWNoYWluU3R1YiA9IHNhbmRib3guc3R1YigpLnJldHVybnMoeyByZXN1bHQ6IHNhbmRib3guc3R1YigpLnJlc29sdmVzKCkgfSk7XG4gICAgICBzYW5kYm94LnN0dWIoQml0R28ucHJvdG90eXBlLCAncHV0JykucmV0dXJucyh7IHNlbmQ6IHVwZGF0ZUtleWNoYWluU3R1YiB9KTtcbiAgICAgIGNyZWF0ZUtleXBhaXJTdHViID0gc2FuZGJveC5zdHViKG9mY0tleWNoYWlucywgJ2NyZWF0ZScpLnJldHVybnMobW9ja05ld0tleXBhaXIpO1xuICAgICAgZW5jcnlwdGlvblN0dWIgPSBzYW5kYm94LnN0dWIoQml0R28ucHJvdG90eXBlLCAnZW5jcnlwdCcpLnJlc29sdmVzKCduZXdFbmNyeXB0ZWRQcnYnKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcm90YXRlIG9mYyBtdWx0aS11c2VyLWtleSBwcm9wZXJseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9vZmMva2V5LyR7bW9ja09mY0tleWNoYWluLmlkfWApLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgbW9ja09mY0tleWNoYWluKTtcblxuICAgICAgYXdhaXQgb2ZjS2V5Y2hhaW5zLnJvdGF0ZUtleWNoYWluKHsgaWQ6IG1vY2tPZmNLZXljaGFpbi5pZCwgcGFzc3dvcmQ6ICcxMjM0JyB9KTtcbiAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWQoY3JlYXRlS2V5cGFpclN0dWIpO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgoZW5jcnlwdGlvblN0dWIsIHsgaW5wdXQ6IG1vY2tOZXdLZXlwYWlyLnBydiwgcGFzc3dvcmQ6ICcxMjM0JywgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aCh1cGRhdGVLZXljaGFpblN0dWIsIHtcbiAgICAgICAgcHViOiBtb2NrTmV3S2V5cGFpci5wdWIsXG4gICAgICAgIGVuY3J5cHRlZFBydjogJ25ld0VuY3J5cHRlZFBydicsXG4gICAgICAgIHJlcUlkOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWxsb3cgdXNlciB0byBzdXBwbHkgcHViIGFuZCBlbmNyeXB0ZWRQcnYgZGlyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvb2ZjL2tleS8ke21vY2tPZmNLZXljaGFpbi5pZH1gKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIG1vY2tPZmNLZXljaGFpbik7XG5cbiAgICAgIGF3YWl0IG9mY0tleWNoYWlucy5yb3RhdGVLZXljaGFpbih7IGlkOiBtb2NrT2ZjS2V5Y2hhaW4uaWQsIHB1YjogJ3B1YicsIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicgfSk7XG4gICAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKGNyZWF0ZUtleXBhaXJTdHViKTtcbiAgICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQoZW5jcnlwdGlvblN0dWIpO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgodXBkYXRlS2V5Y2hhaW5TdHViLCB7XG4gICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgIHJlcUlkOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB0cnlpbmcgdG8gcm90YXRlIG5vbi1vZmMga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LyR7bW9ja05vbk9mY0tleWNoYWluLmlkfWApLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgbW9ja05vbk9mY0tleWNoYWluKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IG5vbk9mY0tleWNoYWlucy5yb3RhdGVLZXljaGFpbih7IGlkOiBtb2NrTm9uT2ZjS2V5Y2hhaW4uaWQsIHBhc3N3b3JkOiAnMTIzNCcgfSksXG4gICAgICAgIChlcnI6IEVycm9yKSA9PiBlcnIubWVzc2FnZSA9PT0gJ3JvdGF0ZUtleWNoYWluIGlzIG9ubHkgcGVybWl0dGVkIGZvciBvZmMgbXVsdGktdXNlci1rZXkgd2FsbGV0J1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldEVuY3J5cHRpb25WZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyZXR1cm5zIDEgd2hlbiB0aGUgdiBmaWVsZCBpcyBhYnNlbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04uc3RyaW5naWZ5KHsgY3Q6ICdjaXBoZXInLCBpdjogJ2l2JywgczogJ3NhbHQnIH0pO1xuICAgICAga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKGVudmVsb3BlKS5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyAxIHdoZW4gdiBpcyBleHBsaWNpdGx5IDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oSlNPTi5zdHJpbmdpZnkoeyB2OiAxLCBjdDogJ2FiYycgfSkpLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIDIgd2hlbiB2IGlzIDInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBjdDogJ2FiYycgfSkpLnNob3VsZC5lcXVhbCgyKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgb24gYW4gdW5yZWNvZ25pemVkIHZlcnNpb24gbnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKEpTT04uc3RyaW5naWZ5KHsgdjogMywgY3Q6ICdhYmMnIH0pKSxcbiAgICAgICAgL1VucmVjb2duaXplZCBlbmNyeXB0aW9uIHZlcnNpb246IDMvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHRoZSBpbnB1dCBpcyBub3QgdmFsaWQgSlNPTicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4ga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKCdub3QtanNvbicpLCAvRmFpbGVkIHRvIHBhcnNlIGNpcGhlcnRleHQgZW52ZWxvcGUvKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiB0aGUgaW5wdXQgaXMgYW4gZW1wdHkgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oJycpLCAvRmFpbGVkIHRvIHBhcnNlIGNpcGhlcnRleHQgZW52ZWxvcGUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdoYW5kbGVzIGEgcmVhbCBTSkNMIHYxIGVudmVsb3BlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2pjbCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgaXY6ICdhYWFhJyxcbiAgICAgICAgdjogMSxcbiAgICAgICAgaXRlcjogMTAwMDAsXG4gICAgICAgIGtzOiAyNTYsXG4gICAgICAgIHRzOiA2NCxcbiAgICAgICAgbW9kZTogJ2NjbScsXG4gICAgICAgIGFkYXRhOiAnJyxcbiAgICAgICAgY2lwaGVyOiAnYWVzJyxcbiAgICAgICAgc2FsdDogJ3Nzc3MnLFxuICAgICAgICBjdDogJ2NjY2MnLFxuICAgICAgfSk7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oc2pjbCkuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hhbmRsZXMgYSByZWFsIEFyZ29uMmlkIHYyIGVudmVsb3BlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYXJnb24yID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB2OiAyLFxuICAgICAgICBjdDogJ2NjY2MnLFxuICAgICAgICBpdjogJ2lpaWknLFxuICAgICAgICB0YWc6ICd0dHR0JyxcbiAgICAgICAgc2FsdDogJ3Nzc3MnLFxuICAgICAgICBtOiA2NTUzNixcbiAgICAgICAgdDogMyxcbiAgICAgICAgcDogNCxcbiAgICAgIH0pO1xuICAgICAga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKGFyZ29uMikuc2hvdWxkLmVxdWFsKDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVlbmNyeXB0QXNWMicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnZGVjcnlwdHMgYSB2MSBlbnZlbG9wZSB3aXRoIHRoZSBwYXNzcGhyYXNlIGFuZCByZS1lbmNyeXB0cyBhcyB2MicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBydiA9ICd0aGVQcml2YXRlS2V5JztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiAnbXlQYXNzJywgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG4gICAgICBKU09OLnBhcnNlKGVuY3J5cHRlZFYxKS52LnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2V5Y2hhaW5zLnJlZW5jcnlwdEFzVjIoZW5jcnlwdGVkVjEsICdteVBhc3MnKTtcbiAgICAgIEpTT04ucGFyc2UocmVzdWx0KS52LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIChhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3VsdCwgcGFzc3dvcmQ6ICdteVBhc3MnIH0pKS5zaG91bGQuZXF1YWwocHJ2KTtcbiAgICB9KTtcblxuICAgIGl0KCdhY2NlcHRzIGEgdjIgZW52ZWxvcGUgYW5kIHJlLWVuY3J5cHRzIGl0IGFzIHYyIChpZGVtcG90ZW50KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBydiA9ICd4cHJ2LXYyJztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiAncGFzcycsIGVuY3J5cHRpb25WZXJzaW9uOiAyIH0pO1xuICAgICAgSlNPTi5wYXJzZShlbmNyeXB0ZWRWMikudi5zaG91bGQuZXF1YWwoMik7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGtleWNoYWlucy5yZWVuY3J5cHRBc1YyKGVuY3J5cHRlZFYyLCAncGFzcycpO1xuICAgICAgSlNPTi5wYXJzZShyZXN1bHQpLnYuc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgKGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzdWx0LCBwYXNzd29yZDogJ3Bhc3MnIH0pKS5zaG91bGQuZXF1YWwocHJ2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzdXJmYWNlcyBkZWNyeXB0IGVycm9ycyBkaXJlY3RseSAobm8gZmFsbGJhY2sgbG9naWMgaW4gdGhlIHByaW1pdGl2ZSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbmNyeXB0ZWQgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICdwcnYnLCBwYXNzd29yZDogJ3JlYWxQYXNzJywgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG4gICAgICBhd2FpdCBrZXljaGFpbnMucmVlbmNyeXB0QXNWMihlbmNyeXB0ZWQsICd3cm9uZ1Bhc3MnKS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==