bitgo
Version:
BitGo JavaScript SDK
1,147 lines • 222 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();
});
it('should add a safe child keychain with derivedFromParentWithHardenedPath', async function () {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', function (body) {
body.pub.should.equal('pub');
body.parent.should.equal('parent-key-id');
body.safeId.should.equal('safe-id');
body.derivedFromParentWithHardenedPath.should.equal("m/7'");
should.equal(body.path, undefined);
should.equal(body.derivedFromParentWithSeed, undefined);
return true;
})
.reply(200, { id: 'child-key-id', derivedFromParentWithHardenedPath: "m/7'", path: '/0/0' });
const result = await keychains.add({
pub: 'pub',
parent: 'parent-key-id',
safeId: 'safe-id',
derivedFromParentWithHardenedPath: "m/7'",
});
result.derivedFromParentWithHardenedPath.should.equal("m/7'");
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 && // Data Network
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').query(true).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 forward the enterprise param on the GET /tss/settings call', async function () {
// Exact query match (not .query(true)) — this only passes if `enterprise` is actually
// forwarded on the request, proving WCI-1358's fix rather than just tolerating it.
const tssSettingsNock = nock(bgUrl)
.get('/api/v2/tss/settings')
.query({ enterprise: 'enterprise-123' })
.reply(200, { coinSettings: {} });
sandbox.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise-123',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
tssSettingsNock.isDone().should.be.true();
});
});
['tsol'].forEach((coin) => {
it('should send no enterprise query param on GET /tss/settings when enterprise is not supplied', async function () {
const tssSettingsNock = nock(bgUrl).get('/api/v2/tss/settings').reply(200, { coinSettings: {} });
sandbox.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
tssSettingsNock.isDone().should.be.true();
});
});
['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').query(true).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').query(true).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')
.query(true)
.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2hhaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2tleWNoYWlucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLHFCQUFxQjtBQUNyQixFQUFFOztBQUVGLDRDQUF3RjtBQUN4RixpQ0FBaUM7QUFDakMsNEJBQTRCO0FBQzVCLDZCQUE4QjtBQUM5QixpQ0FBa0M7QUFDbEMsK0JBQStCO0FBRS9CLDhDQUE4RztBQUM5Ryw4Q0FBNEM7QUFDNUMsOENBQTJDO0FBRzNDLFFBQVEsQ0FBQyxjQUFjLEVBQUU7SUFDdkIsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksU0FBUyxDQUFDO0lBQ2QsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWpDLEtBQUssR0FBRyxpQkFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLO1lBQy9CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ3RCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLElBQUk7Z0JBQ3RDLElBQUksQ0FBQyxH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QkFBZSxDQUFDLFVBQVU7WUFDdEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU0sSUFBSSwyRUFBMkU7WUFDakgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUssSUFBSSwwRUFBMEU7WUFDL0csQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUssSUFBSSwyRUFBMkU7WUFDaEgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU8sSUFBSSw2RUFBNkU7WUFDcEgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUssSUFBSSwyRUFBMkU7WUFDaEgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEVBQUU7WUFDOUIsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUs7WUFDakMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU87WUFDbkMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU87WUFDbkMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU87WUFDbkMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUs7WUFDakMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLFFBQVE7WUFDcEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEVBQUUsSUFBSSxlQUFlO1lBQ2pELENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxPQUFPO1lBQ25DLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxJQUFJO1lBQ2hDLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxJQUFJO1lBQ2hDLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxTQUFTO1lBQ3JDLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJB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QyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUVBQXVFLEVBQUUsS0FBSztZQUMvRSxNQUFNLFNBQVMsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwRyxNQUFNLFNBQVMsQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIFRlc3QgZm9yIEtleWNoYWluc1xuLy9cblxuaW1wb3J0IHsgQ29pbkZhbWlseSwgQ29pbktpbmQsIGNvaW5zLCBLZXlDdXJ2ZSwgVW5kZXJseWluZ0Fzc2V0IH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbm9jayA9IHJlcXVpcmUoJ25vY2snKTtcbmltcG9ydCBzaG91bGQgPSByZXF1aXJlKCdzaG91bGQnKTtcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IHsgY29tbW9uLCBkZWNvZGVPckVsc2UsIEVDRFNBVXRpbHMsIEVERFNBVXRpbHMsIEtleWNoYWluLCBLZXljaGFpbnMsIE92Y1NoYXJlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uL3NyYy9iaXRnbyc7XG5pbXBvcnQgeyBTaW5vblN0dWIgfSBmcm9tICdzaW5vbic7XG5cbmRlc2NyaWJlKCdWMiBLZXljaGFpbnMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbztcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQga2V5Y2hhaW5zO1xuICBsZXQgYmdVcmw7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiaXRnby5zZXRWYWxpZGF0ZShmYWxzZSk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0bHRjJyk7XG4gICAga2V5Y2hhaW5zID0gYmFzZWNvaW4ua2V5Y2hhaW5zKCk7XG5cbiAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZCBLZXljaGFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGFkZCBhIGtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5wdWIuc2hvdWxkLmVxdWFsKCdwdWInKTtcbiAgICAgICAgICBib2R5LmRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQuc2hvdWxkLmVxdWFsKCdkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGtleWNoYWlucy5hZGQoeyBwdWI6ICdwdWInLCBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiAnZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCcgfSk7XG4gICAgICBzY29wZS5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBhIHNhZmUgY2hpbGQga2V5Y2hhaW4gd2l0aCBkZXJpdmVkRnJvbVBhcmVudFdpdGhIYXJkZW5lZFBhdGgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RsdGMva2V5JywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnB1Yi5zaG91bGQuZXF1YWwoJ3B1YicpO1xuICAgICAgICAgIGJvZHkucGFyZW50LnNob3VsZC5lcXVhbCgncGFyZW50LWtleS1pZCcpO1xuICAgICAgICAgIGJvZHkuc2FmZUlkLnNob3VsZC5lcXVhbCgnc2FmZS1pZCcpO1xuICAgICAgICAgIGJvZHkuZGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoLnNob3VsZC5lcXVhbChcIm0vNydcIik7XG4gICAgICAgICAgc2hvdWxkLmVxdWFsKGJvZHkucGF0aCwgdW5kZWZpbmVkKTtcbiAgICAgICAgICBzaG91bGQuZXF1YWwoYm9keS5kZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkLCB1bmRlZmluZWQpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7IGlkOiAnY2hpbGQta2V5LWlkJywgZGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoOiBcIm0vNydcIiwgcGF0aDogJy8wLzAnIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2V5Y2hhaW5zLmFkZCh7XG4gICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgIHBhcmVudDogJ3BhcmVudC1rZXktaWQnLFxuICAgICAgICBzYWZlSWQ6ICdzYWZlLWlkJyxcbiAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoSGFyZGVuZWRQYXRoOiBcIm0vNydcIixcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LmRlcml2ZWRGcm9tUGFyZW50V2l0aEhhcmRlbmVkUGF0aC5zaG91bGQuZXF1YWwoXCJtLzcnXCIpO1xuICAgICAgc2NvcGUuZG9uZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICAvKipcbiAgICogVGhpcyBzZWN0aW9uJ3MgaW50ZW50aW9uIGlzIHRvIHByb3ZpZGUgc29tZSBrZXkgZ2VuZXJhdGlvbiBzYW5pdHkgY2hlY2tpbmcuIGdlbmVyYXRlS2V5UGFpciBpcyBhIGdlbmVyYWwgc3VyZmFjZVxuICAgKiBmb3Iga2V5IGdlbmVyYXRpb24gYnV0IHRoZSBrZXlzIGFyZSB0cmVhdGVkIHRoZSBzYW1lIGJ5IEJpdEdvIGRvd24gdGhlIGxpbmUuIEFueSBTRUNQMjU2SzEgYmFzZWQgY29pbnMga2V5LXBhaXJzIGNhblxuICAgKiBiZSByZS11c2VkIHNvIG5lZWQgdG8gYmUgdGhlIHNhbWUuXG4gICAqKi9cbiAgZGVzY3JpYmUoJ0tleSBnZW5lcmF0aW9uIGVuZm9yY2VtZW50IGZvciBTRUNQMjU2SzEnLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaXRlcmF0ZSBvdmVyIG5vbi1maWF0IGNyeXB0byBzZWNwIGNvaW5zXG4gICAgY29uc3QgY29pbkZhbWlseVZhbHVlcyA9IE9iamVjdC5rZXlzKENvaW5GYW1pbHkpLm1hcCgobikgPT4gbi50b0xvd2VyQ2FzZSgpKTtcbiAgICBjb25zdCBjcnlwdG9TZWNwQ29pbnMgPSBjb2lucy5maWx0ZXIoXG4gICAgICAobikgPT5cbiAgICAgICAgbi5wcmltYXJ5S2V5Q3VydmUgPT09IEtleUN1cnZlLlNlY3AyNTZrMSAmJlxuICAgICAgICBuLmtpbmQgPT09IENvaW5LaW5kLkNSWVBUTyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuVVNEICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5BVkFYUCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQVBFQ0hBSU4gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkRPR0UgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkVUSFcgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LktBVkFDT1NNT1MgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkNPUkVVTSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQkVSQSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSVNMTSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQVJCRVRIICYmIC8vIFRPRE8oV0lOLTY5Mik6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIGFyYmV0aCBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuT1BFVEggJiYgLy8gVE9ETyhXSU4tNjkyKTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3Igb3BldGggaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlpLRVRIICYmIC8vIFRPRE8oV0lOLTE0MjcpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciB6a2V0aCBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuT0FTICYmIC8vIFRPRE8oV0lOLTM2OTYpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBvYXMgaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkNPUkVEQU8gJiYgLy8gVE9ETyhXSU4tMzY5Nik6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIGNvcmVkYW8gaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkZMUiAmJiAvLyBUT0RPKFdJTi00MjE1KTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgRkxSIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5TR0IgJiYgLy8gVE9ETyhXSU4tNDIxNik6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIFNHQiBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuV0VNSVggJiYgLy8gVE9ETyhXSU4tNDE3Nyk6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIFdFTUlYIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5YREMgJiYgLy8gVE9ETyhXSU4tNDE3Myk6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIFhEQyBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuUlVORSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQkFCWSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSUNQICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5NQU5UUkEgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1PTiAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuT0cgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LldPUkxEICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5QSFJTICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5DVEMgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkhZUEVFVk0gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlhQTCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuU09ORUlVTSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuVkVUICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5DUk9OT1MgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkZFVENIQUkgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LklOSVRJQSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQVNJICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5TT05JQyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuU0VJRVZNICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5LQUlBICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5JUllTICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5MSU5FQUVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSVAgJiYgLy8gRGF0YSBOZXR3b3JrXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5CQVNFRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5TT01JICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5GTFJQICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5GTFVFTlRFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1BTlRMRSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSE9PREVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSFBQRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5KT1ZBWUVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuT0tCWExBWUVSICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5VTklFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1PUlBIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5NT1JQSEVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuRE9HRU9TICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5NRUdBRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5BUkNVU0RDICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5aS1NZTkNFUkEgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkhZUEVSTElRVUlEICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5CT0JBRVRIICYmXG4gICAgICAgIGNvaW5GYW1pbHlWYWx1ZXMuaW5jbHVkZXMobi5uYW1lKVxuICAgICk7XG5cbiAgICBjb25zdCBleHBlY3RlZFhwdWIgPVxuICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHcFpmOG14TldoU1BkV2FMR3ZRenphZ2U2dnEyb1FGenE4dG9Wem1ranlnWVozSGNadzZlQ3pBZm45WmR5R2pLb0trY3BLd2Fja2Rnem5WYml1bnBxN3JreER1N3F1Uyc7XG4gICAgY29uc3QgZXhwZWN0ZWRYcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLNExWQzJrUk45WlZmNVVqcXNUaDlkTW0zSllSUkY0ajF4TFpleFRUV0NCTjRobWRaVUhlVDN2Q0pQTDE4MUVyVmFZNDg5QXJCS1NXYUI3RHU3dnlWUzZYQzQzV3RLN0EnO1xuXG4gICAgY29uc3Qgc2VlZCA9IEJ1ZmZlci5mcm9tKCd0aGlzIGlzIHNvbWUgcmFuZG9tIHNlZWQgd2Ugd2lsbCB1c2UnLCAndXRmLTgnKTtcblxuICAgIGNyeXB0b1NlY3BDb2lucy5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSB0aGUgc2FtZSAke2NvaW4ubmFtZX0ga2V5IHdpdGggdGhlIHNhbWUgc2VlZGAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudENvaW4gPSBiaXRnby5jb2luKGNvaW4ubmFtZSk7XG4gICAgICAgIGNvbnN0IGtleVBhaXIgPSBjdXJyZW50Q29pbi5nZW5lcmF0ZUtleVBhaXIoc2VlZCk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGtleVBhaXIucHViKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KGtleVBhaXIucHJ2KTtcblxuICAgICAgICBrZXlQYWlyLnB1Yi5zaG91bGQuZXF1YWwoZXhwZWN0ZWRYcHViKTtcbiAgICAgICAga2V5UGFpci5wcnYuc2hvdWxkLmVxdWFsKGV4cGVjdGVkWHBydik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1VwZGF0ZSBQYXNzd29yZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvbGRQYXNzd29yZCA9ICdvbGRQYXNzd29yZCc7XG4gICAgY29uc3QgbmV3UGFzc3dvcmQgPSAnbmV3UGFzc3dvcmQnO1xuICAgIGNvbnN0IG90aGVyUGFzc3dvcmQgPSAnb3RoZXJQYXNzd29yZCc7XG5cbiAgICBkZXNjcmliZSgnc2hvdWxkIGZhaWwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgc2FuZGJveDtcbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd0byB1cGRhdGUgdGhlIHBhc3N3b3JkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlUGFzc3dvcmQoeyBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBvbGRQYXNzd29yZCcpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAxMjM0LCBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiBvbGRQYXNzd29yZCBidXQgZm91bmQgbnVtYmVyJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHBhcmFtZXRlcjogbmV3UGFzc3dvcmQnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnLCBuZXdQYXNzd29yZDogNTY3OCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogbmV3UGFzc3dvcmQgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd0byB1cGRhdGUgdGhlIHBhc3N3b3JkIGZvciBhIHNpbmdsZSBrZXljaGFpbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgKCgpID0+IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KSkuc2hvdWxkLnRocm93KFxuICAgICAgICAgICdleHBlY3RlZCBvbGQgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnXG4gICAgICAgICk7XG5cbiAgICAgICAgKCgpID0+IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6IDEyMzQsIG5ld1Bhc3N3b3JkOiAnNTY3OCcgfSkpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAnZXhwZWN0ZWQgb2xkIHBhc3N3b3JkIHRvIGJlIGEgc3RyaW5nJ1xuICAgICAgICApO1xuXG4gICAgICAgICgoKSA9PiBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcgfSkpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAnZXhwZWN0ZWQgbmV3IHBhc3N3b3JkIHRvIGJlIGEgc3RyaW5nJ1xuICAgICAgICApO1xuXG4gICAgICAgICgoKSA9PiBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiA1Njc4IH0pKS5zaG91bGQudGhyb3coKTtcblxuICAgICAgICAoKCkgPT4ga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnLCBuZXdQYXNzd29yZDogJzU2NzgnIH0pKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgJ2V4cGVjdGVkIGtleWNoYWluIHRvIGJlIGFuIG9iamVjdCB3aXRoIGFuIGVuY3J5cHRlZFBydiBwcm9wZXJ0eSdcbiAgICAgICAgKTtcblxuICAgICAgICAoKCkgPT5cbiAgICAgICAgICBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZDogJzEyMzQnLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQ6ICc1Njc4JyxcbiAgICAgICAgICAgIGtleWNoYWluOiB7fSxcbiAgICAgICAgICB9KSkuc2hvdWxkLnRocm93KCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICAoKCkgPT5cbiAgICAgICAgICBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZDogJzEyMzQnLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQ6ICc1Njc4JyxcbiAgICAgICAgICAgIGtleWNoYWluOiB7IGVuY3J5cHRlZFBydjogMTIzIH0sXG4gICAgICAgICAgfSkpLnNob3VsZC50aHJvdygnZXhwZWN0ZWQga2V5Y2hhaW4gdG8gYmUgYW4gb2JqZWN0IHdpdGggYW4gZW5jcnlwdGVkUHJ2IHByb3BlcnR5Jyk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KSB9O1xuICAgICAgICAoKCkgPT4ga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQsIGtleWNoYWluIH0pKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgJ3Bhc3N3b3JkIHVzZWQgdG8gZGVjcnlwdCBrZXljaGFpbiBwcml2YXRlIGtleSBpcyBpbmNvcnJlY3QnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3RvIHVwZGF0ZSB0aGUgcGFzc3dvcmQgZm9yIGEgc2luZ2xlIGtleWNoYWluIChhc3luYyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBvbGQgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAxMjM0LCBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIG9sZCBwYXNzd29yZCB0byBiZSBhIHN0cmluZycpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBuZXcgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiA1Njc4IH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIG5ldyBwYXNzd29yZCB0byBiZSBhIHN0cmluZycpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JywgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiAnNTY3OCcsIGtleWNoYWluOiB7fSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZDogJzEyMzQnLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQ6ICc1Njc4JyxcbiAgICAgICAgICAgIGtleWNoYWluOiB7IGVuY3J5cHRlZFBydjogMTIzIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZXhwZWN0ZWQga2V5Y2hhaW4gdG8gYmUgYW4gb2JqZWN0IHdpdGggYW4gZW5jcnlwdGVkUHJ2IHByb3BlcnR5Jyk7XG5cbiAgICAgICAgLy8gd3JvbmcgcGFzc3dvcmQg4oCUIGRlY3J5cHQgZmFpbHNcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KSB9O1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCwga2V5Y2hhaW4gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmFpbGVkIHRvIHVwZGF0ZSBrZXljaGFpbiBwYXNzd29yZDogaW5jb3JyZWN0IHBhc3N3b3JkJyk7XG5cbiAgICAgICAgLy8gaW52YWxpZCBKU09OIGluIGVuY3J5cHRlZFBydlxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCwga2V5Y2hhaW46IHsgZW5jcnlwdGVkUHJ2OiAnbm90LXZhbGlkLWpzb24nIH0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmFpbGVkIHRvIHVwZGF0ZSBrZXljaGFpbiBwYXNzd29yZDogZGVjcnlwdDogY2lwaGVydGV4dCBpcyBub3QgdmFsaWQgSlNPTicpO1xuXG4gICAgICAgIC8vIHVua25vd24gZW52ZWxvcGUgdmVyc2lvblxuICAgICAgICBjb25zdCB1bmtub3duVmVyc2lvbkVudmVsb3BlID0gSlNPTi5zdHJpbmdpZnkoeyB2OiA5OSwgY3Q6ICdhYmMnIH0pO1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAgICBvbGRQYXNzd29yZCxcbiAgICAgICAgICAgIG5ld1Bhc3N3b3JkLFxuICAgICAgICAgICAga2V5Y2hhaW46IHsgZW5jcnlwdGVkUHJ2OiB1bmtub3duVmVyc2lvbkVudmVsb3BlIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZmFpbGVkIHRvIHVwZGF0ZSBrZXljaGFpbiBwYXNzd29yZDogZGVjcnlwdDogdW5rbm93biBlbnZlbG9wZSB2ZXJzaW9uIDk5Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ29uIGFueSBvdGhlciBlcnJvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZW5jWHBydjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViMScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWlucywgJ3VwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQnKS50aHJvd3MoJ2Vycm9yJywgJ3NvbWUgcmFuZG9tIGVycm9yJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3NvbWUgcmFuZG9tIGVycm9yJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzdWNjZXNzZnVsIHBhc3N3b3JkIHVwZGF0ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRlS2V5cyA9IGFzeW5jIGZ1bmN0aW9uIChrZXlzLCBuZXdQYXNzd29yZCwgZXhwZWN0ZWRMZW5ndGgpIHtcbiAgICAgICAgYXNzZXJ0Lm9rKE9iamVjdC5rZXlzKGtleXMpLmxlbmd0aCA9PT0gZXhwZWN0ZWRMZW5ndGgsICdzaG91bGQgaGF2ZSB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIGtleXMnKTtcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoa2V5cykpIHtcbiAgICAgICAgICBhc3NlcnQub2soa2V5LmluY2x1ZGVzKCd4cHViJykgfHwga2V5LmluY2x1ZGVzKCdyYW5kb21pZCcpLCAna2V5IHNob3VsZCBiZSB4cHViIG9yIHJhbmRvbWlkJyk7XG4gICAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiB2YWx1ZSBhcyBzdHJpbmcsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLnN0YXJ0V2l0aCgneHBydicpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpdCgncmVjZWl2ZSBvbmx5IG9uZSBwYWdlIHdoZW4gbGlzdGluZyBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjInLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjMgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MycsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViMScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWIyJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYyLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyYW5kb21pZDEnLFxuICAgICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjMsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgYXdhaXQgdmFsaWRhdGVLZXlzKGtleXMsIG5ld1Bhc3N3b3JkLCAyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmVjZWl2ZSBtdWx0aXBsZSBwYWdlcyB3aGVuIGxpc3Rpbmcga2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwcmV2SWQgPSAncHJldklkJztcbiAgICAgICAgY29uc3QgZW5jWHBydjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MicsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2M2EgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MycsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjNiID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjMnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnY0ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjQnLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBuZXh0QmF0Y2hQcmV2SWQ6IHByZXZJZCxcbiAgICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWIxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMScsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2M2EsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi90bHRjL2tleScpXG4gICAgICAgICAgLnF1ZXJ5KGZ1bmN0aW9uIHF1ZXJ5TmV4dFBhZ2VNYXRjaChxdWVyeU9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIHF1ZXJ5T2JqZWN0LnByZXZJZCA9PT0gcHJldklkO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjMnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjNiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjQnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGtleXMgPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgYXdhaXQgdmFsaWRhdGVLZXlzKGtleXMsIG5ld1Bhc3N3b3JkLCAzKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlIGtleWNoYWluIHBhc3N3b3JkIHVwZGF0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcHJ2ID0gJ3hwcnZ0ZXN0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgeHB1YjogJ3hwdWIxMjMnLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBuZXdLZXljaGFpbiA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsga2V5Y2hhaW4sIG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCB9KTtcblxuICAgICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IG5ld0tleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLmVxdWFsKHBydik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3NpbmdsZSBrZXljaGFpbiBwYXNzd29yZCB1cGRhdGUgZW1pdHMgYSB2MiAoQXJnb24yaWQpIGVudmVsb3BlIGZvciBhIHYyIGlucHV0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBwcnYgPSAneHBydnRlc3QtdjInO1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBlbmNyeXB0aW9uVmVyc2lvbjogMiB9KTtcbiAgICAgICAgY29uc3QgZW52ZWxvcGUgPSBKU09OLnBhcnNlKGVuY3J5cHRlZFBydik7XG4gICAgICAgIGVudmVsb3BlLnYuc2hvdWxkLmVxdWFsKDIsICdwcmUtY29uZGl0aW9uOiBrZXljaGFpbiBtdXN0IGJlIHYyLWVuY3J5cHRlZCcpO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWluID0geyB4cHViOiAneHB1YjEyMycsIGVuY3J5cHRlZFBydiB9O1xuICAgICAgICBjb25zdCBuZXdLZXljaGFpbiA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsga2V5Y2hhaW4sIG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCB9KTtcblxuICAgICAgICBjb25zdCBuZXdFbnZlbG9wZSA9IEpTT04ucGFyc2UobmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KTtcbiAgICAgICAgbmV3RW52ZWxvcGUudi5zaG91bGQuZXF1YWwoMiwgJ3JlLWVuY3J5cHRlZCBrZXljaGFpbiBtdXN0IHN0aWxsIGJlIHYyJyk7XG5cbiAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgZGVjcnlwdGVkUHJ2LnNob3VsZC5lcXVhbChwcnYsICduZXcgcGFzc3dvcmQgbXVzdCBkZWNyeXB0IHRvIG9yaWdpbmFsIHBydicpO1xuXG4gICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogbmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSkuc2hvdWxkLmJlLnJlamVjdGVkKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3NpbmdsZSBrZXljaGFpbiBwYXNzd29yZCB1cGRhdGUgcHJlc2VydmVzIGEgdjEgKFNKQ0wpIGVudmVsb3BlIGJ5IGRlZmF1bHQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBydiA9ICd4cHJ2dGVzdC12MSc7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogcHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQsIGVuY3J5cHRpb25WZXJzaW9uOiAxIH0pO1xuICAgICAgICBKU09OLnBhcnNlKGVuY3J5cHRlZFBydikuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCd2JywgMiwgJ3ByZS1jb25kaXRpb246IGlucHV0IG11c3Qgbm90IGJlIHYyJyk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IHhwdWI6ICd4cHViMTIzJywgZW5jcnlwdGVkUHJ2IH07XG4gICAgICAgIGNvbnN0IG5ld0tleWNoYWluID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBrZXljaGFpbiwgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pO1xuXG4gICAgICAgIEpTT04ucGFyc2UobmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ3YnLCAyLCAndjEga2V5Y2hhaW4gbXVzdCBzdGF5IHYxIGJ5IGRlZmF1bHQnKTtcblxuICAgICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IG5ld0tleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLmVxdWFsKHBydiwgJ25ldyBwYXNzd29yZCBtdXN0IGRlY3J5cHQgdG8gb3JpZ2luYWwgcHJ2Jyk7XG5cbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlIGtleWNoYWluIHBhc3N3b3JkIHVwZGF0ZSB1cGdyYWRlcyBhIHYxIGVudmVsb3BlIHRvIHYyIHdoZW4gZW5jcnlwdGlvblZlcnNpb246IDIgaXMgcGFzc2VkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBwcnYgPSAneHBydnRlc3QtdjEtb3B0LWluJztcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCwgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IHhwdWI6ICd4cHViMTIzJywgZW5jcnlwdGVkUHJ2IH07XG4gICAgICAgIGNvbnN0IG5ld0tleWNoYWluID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoe1xuICAgICAgICAgIGtleWNoYWluLFxuICAgICAgICAgIG9sZFBhc3N3b3JkLFxuICAgICAgICAgIG5ld1Bhc3N3b3JkLFxuICAgICAgICAgIGVuY3J5cHRpb25WZXJzaW9uOiAyLFxuICAgICAgICB9KTtcblxuICAgICAgICBKU09OLnBhcnNlKG5ld0tleWNoYWluLmVuY3J5cHRlZFBydikudi5zaG91bGQuZXF1YWwoMiwgJ3YyIG9wdC1pbiBtdXN0IGVtaXQgYSB2MiBlbnZlbG9wZScpO1xuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogbmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGRlY3J5cHRlZFBydi5zaG91bGQuZXF1YWwocHJ2LCAnbmV3IHBhc3N3b3JkIG11c3QgZGVjcnlwdCB0byBvcmlnaW5hbCBwcnYnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChcInVwZGF0ZVBhc3N3b3JkIHByZXNlcnZlcyBlYWNoIGtleWNoYWluJ3MgZXhpc3RpbmcgZW52ZWxvcGUgdmVyc2lvbiBieSBkZWZhdWx0XCIsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdjFQcnYgPSAneHBydi12MSc7XG4gICAgICAgIGNvbnN0IHYyUHJ2ID0gJ3hwcnYtdjInO1xuXG4gICAgICAgIGNvbnN0IGVuY1YxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiB2MVBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBlbmNyeXB0aW9uVmVyc2lvbjogMSB9KTtcbiAgICAgICAgY29uc3QgZW5jVjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHYyUHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQsIGVuY3J5cHRpb25WZXJzaW9uOiAyIH0pO1xuICAgICAgICBjb25zdCBlbmNPdGhlciA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYtb3RoZXInLCBwYXNzd29yZDogJ2RpZmZlcmVudC1wYXNzd29yZCcgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViLXYxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1YxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1Yi12MicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNWMixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWItb3RoZXInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jT3RoZXIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHVwZGF0ZWRLZXlzID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pO1xuXG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChPYmplY3Qua2V5cyh1cGRhdGVkS2V5cykubGVuZ3RoLCAyLCAnb25seSB0aGUgdHdvIG1hdGNoaW5nIGtleWNoYWlucyBzaG91bGQgYmUgdXBkYXRlZCcpO1xuXG4gICAgICAgIGNvbnN0IHVwZGF0ZWRWMSA9IHVwZGF0ZWRLZXlzWyd4cHViLXYxJ107XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRWMiA9IHVwZGF0ZWRLZXlzWyd4cHViLXYyJ107XG4gICAgICAgIGFzc2VydC5vayh1cGRhdGVkVjEsICd2MSBrZXljaGFpbiBtdXN0IGJlIGluIHRoZSByZXN1bHQnKTtcbiAgICAgICAgYXNzZXJ0Lm9rKHVwZGF0ZWRWMiwgJ3YyIGtleWNoYWluIG11c3QgYmUgaW4gdGhlIHJlc3VsdCcpO1xuXG4gICAgICAgIEpTT04ucGFyc2UodXBkYXRlZFYxKS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ3YnLCAyLCAndjEga2V5Y2hhaW4gbXVzdCBzdGF5IHYxIGJ5IGRlZmF1bHQnKTtcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkVjEgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHVwZGF0ZWRWMSwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRWMS5zaG91bGQuZXF1YWwodjFQcnYpO1xuXG4gICAgICAgIEpTT04ucGFyc2UodXBkYXRlZFYyKS52LnNob3VsZC5lcXVhbCgyLCAndjIga2V5Y2hhaW4gbXVzdCByZW1haW4gdjIgYWZ0ZXIgcGFzc3dvcmQgY2hhbmdlJyk7XG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFYyID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiB1cGRhdGVkVjIsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgZGVjcnlwdGVkVjIuc2hvdWxkLmVxdWFsKHYyUHJ2KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgdXBkYXRlZCBrZXlzIHdpdGggaWRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBlbmNYcHJ2MSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2MiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYyJywgcGFzc3dvcmQ6IG90aGVyUGFzc3dvcmQgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi90bHRjL2tleScpXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyYW5kb21pZDEnLFxuICAgICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMicsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUtleXMoa2V5cywgbmV3UGFzc3dvcmQsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdXBkYXRlIG11bHRpLXVzZXItb2ZjIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjInLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgICAgIG9mYzoge1xuICAgICAgICAgICAgICAgICAgICBmZWF0dXJlczogWydtdWx0aS11c2VyLWtleSddLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6ICdyYW5kb21pZDInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjIsXG4gICAgICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgICAgICBvZmM6IHtcbiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXM6IFsnbXVsdGktdXNlci1rZXknXSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUtleXMoa2V5cywgbmV3UGFzc3dvcmQsIDEpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQ3JlYXRlIFRTUyBLZXljaGFpbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGxldCBzYW5kYm94O1xuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgWyd0c29sJywgJ3Rkb3QnLCAndG5lYXInXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgY3JlYXRlIEVERFNBIFRTUyBLZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2FuZGJveC5zdHViKEVERFNBVXRpbHMuZGVmYXVsdC5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKS5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGtleWNoYWlucy5zaG91bGQuZGVlcEVxdWFsKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0YnNjJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGNyZWF0ZSBFQ0RTQSBUU1MgS2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvaW5TZXR0aW5nczoge30sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2FuZGJveC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKS5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGtleWNoYWlucy5zaG91bGQuZGVlcEVxdWFsKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0c29sJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGZvcndhcmQgdGhlIGVudGVycHJpc2UgcGFyYW0gb24gdGhlIEdFVCAvdHNzL3NldHRpbmdzIGNhbGwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gRXhhY3QgcXVlcnkgbWF0Y2ggKG5vdCAucXVlcnkodHJ1ZSkpIOKAlCB0aGlzIG9ubHkgcGFzc2VzIGlmIGBlbnRlcnByaXNlYCBpcyBhY3R1YWxseVxuICAgICAgICAgIC8vIGZvcndhcmRlZCBvbiB0aGUgcmVxdWVzdCwgcHJvdmluZyBXQ0ktMTM1OCdzIGZpeCByYXRoZXIgdGhhbiBqdXN0IHRvbGVyYXRpbmcgaXQuXG4gICAgICAgICAgY29uc3QgdHNzU2V0dGluZ3NOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdHNzL3NldHRpbmdzJylcbiAgICAgICAgICAgIC5xdWVyeSh7IGVudGVycHJpc2U6ICdlbnRlcnByaXNlLTEyMycgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHsgY29pblNldHRpbmdzOiB7fSB9KTtcbiAgICAgICAgICBzYW5kYm94LnN0dWIoRUREU0FVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBhd2FpdCBiaXRnby5jb2luKGNvaW4pLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlLTEyMycsXG4gICAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRzc1NldHRpbmdzTm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBbJ3Rzb2wnXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgc2VuZCBubyBlbnRlcnByaXNlIHF1ZXJ5IHBhcmFtIG9uIEdFVCAvdHNzL3NldHRpbmdzIHdoZW4gZW50ZXJwcmlzZSBpcyBub3Qgc3VwcGxpZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgdHNzU2V0dGluZ3NOb2NrID0gbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpLnJlcGx5KDIwMCwgeyBjb2luU2V0dGluZ3M6IHt9IH0pO1xuICAgICAgICAgIHNhbmRib3guc3R1YihFRERTQVV0aWxzLmRlZmF1bHQucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuICAgICAgICAgIGF3YWl0IGJpdGdvLmNvaW4oY29pbikua2V5Y2hhaW5zKCkuY3JlYXRlTXBjKHtcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0c3NTZXR0aW5nc05vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0c29sJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHBhc3Mgd2ViYXV0aG5JbmZvIHRvIGNyZWF0ZUtleWNoYWlucyBmb3IgRUREU0EgVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdlYmF1dGhuSW5mbyA9IHtcbiAgICAgICAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTEnLFxuICAgICAgICAgICAgcHJmU2FsdDogJ3NhbHQtMScsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiAncHJmLWRlcml2ZWQtcGFzc3BocmFzZScsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCBjcmVhdGVLZXljaGFpbnMgPSBzYW5kYm94XG4gICAgICAgICAgICAuc3R1YihFRERTQVV0aWxzLmRlZmF1bHQucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJylcbiAgICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICB3ZWJhdXRobkluZm8sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY3JlYXRlS2V5Y2hhaW5zLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICBjcmVhdGVLZXljaGFpbnMuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dlYmF1dGhuSW5mbycsIHdlYmF1dGhuSW5mbyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIFsndGJzYyddLmZvckVhY2goKGNvaW4pID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3Qgc2FmZSByb290IGNyZWF0aW9uIHdoZW4gdGhlIHJlc29sdmVkIGNlcmVtb255IGlzIGxlZ2FjeSBNUEN2MScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjIvdHNzL3NldHRpbmdzJykucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb2luU2V0dGluZ3M6IHt9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBhd2FpdCBiaXRnb1xuICAgICAgICAgICAgLmNvaW4oY29pbilcbiAgICAgICAgICAgIC5rZXljaGFpbnMoKVxuICAgICAgICAgICAgLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgICAgc2FmZUlkOiAnc2FmZUlkJyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvbGVnYWN5IE1QQ3YxIGNlcmVtb255Lyk7XG4gICAgICAgICAgY3JlYXRlS2V5Y2hhaW5zLmNhbGxlZC5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0YnNjJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHBhc3Mgd2ViYXV0aG5JbmZvIHRvIGNyZWF0ZUtleWNoYWlucyBmb3IgRUNEU0EgVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvaW5TZXR0aW5nczoge30sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3Qgd2ViYXV0aG5JbmZvID0ge1xuICAgICAgICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMScsXG4gICAgICAgICAgICBwcmZTYWx0OiAnc2FsdC0xJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAgIC5zdHViKEVDRFNBVXRpbHMuRWNkc2FVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBhd2FpdCBiaXRnby5jb2luKGNvaW4pLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgIHdlYmF1dGhuSW5mbyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIGNyZWF0ZUtleWNoYWlucy5maXJzdENhbGwuYXJnc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2ViYXV0aG5JbmZvJywgd2ViYXV0aG5JbmZvKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdSZWNyZWF0ZSBLZXljaGFpbnMgZnJvbSBNUENWMSB0byBNUENWMicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSAnaHRldGgnO1xuICAgICAgY29uc3Qgd2FsbGV0SWQgPSAnd2FsbGV0SWQnO1xuICAgICAgY29uc3Qgb3RwID0gJzAwMDAwMCc7XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgICBjb25zdCBkZWNyeXB0UmVzdWx0ID0gSlNPTi5zdHJpbmdpZnkoeyBrZXk6ICdkZWNyeXB0ZWQnIH0pO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY29pblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIGV0aDoge1xuICAgICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKGRlY3J5cHRSZXN1bHQpO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIGVtcHR5IHN0cmluZ3MgYXJlIHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXM6IFBhcmFtZXRlcnM8S2V5Y2hhaW5zWydyZWNyZWF0ZU1wYyddPlswXSA9IHtcbiAgICAgICAgICBjb2luLFxuICAgICAgICAgIHdhbGxldElkLFxuICAgICAgICAgIG90cCxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZCcsXG4gICAgICAgICAgICBlbmNyeXB0ZWRCYWNrdXBLZXk6ICdlbmNyeXB0ZWQnLFxuICAgICAgICAgICAgZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZTogJ3Bhc3NwaHJhc2UnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnJlY3JlYXRlTXBjKHsgLi4ucGFyYW1zLCBjb2luOiAnJyB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGNvaW4nKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAucmVjcmVhdGVNcGMoeyAuLi5wYXJhbXMsIHdhbGxldElkOiAnJyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIHdhbGxldElkJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnJlY3JlYXRlTXBjKHsgLi4ucGFyYW1zLCBvdHA6ICcnIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0gb3RwJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnJlY3JlYXRlTXBjKHsgLi4ucGFyYW1zLCBwYXNzcGhyYXNlOiAnJyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIHBhc3NwaHJhc2UnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAucmVjcmVhdGVNcGMoe1xuICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgICAgLi4ucGFyYW1zLmVuY3J5cHRlZE1hdGVyaWFsLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyk7XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC5yZWNyZWF0ZU1wYyh7XG4gICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgICAuLi5wYXJhbXMuZW5jcnlwdGVkTWF0ZXJpYWwsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFVzZXJLZXk6ICcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGVuY3J5cHRlZFVzZXJLZXknKTtcbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnJlY3JlYXRlTXBjKHtcbiAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgIGVuY3J5cHRlZE1hdGVyaWFsOiB7XG4gICAgICAgICAgICAgIC4uLnBhcmFtcy5lbmNyeXB0ZWRNYXRlcmlhbCxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBlbmNyeXB0ZWRCYWNrdXBLZXknKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgb3RwIHVubG9jayBmYWlscycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS91c2VyL3VubG9jaycpLnJlcGx5V2l0aEVycm9yKCdvdHAgZXJyb3InKTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGNvaW4sXG4gICAgICAgICAgd2FsbGV0SWQsXG4gICAgICAgICAgb3RwLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFVzZXJLZXk6ICdlbmNyeXB0ZWRVc2VyS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZEJhY2t1cEtleTogJ2VuY3J5cHRlZEJhY2t1cEtleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAnZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdvdHAgZXJyb3InKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgcGFzc2NvZGUgcmVjb3ZlcnkgYXBpIGNhbGwgZmFpbHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvdXNlci91bmxvY2snKS5yZXBseSgyMDAsIHsgb3RwIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0vd2FsbGV0LyR7d2FsbGV0SWR9L3Bhc3Njb2RlcmVjb3ZlcnlgKVxuICAgICAgICAgIC5yZXBseVdpdGhFcnJvcigncGFzc2NvZGUgcmVjb3ZlcnkgZXJyb3InKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgY29pbixcbiAgICAgICAgICB3YWxsZXRJZCxcbiAgICAgICAgICBvdHAsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZFVzZXJLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnZW5jcnlwdGVkQmFja3VwS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICdlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWlucy5yZWNyZWF0ZU1wYyhwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3Bhc3Njb2RlIHJlY292ZXJ5IGVycm9yJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHBhc3Njb2RlIHJlY292ZXJ5IGFwaSBjYWxsIHJldHVybnMgaW52YWxpZCByZWNvdmVyeSBpbmZvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL3VzZXIvdW5sb2NrJykucmVwbHkoMjAwLCB7IG90cCB9KTtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC8ke3dhbGxldElkfS9wYXNzY29kZXJlY292ZXJ5YCkucmVwbHkoMjAwLCB7IHJlY292ZXJ5SW5mbzoge30gfSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIGNvaW4sXG4gICAgICAgICAgd2FsbGV0SWQsXG4gICAgICAgICAgb3RwLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFVzZXJLZXk6ICdlbmNyeXB0ZWRVc2VyS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZEJhY2t1cEtleTogJ2VuY3J5cHRlZEJhY2t1cEtleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAnZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdmYWlsZWQgdG8gZ2V0IHJlY292ZXJ5IGluZm8nKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgY3JlYXRlTXBjIHdpdGggdGhlIGNvcnJlY3QgcGFyYW1ldGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS91c2VyL3VubG9jaycpLnJlcGx5KDIwMCwgeyBvdHAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvJHt3YWxsZXRJZH0vcGFzc2NvZGVyZWNvdmVyeWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyByZWNvdmVyeUluZm86IHsgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJzEyMycgfSB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgY29pbixcbiAgICAgICAgICB3YWxsZXRJZDogJ3dhbGxldElkJyxcbiAgICAgICAgICBvdHAsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZFVzZXJLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnZW5jcnlwdGVkQmFja3VwS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICdlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjcmVhdGVNcGNTdHViID0gc2lub24uc3R1YihrZXljaGFpbnMsICdjcmVhdGVNcGMnKS5yZXNvbHZlcygpO1xuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMocGFyYW1zKTtcblxuICAgICAgICBhc3NlcnQub2soXG4gICAgICAgICAgY3JlYXRlTXBjU3R1Yi5jYWxsZWRPbmNlV2l0aCh7XG4gICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcmV0cm9maXQ6IHtcbiAgICAgICAgICAgICAgZGVjcnlwdGVkVXNlcktleTogZGVjcnlwdFJlc3VsdCxcbiAgICAgICAgICAgICAgZGVjcnlwdGVkQmFja3VwS2V5OiBkZWNyeXB0UmVzdWx0LFxuICAgICAgICAgICAgICB3YWxsZXRJZDogcGFyYW1zLndhbGxldElkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlcihmdW5jdGlvbiBhZnRlclVwZGF0ZVBhc3N3b3JkKCkge1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0NyZWF0ZSBCaXRHbyBLZXkgZnJvbSBPVkMgSlNPTicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiaXRHb0tleVJlc3VsdCA9IHtcbiAgICAgIGlkOiAnNjQyMWViNzU1ZmVhOWUwMDA2YzJjMDQwMDcyZjc0YmInLFxuICAgICAgY29tbW9uS2V5Y2hhaW46ICcxMjMnLFxuICAgICAgd2FsbGV0SFNNR1BHUHVibGljS2V5U2lnczogJzEyMycsXG4gICAgICB2ZXJpZmllZFZzc1Byb29mOiB0cnVlLFxuICAgICAga2V5U2hhcmVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBmcm9tOiAnYml0Z28nLFxuICAgICAgICAgIHRvOiAndXNlcicsXG4gICAgICAgICAgcHVibGljU2hhcmU6ICdjY2MnLFxuICAgICAgICAgIHByaXZhdGVTaGFyZTogJ2NjYyBwcml2YXRlJyxcbiAgICAgICAgICBwYWlsbGllclB1YmxpY0tleTogJ2NjYyBwYWlsbGllcicsXG4gICAgICAgICAgdnNzUHJvb2Y6ICdjY2MgdnNzIHByb29mJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiaXRnbycsXG4gICAgICAgICAgdG86ICdiYWNrdXAnLFxuICAgICAgICAgIHB1YmxpY1NoYXJlOiAnZmZmJyxcbiAgICAgICAgICBwcml2YXRlU2hhcmU6ICdmZmYgcHJpdmF0ZScsXG4gICAgICAgICAgcGFpbGxpZXJQdWJsaWNLZXk6ICdmZmYgcGFpbGxpZXInLFxuICAgICAgICAgIHZzc1Byb29mOiAnZmZmIHZzcyBwcm9vZicsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBjb25zdCBvdmNPdXRwdXRKc29uID0ge1xuICAgICAgdHNzVmVyc2lvbjogJzAuMC4xJyxcbiAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgY29pbjogJ3NvbCcsXG4gICAgICBzdGF0ZTogMSxcbiAgICAgIG92Yzoge1xuICAgICAgICAxOiB7XG4gICAgICAgICAgZ3BnUHViS2V5OlxuICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N29cXG49dmpnbFxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIG92Y1RvQml0Z29TaGFyZToge1xuICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWQvd1EvQWh3SVJzU2YvNmlId21IS3ZFWUF3ZmFMdFRRb3RTNkJ3Wm1cXG5hWDAwVDdMdW1HSXJOWnpCZ2NnZ0JLTWwrOE9tb204bVg1c1A4RlVFNDUxaVpqQm1YbGtwSGxwQXFza1NcXG5FaTVTZmpsc1QzMXV0b0xhQkxBN05qTlNteVlISWl5Zmg2WW53ZlY1VTcyazZoaGZwdURTc1FHeThZeHBcXG5NMmRWbE40dW9PMzF6Z1FQZitmZ0prWnZBUHd2allMQkw0TzhoczIxSEdmMFZ2Rzk5YnJrNHhsRlZSaHdcXG5RbnVQcE01MUdPczR2VXRiTE5TWW5BdWhVNFJlWHd3RFY5WHUwTVhBamZRTWsyRTN3UUxHUSs4MnV2MkJcXG4xaFBEOW5ESFR0QWRXclhkNlpqWEZyRzRNZjJNUUJ4eVNGdlZTbkZpNnlTdGpmWmVpS2NENVZnMzhQakdcXG5XZzFPNU4zL3BhcTk4SGZIMFE0cU5LR1psandvM29FUVp6bFltMmtWbkkwUFVMb01ZZz09XFxuPW92QXhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgICAgICBpOiAzLFxuICAgICAgICAgICAgajogMSxcbiAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzcTlSTUZLNEVFQUFvQ0F3UmdEcGdtMWJwdFJUNXlMT01hZGNHQUh1dmt4SVNMOC8zeFB5L0RcXG5ZQSsxTmdCcUlGSy8zT09YeHA3M1R2ODZidDFkZ0g3T0QxQUNPMG1WWEFvWDVFYVZ6V1p2ZG1NdE1TMTFcXG5jMlZ5TFdSbU1qUXdPV1kwTldOaE1UWm1OVFUzT0dOa016QXhNeUE4YjNaakxURXRkWE5sY2kxa1pqSTBcXG5NRGxtTkRWallURTJaalUxTnpoalpETXdNVE5BWkdZeU5EQTVaalExWTJFeE5tWTFOVGM0WTJRek1ERXpcXG5MbU52YlQ3Q2pBUVFFd2dBSFFVQ1pCc3E5UVFMQ1FjSUF4VUlDZ1FXQUFJQkFoa0JBaHNEQWg0QkFDRUpcXG5FT1VlQzdRckdMKzJGaUVFak42dlBVRlJ3ZVZ0REtGWjVSNEx0Q3NZdjdaN29BRUF2TkthSnJUSXMza3lcXG5ieGprVWljc3V4T3lBMm9XR2FySkg2VEdsV0Y2V0Q4QS8zRUllWnpQS1NMYVcrM2VucGJDUGlVOFJWRHBcXG5DNnlvNk5NQXFLcDRYbHlRemxNRVpCc3E5UklGSzRFRUFBb0NBd1FXbFdQTk1wazNhZkV6ZmdHMHhGZzRcXG5DRWpZN2ZHTzM1bjQ3blo0cXhqRVh6MlhONEkyM3hGTWl3WmJYYnB0RFhscW03VzlaQUhLaTg5MmgrWXRcXG5VNEI2QXdFSUI4SjRCQmdUQ0FBSkJRSmtHeXIxQWhzTUFDRUpFT1VlQzdRckdMKzJGaUVFak42dlBVRlJcXG53ZVZ0REtGWjVSNEx0Q3NZdjdZcVp3RDhETFJ1bmVCMEhFekJDeXJFNFlMK1VIYW9mb0hRWDErblJoMGpcXG44MnFhRHpBQS9pM1UxU29FSWkzMllNcm9yTkc1MHZiNHZhRVBiYlltZmdsYitKUTFZeDdvempNRVpCc3FcXG45UllKS3dZQkJBSGFSdzhCQVFkQVMxNTM0TGRDQzYwQVNwRWduRUJDOHBXUFNPV1dCTFh5V2FCaEVPVzJcXG4vaWpDZUFRWUV3Z0FDUVVDWkJzcTlRSWJJQUFoQ1JEbEhndTBLeGkvdGhZaEJJemVyejFCVWNIbGJReWhcXG5XZVVlQzdRckdMKzJGVVlBL0FnTVU0VjdDN0kvNUh3SzczbWN0YUdYTmRmVnIvbXVSTU5PR1cvQ0F4VkxcXG5BUDlLYUJyOTVvMzJvRU41ZW83dFdGQnlvT0NDazlKTWpzMzZDcTdvK3NSMzFBPT1cXG49ZVozQlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIDI6IHtcbiAgICAgICAgICBncGdQdWJLZXk6XG4gICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgydz09XFxuPUV0dHVcXG4tLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuJyxcbiAgICAgICAgICBvdmNUb0JpdGdvU2hhcmU6IHtcbiAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAnZWNmOTVlOWJhNmYwMmMwYmM0YzJhYjI1NDU2NWQyMWExNTYyMDU5YzhhMWFiNzBkMjg2ZmEwNGFlMmM1MTFlMDQ5MTQxMGI2ZDZmYThhYjIyZTY5MWJlZDc5MzhhN2FkYWFiZmE4ZDlkNTlhYWI5Y2MyYzA3OGNkMzdkZGUwMWInLFxuICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVlMW5ZTnY5RG5IbDhIWDhqTnMzcmVHczVuUFQyYk56R01DRkwwTjNQXFxuS0x3R2Q4REJrREpJTXBvQ2xhQVMvSFRVVFBUUnpqNFUxR1NoVjc5SStiYmZUREJWNnVoeWZaN2E4OGRWXFxuUkRUWGw2cmNoRmwvZm13TG9YbnFIK0JEUEVYeXRwQXZLd0RyQWc1NVQvSDdhb3A1UWJmU3NRRXJFdjdYXFxuVHBUTEhISGZsRUVRTDYycDFSbm5xMmtLdndKSzdUWTFnNVJ0UGdZWEg2R0VzMzNETHVsUGVVczhVa0txXFxuVFBMZjIrMUtDTFl5ek13bVNpOEtFQzhISmIwdkFrWFpBbFoxK0RvWjJQZmlJSmNWbno3YTNvbWppUDc3XFxuaG1DOHBoVGNKNzE4VXhJQjA5Zjh1aWMwL2ZNN0ZOdTBKSEZnUkRBNjl6emVGWW5aYzJYTlFnNWhzL2RaXFxuWjhBaXRQNHJuYUFmcHJzcTRyQUVFL2MzVHJtOXR6UUhaUENxci8yczRMbHV5VU1WSnc9PVxcbj1JSlpIXFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICB2c3NQcm9vZjogJzMwOWQyZmVmMjI3MmFkMzEzNzU5NTRiOTlhODYyNzQyZjIyZDgwMjNlZWY5ODU1YjhhZTI2ZWE4NGUwOGJmNWUnLFxuICAgICAgICAgICAgaTogMyxcbiAgICAgICAgICAgIGo6IDIsXG4gICAgICAgICAgICB1U2lnOiAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgyODR6XFxuQkdRYkt6UVdDU3NHQVFRQjJrY1BBUUVIUUlWVG1sdDhhL2ZqSkNZOVV5UDhKNTFlVFBYOVBNUkYzL0hyXFxuQll3dGZPWll3bmdFR0JNSUFBa0ZBbVFiS3pRQ0d5QUFJUWtRdGdKT1J0a3BPMlVXSVFTMDZVcEJUbnQyXFxubzI2cUxucTJBazVHMlNrN1pjdGhBUUQ0ZWszYXFVREViaGZSSG9sbTRqRmhJUEliYjloVUp3dUJSMFI0XFxuK2d2YWVBRUFrOHVrNWNFQUNlcW1wZEVGNTJvR3g3am1HQ29YNzNBSUlMWVZjZjlpTWtJPVxcbj05MkhmXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvdmNUb092Y1NoYXJlOiB7XG4gICAgICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAgICAgJ2VjZjk1ZTliYTZmMDJjMGJjNGMyYWIyNTQ1NjVkMjFhMTU2MjA1OWM4YTFhYjcwZDI4NmZhMDRhZTJjNTExZTA0OTE0MTBiNmQ2ZmE4YWIyMmU2OTFiZWQ3OTM4YTdhZGFhYmZhOGQ5ZDU5YWFiOWNjMmMwNzhjZDM3ZGRlMDFiJyxcbiAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNEQrRjN2STk2MnpWTVNBZ01FTnkyWDl4RElPbTFnd09mTWRMLzF2WmplTVcvaWxlL2YyZFJJUDJHVlxcbnY0dzYwSzkyK21ISTl5b29VMVZUNzdqWnJWT2NOSzQxREZOQ0YvZnVvVVUrVnpCT04wSTFoSHlYbTJRSlxcbndMK25OZHZBWHdSdjduU0ZEM0FCVW1SWWRHNzFBRklXalcyTCsxQzJoeHBzTmxtZHhmZlNzUUhIVDl1UFxcbkJOcEZZZ1FONzdPVXhjZ3J3ZVNWclB5ZXIxckNROG8rUW5vSzIvaEl4OVBsSlprY2wzdXdGNlRwQnRqc1xcbnF2UnhUaG9tb0h5bzBoSkhHMHZtSTQyR3E1dTB0Y1NlVTkwMmVmcENEYWVKaFBWT2lxSVNvSjk2d24wclxcbkZCM2xZTFNmbE9wQ0xBRTduc1pKUm9YQTZha1U3eE1DTU5BKytkNHR2NnA5OEZRK01aNmU5eDZraVN3MVxcbk0rVldqK1B2TjFkdFE4Zk5Zd3BKZjdLQmZEMXc2SVNNRkRtZXdrREU3aUJPWEY2Rkx3PT1cXG49KzNZY1xcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICAgICAgdnNzUHJvb2Y6ICczMDlkMmZlZjIyNzJhZDMxMzc1OTU0Yjk5YTg2Mjc0MmYyMmQ4MDIzZWVmOTg1NWI4YWUyNmVhODRlMDhiZjVlJyxcbiAgICAgICAgICAgIGk6IDEsXG4gICAgICAgICAgICBqOiAyLFxuICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMjg0elxcbkJHUWJLelFXQ1NzR0FRUUIya2NQQVFFSFFOVkdnMHZQc2ZLMXlKakZ1RFlCOFRqN0NRUkhLR0FWRURjalxcbmgvUUlxcjBLd25nRUdCTUlBQWtGQW1RYkt6UUNHeUFBSVFrUXRnSk9SdGtwTzJVV0lRUzA2VXBCVG50Mlxcbm8yNnFMbnEyQWs1RzJTazdaUzlvQVFDZTJ6SkQ1SXRXMkdFZ0FpdG5ZK05yTEJqYlhJNitMWTI5R2pSYVxcbmY2eUZUUUQvY1AwRTFEbGVxWE1qZ2ZSK2V3dDZxdVZGTVplYmhyM3RCci9IMFp2LzlFQT1cXG49OGFpK1xcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgZXhwZWN0ZWRCaXRHb091dHB1dCA9IHtcbiAgICAgIHdhbGxldDoge1xuICAgICAgICAuLi5vdmNPdXRwdXRKc29uLFxuICAgICAgICBzdGF0ZTogMixcbiAgICAgICAgcGxhdGZvcm06IHtcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogYml0R29LZXlSZXN1bHQuY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgd2FsbGV0R3BnUHViS2V5U2lnczogYml0R29LZXlSZXN1bHQud2FsbGV0SFNNR1BHUHVibGljS2V5U2lncyxcbiAgICAgICAgICBvdmM6IHtcbiAgICAgICAgICAgIDE6IHtcbiAgICAgICAgICAgICAgYml0Z29Ub092Y1NoYXJlOiB7XG4gICAgICAgICAgICAgICAgaTogMSxcbiAgICAgICAgICAgICAgICBqOiAzLFxuICAgICAgICAgICAgICAgIHB1YmxpY1NoYXJlOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMF0ucHVibGljU2hhcmUsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMF0ucHJpdmF0ZVNoYXJlLFxuICAgICAgICAgICAgICAgIHBhaWxsaWVyUHVibGljS2V5OiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMF0ucGFpbGxpZXJQdWJsaWNLZXksXG4gICAgICAgICAgICAgICAgdnNzUHJvb2Y6IGJpdEdvS2V5UmVzdWx0LmtleVNoYXJlc1swXS52c3NQcm9vZixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAyOiB7XG4gICAgICAgICAgICAgIGJpdGdvVG9PdmNTaGFyZToge1xuICAgICAgICAgICAgICAgIGk6IDIsXG4gICAgICAgICAgICAgICAgajogMyxcbiAgICAgICAgICAgICAgICBwdWJsaWNTaGFyZTogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzFdLnB1YmxpY1NoYXJlLFxuICAgICAgICAgICAgICAgIHByaXZhdGVTaGFyZTogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzFdLnByaXZhdGVTaGFyZSxcbiAgICAgICAgICAgICAgICBwYWlsbGllclB1YmxpY0tleTogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzFdLnBhaWxsaWVyUHVibGljS2V5LFxuICAgICAgICAgICAgICAgIHZzc1Byb29mOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMV0udnNzUHJvb2YsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gICAgaXQoJ1BhcnNlcyB0aGUgT1ZDIEpTT04gZmlsZSBwcm9wZXJseSBhbmQgY3JlYXRlcyB0aGUgbmV4dCBpbnB1dCBmb3IgT1ZDJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycsIGtleVR5cGU6ICd0c3MnIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCBiaXRHb0tleVJlc3VsdCk7XG4gICAgICBjb25zdCBwbGF0Zm9ybU91dHB1dCA9IGF3YWl0IGJpdGdvLmNvaW4oJ3Rzb2wnKS5rZXljaGFpbnMoKS5jcmVhdGVUc3NCaXRHb0tleUZyb21PdmNTaGFyZXMob3ZjT3V0cHV0SnNvbik7XG4gICAgICBzaG91bGQuZXF1YWwocGxhdGZvcm1PdXRwdXQuYml0R29LZXlJZCwgYml0R29LZXlSZXN1bHQuaWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChwbGF0Zm9ybU91dHB1dC5iaXRHb091dHB1dEpzb25Gb3JPdmMsIGV4cGVjdGVkQml0R29PdXRwdXQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Bhc3NlcyB0aGUgZW50ZXJwcmlzZSB3aXRoIGNvcnJlY3QgdmFsdWUgdG8gYml0Z28gaWYgcHJvdmlkZWQgYnkgY2FsbGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z29Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycsIGtleVR5cGU6ICd0c3MnIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCAodXJpLCBib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbnRlcnByaXNlJyk7XG4gICAgICAgICAgYm9keS5lbnRlcnByaXNlLnNob3VsZC5lcXVhbCgnZW50ZXJwcmlzZUlkJyk7XG4gICAgICAgICAgcmV0dXJuIGJpdEdvS2V5UmVzdWx0O1xuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IHBsYXRmb3JtT3V0cHV0ID0gYXdhaXQgYml0Z29cbiAgICAgICAgLmNvaW4oJ3Rzb2wnKVxuICAgICAgICAua2V5Y2hhaW5zKClcbiAgICAgICAgLmNyZWF0ZVRzc0JpdEdvS2V5RnJvbU92Y1NoYXJlcyhvdmNPdXRwdXRKc29uLCAnZW50ZXJwcmlzZUlkJyk7XG4gICAgICBzaG91bGQuZXF1YWwocGxhdGZvcm1PdXRwdXQuYml0R29LZXlJZCwgYml0R29LZXlSZXN1bHQuaWQpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChwbGF0Zm9ybU91dHB1dC5iaXRHb091dHB1dEpzb25Gb3JPdmMsIGV4cGVjdGVkQml0R29PdXRwdXQpO1xuICAgICAgYml0Z29Ob2NrLmlzRG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1Nob3VsZCBmYWlsIGlmIHRoZSBzdGF0ZSBpcyBub3QgMScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG92Y091dHB1dEpzb24gPSB7XG4gICAgICAgIHRzc1ZlcnNpb246ICcwLjAuMScsXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICBjb2luOiAnc29sJyxcbiAgICAgICAgc3RhdGU6IDAsXG4gICAgICAgIG92Yzoge1xuICAgICAgICAgIDE6IHtcbiAgICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N29cXG49dmpnbFxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgb3ZjVG9CaXRnb1NoYXJlOiB7XG4gICAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVkL3dRL0Fod0lSc1NmLzZpSHdtSEt2RVlBd2ZhTHRUUW90UzZCd1ptXFxuYVgwMFQ3THVtR0lyTlp6QmdjZ2dCS01sKzhPbW9tOG1YNXNQOEZVRTQ1MWlaakJtWGxrcEhscEFxc2tTXFxuRWk1U2ZqbHNUMzF1dG9MYUJMQTdOak5TbXlZSElpeWZoNllud2ZWNVU3Mms2aGhmcHVEU3NRR3k4WXhwXFxuTTJkVmxONHVvTzMxemdRUGYrZmdKa1p2QVB3dmpZTEJMNE84aHMyMUhHZjBWdkc5OWJyazR4bEZWUmh3XFxuUW51UHBNNTFHT3M0dlV0YkxOU1luQXVoVTRSZVh3d0RWOVh1ME1YQWpmUU1rMkUzd1FMR1ErODJ1djJCXFxuMWhQRDluREhUdEFkV3JYZDZaalhGckc0TWYyTVFCeHlTRnZWU25GaTZ5U3RqZlplaUtjRDVWZzM4UGpHXFxuV2cxTzVOMy9wYXE5OEhmSDBRNHFOS0dabGp3bzNvRVFaemxZbTJrVm5JMFBVTG9NWWc9PVxcbj1vdkF4XFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgICAgICAgIGk6IDMsXG4gICAgICAgICAgICAgIGo6IDEsXG4gICAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzcTlSTUZLNEVFQUFvQ0F3UmdEcGdtMWJwdFJUNXlMT01hZGNHQUh1dmt4SVNMOC8zeFB5L0RcXG5ZQSsxTmdCcUlGSy8zT09YeHA3M1R2ODZidDFkZ0g3T0QxQUNPMG1WWEFvWDVFYVZ6V1p2ZG1NdE1TMTFcXG5jMlZ5TFdSbU1qUXdPV1kwTldOaE1UWm1OVFUzT0dOa016QXhNeUE4YjNaakxURXRkWE5sY2kxa1pqSTBcXG5NRGxtTkRWallURTJaalUxTnpoalpETXdNVE5BWkdZeU5EQTVaalExWTJFeE5tWTFOVGM0WTJRek1ERXpcXG5MbU52YlQ3Q2pBUVFFd2dBSFFVQ1pCc3E5UVFMQ1FjSUF4VUlDZ1FXQUFJQkFoa0JBaHNEQWg0QkFDRUpcXG5FT1VlQzdRckdMKzJGaUVFak42dlBVRlJ3ZVZ0REtGWjVSNEx0Q3NZdjdaN29BRUF2TkthSnJUSXMza3lcXG5ieGprVWljc3V4T3lBMm9XR2FySkg2VEdsV0Y2V0Q4QS8zRUllWnpQS1NMYVcrM2VucGJDUGlVOFJWRHBcXG5DNnlvNk5NQXFLcDRYbHlRemxNRVpCc3E5UklGSzRFRUFBb0NBd1FXbFdQTk1wazNhZkV6ZmdHMHhGZzRcXG5DRWpZN2ZHTzM1bjQ3blo0cXhqRVh6MlhONEkyM3hGTWl3WmJYYnB0RFhscW03VzlaQUhLaTg5MmgrWXRcXG5VNEI2QXdFSUI4SjRCQmdUQ0FBSkJRSmtHeXIxQWhzTUFDRUpFT1VlQzdRckdMKzJGaUVFak42dlBVRlJcXG53ZVZ0REtGWjVSNEx0Q3NZdjdZcVp3RDhETFJ1bmVCMEhFekJDeXJFNFlMK1VIYW9mb0hRWDErblJoMGpcXG44MnFhRHpBQS9pM1UxU29FSWkzMllNcm9yTkc1MHZiNHZhRVBiYlltZmdsYitKUTFZeDdvempNRVpCc3FcXG45UllKS3dZQkJBSGFSdzhCQVFkQVMxNTM0TGRDQzYwQVNwRWduRUJDOHBXUFNPV1dCTFh5V2FCaEVPVzJcXG4vaWpDZUFRWUV3Z0FDUVVDWkJzcTlRSWJJQUFoQ1JEbEhndTBLeGkvdGhZaEJJemVyejFCVWNIbGJReWhcXG5XZVVlQzdRckdMKzJGVVlBL0FnTVU0VjdDN0kvNUh3SzczbWN0YUdYTmRmVnIvbXVSTU5PR1cvQ0F4VkxcXG5BUDlLYUJyOTVvMzJvRU41ZW83dFdGQnlvT0NDazlKTWpzMzZDcTdvK3NSMzFBPT1cXG49ZVozQlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIDI6IHtcbiAgICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMnc9PVxcbj1FdHR1XFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICBvdmNUb0JpdGdvU2hhcmU6IHtcbiAgICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICAgJ2VjZjk1ZTliYTZmMDJjMGJjNGMyYWIyNTQ1NjVkMjFhMTU2MjA1OWM4YTFhYjcwZDI4NmZhMDRhZTJjNTExZTA0OTE0MTBiNmQ2ZmE4YWIyMmU2OTFiZWQ3OTM4YTdhZGFhYmZhOGQ5ZDU5YWFiOWNjMmMwNzhjZDM3ZGRlMDFiJyxcbiAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWUxbllOdjlEbkhsOEhYOGpOczNyZUdzNW5QVDJiTnpHTUNGTDBOM1BcXG5LTHdHZDhEQmtESklNcG9DbGFBUy9IVFVUUFRSemo0VTFHU2hWNzlJK2JiZlREQlY2dWh5Zlo3YTg4ZFZcXG5SRFRYbDZyY2hGbC9mbXdMb1hucUgrQkRQRVh5dHBBdkt3RHJBZzU1VC9IN2FvcDVRYmZTc1FFckV2N1hcXG5UcFRMSEhIZmxFRVFMNjJwMVJubnEya0t2d0pLN1RZMWc1UnRQZ1lYSDZHRXMzM0RMdWxQZVVzOFVrS3FcXG5UUExmMisxS0NMWXl6TXdtU2k4S0VDOEhKYjB2QWtYWkFsWjErRG9aMlBmaUlKY1ZuejdhM29tamlQNzdcXG5obUM4cGhUY0o3MThVeElCMDlmOHVpYzAvZk03Rk51MEpIRmdSREE2OXp6ZUZZblpjMlhOUWc1aHMvZFpcXG5aOEFpdFA0cm5hQWZwcnNxNHJBRUUvYzNUcm05dHpRSFpQQ3FyLzJzNExsdXlVTVZKdz09XFxuPUlKWkhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgICAgdnNzUHJvb2Y6ICczMDlkMmZlZjIyNzJhZDMxMzc1OTU0Yjk5YTg2Mjc0MmYyMmQ4MDIzZWVmOTg1NWI4YWUyNmVhODRlMDhiZjVlJyxcbiAgICAgICAgICAgICAgaTogMyxcbiAgICAgICAgICAgICAgajogMixcbiAgICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMjg0elxcbkJHUWJLelFXQ1NzR0FRUUIya2NQQVFFSFFJVlRtbHQ4YS9makpDWTlVeVA4SjUxZVRQWDlQTVJGMy9IclxcbkJZd3RmT1pZd25nRUdCTUlBQWtGQW1RYkt6UUNHeUFBSVFrUXRnSk9SdGtwTzJVV0lRUzA2VXBCVG50Mlxcbm8yNnFMbnEyQWs1RzJTazdaY3RoQVFENGVrM2FxVURFYmhmUkhvbG00akZoSVBJYmI5aFVKd3VCUjBSNFxcbitndmFlQUVBazh1azVjRUFDZXFtcGRFRjUyb0d4N2ptR0NvWDczQUlJTFlWY2Y5aU1rST1cXG49OTJIZlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG92Y1RvT3ZjU2hhcmU6IHtcbiAgICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICAgJ2VjZjk1ZTliYTZmMDJjMGJjNGMyYWIyNTQ1NjVkMjFhMTU2MjA1OWM4YTFhYjcwZDI4NmZhMDRhZTJjNTExZTA0OTE0MTBiNmQ2ZmE4YWIyMmU2OTFiZWQ3OTM4YTdhZGFhYmZhOGQ5ZDU5YWFiOWNjMmMwNzhjZDM3ZGRlMDFiJyxcbiAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREK0Yzdkk5NjJ6Vk1TQWdNRU55Mlg5eERJT20xZ3dPZk1kTC8xdlpqZU1XL2lsZS9mMmRSSVAyR1ZcXG52NHc2MEs5MittSEk5eW9vVTFWVDc3alpyVk9jTks0MURGTkNGL2Z1b1VVK1Z6Qk9OMEkxaEh5WG0yUUpcXG53TCtuTmR2QVh3UnY3blNGRDNBQlVtUllkRzcxQUZJV2pXMkwrMUMyaHhwc05sbWR4ZmZTc1FISFQ5dVBcXG5CTnBGWWdRTjc3T1V4Y2dyd2VTVnJQeWVyMXJDUThvK1Fub0syL2hJeDlQbEpaa2NsM3V3RjZUcEJ0anNcXG5xdlJ4VGhvbW9IeW8waEpIRzB2bUk0MkdxNXUwdGNTZVU5MDJlZnBDRGFlSmhQVk9pcUlTb0o5NnduMHJcXG5GQjNsWUxTZmxPcENMQUU3bnNaSlJvWEE2YWtVN3hNQ01OQSsrZDR0djZwOThGUStNWjZlOXg2a2lTdzFcXG5NK1ZXaitQdk4xZHRROGZOWXdwSmY3S0JmRDF3NklTTUZEbWV3a0RFN2lCT1hGNkZMdz09XFxuPSszWWNcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgICAgdnNzUHJvb2Y6ICczMDlkMmZlZjIyNzJhZDMxMzc1OTU0Yjk5YTg2Mjc0MmYyMmQ4MDIzZWVmOTg1NWI4YWUyNmVhODRlMDhiZjVlJyxcbiAgICAgICAgICAgICAgaTogMSxcbiAgICAgICAgICAgICAgajogMixcbiAgICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNyTkJNRks0RUVBQW9DQXdUMnhYdi9tRy9kYVBkS0dEL2ZISVVFRTJadGNLK25qdENadE1FclxcbmtJdWJtVXdlM0RqOCtoUXh0M1NLYVR4UWJ1RCtXYUxTajk4NlFZVXI0Wnc0VCtXM3pXcHZkbU10TWkxaVxcbllXTnJkWEF0TlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRJRHh2ZG1NdE1pMWlZV05yZFhBdFxcbk5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0UURVME4ySmlaR1l6TURoak1XVTJNV05rT1dSaVxcbk9EWmxPQzVqYjIwK3dvd0VFQk1JQUIwRkFtUWJLelFFQ3drSENBTVZDQW9FRmdBQ0FRSVpBUUliQXdJZVxcbkFRQWhDUkMyQWs1RzJTazdaUlloQkxUcFNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bHh0WUJBTExJQm5BYVxcbjRBUzc3WHZYbW16bk5DV08vSE51RFBEMnVnUnFWaHFVNFN4bUFRRG1hMTRBUHVNTlNWeWkxN3hvbVpqV1xcbjBuaW10YU1JQmpjMEE0TVhFNkc0WGM1VEJHUWJLelFTQlN1QkJBQUtBZ01FVUhvUURZOTh5OENBVm91dVxcbnk0eTNRMlFuQnBuVUJLLzBQRUxWN1ZBTlhkOWxZN0NTaHlvZ0pTY2dQbGlVbTk3QXU5RkMxN3ZxWmExQlxcbjViQk1KQWRYVndNQkNBZkNlQVFZRXdnQUNRVUNaQnNyTkFJYkRBQWhDUkMyQWs1RzJTazdaUlloQkxUcFxcblNrRk9lM2FqYnFvdWVyWUNUa2JaS1R0bFI1d0EvM3pPRlRTZVhYUlJlbVhsM2hZMTBzcHhhYkU0TzJKOFxcblpEMlZSZmpiRHBaakFRRFdnMVcralBiTTJIdGlrZDFOMDFWK3p3ZU5EaEpFSDY1cjBRcjhCbFhoMjg0elxcbkJHUWJLelFXQ1NzR0FRUUIya2NQQVFFSFFOVkdnMHZQc2ZLMXlKakZ1RFlCOFRqN0NRUkhLR0FWRURjalxcbmgvUUlxcjBLd25nRUdCTUlBQWtGQW1RYkt6UUNHeUFBSVFrUXRnSk9SdGtwTzJVV0lRUzA2VXBCVG50Mlxcbm8yNnFMbnEyQWs1RzJTazdaUzlvQVFDZTJ6SkQ1SXRXMkdFZ0FpdG5ZK05yTEJqYlhJNitMWTI5R2pSYVxcbmY2eUZUUUQvY1AwRTFEbGVxWE1qZ2ZSK2V3dDZxdVZGTVplYmhyM3RCci9IMFp2LzlFQT1cXG49OGFpK1xcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYml0Z29cbiAgICAgICAgLmNvaW4oJ3Rzb2wnKVxuICAgICAgICAua2V5Y2hhaW5zKClcbiAgICAgICAgLmNyZWF0ZVRzc0JpdEdvS2V5RnJvbU92Y1NoYXJlcyhvdmNPdXRwdXRKc29uKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnU3RhdGUgZXhwZWN0ZWQgdG8gYmUgXCIxXCIuIFBsZWFzZSBjb21wbGV0ZSB0aGUgZmlyc3QgdHdvIE9WQyBvcGVyYXRpb25zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnRmFpbHMgdG8gZGVjb2RlIGlmIHRoZSBPVkMganNvbiBpcyBtaXNzaW5nIGZpZWxkcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG92Y091dHB1dEpzb24gPSB7XG4gICAgICAgIHRzc1ZlcnNpb246ICcwLjAuMScsXG4gICAgICAgIHN0YXRlOiAxLFxuICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgIG92Yzoge1xuICAgICAgICAgIDE6IHtcbiAgICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N29cXG49dmpnbFxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgb3ZjVG9CaXRnb1NoYXJlOiB7XG4gICAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVkL3dRL0Fod0lSc1NmLzZpSHdtSEt2RVlBd2ZhTHRUUW90UzZCd1ptXFxuYVgwMFQ3THVtR0lyTlp6QmdjZ2dCS01sKzhPbW9tOG1YNXNQOEZVRTQ1MWlaakJtWGxrcEhscEFxc2tTXFxuRWk1U2ZqbHNUMzF1dG9MYUJMQTdOak5TbXlZSElpeWZoNllud2ZWNVU3Mms2aGhmcHVEU3NRR3k4WXhwXFxuTTJkVmxONHVvTzMxemdRUGYrZmdKa1p2QVB3dmpZTEJMNE84aHMyMUhHZjBWdkc5OWJyazR4bEZWUmh3XFxuUW51UHBNNTFHT3M0dlV0YkxOU1luQXVoVTRSZVh3d0RWOVh1ME1YQWpmUU1rMkUzd1FMR1ErODJ1djJCXFxuMWhQRDluREhUdEFkV3JYZDZaalhGckc0TWYyTVFCeHlTRnZWU25GaTZ5U3RqZlplaUtjRDVWZzM4UGpHXFxuV2cxTzVOMy9wYXE5OEhmSDBRNHFOS0dabGp3bzNvRVFaemxZbTJrVm5JMFBVTG9NWWc9PVxcbj1vdkF4XFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgICAgICAgIGk6IDMsXG4gICAgICAgICAgICAgIGo6IDEsXG4gICAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzcTlSTUZLNEVFQUFvQ0F3UmdEcGdtMWJwdFJUNXlMT01hZGNHQUh1dmt4SVNMOC8zeFB5L0RcXG5ZQSsxTmdCcUlGSy8zT09YeHA3M1R2ODZidDFkZ0g3T0QxQUNPMG1WWEFvWDVFYVZ6V1p2ZG1NdE1TMTFcXG5jMlZ5TFdSbU1qUXdPV1kwTldOaE1UWm1OVFUzT0dOa016QXhNeUE4YjNaakxURXRkWE5sY2kxa1pqSTBcXG5NRGxtTkRWallURTJaalUxTnpoalpETXdNVE5BWkdZeU5EQTVaalExWTJFeE5tWTFOVGM0WTJRek1ERXpcXG5MbU52YlQ3Q2pBUVFFd2dBSFFVQ1pCc3E5UVFMQ1FjSUF4VUlDZ1FXQUFJQkFoa0JBaHNEQWg0QkFDRUpcXG5FT1VlQzdRckdMKzJGaUVFak42dlBVRlJ3ZVZ0REtGWjVSNEx0Q3NZdjdaN29BRUF2TkthSnJUSXMza3lcXG5ieGprVWljc3V4T3lBMm9XR2FySkg2VEdsV0Y2V0Q4QS8zRUllWnpQS1NMYVcrM2VucGJDUGlVOFJWRHBcXG5DNnlvNk5NQXFLcDRYbHlRemxNRVpCc3E5UklGSzRFRUFBb0NBd1FXbFdQTk1wazNhZkV6ZmdHMHhGZzRcXG5DRWpZN2ZHTzM1bjQ3blo0cXhqRVh6MlhONEkyM3hGTWl3WmJYYnB0RFhscW03VzlaQUhLaTg5MmgrWXRcXG5VNEI2QXdFSUI4SjRCQmdUQ0FBSkJRSmtHeXIxQWhzTUFDRUpFT1VlQzdRckdMKzJGaUVFak42dlBVRlJcXG53ZVZ0REtGWjVSNEx0Q3NZdjdZcVp3RDhETFJ1bmVCMEhFekJDeXJFNFlMK1VIYW9mb0hRWDErblJoMGpcXG44MnFhRHpBQS9pM1UxU29FSWkzMllNcm9yTkc1MHZiNHZhRVBiYlltZmdsYitKUTFZeDdvempNRVpCc3FcXG45UllKS3dZQkJBSGFSdzhCQVFkQVMxNTM0TGRDQzYwQVNwRWduRUJDOHBXUFNPV1dCTFh5V2FCaEVPVzJcXG4vaWpDZUFRWUV3Z0FDUVVDWkJzcTlRSWJJQUFoQ1JEbEhndTBLeGkvdGhZaEJJemVyejFCVWNIbGJReWhcXG5XZVVlQzdRckdMKzJGVVlBL0FnTVU0VjdDN0kvNUh3SzczbWN0YUdYTmRmVnIvbXVSTU5PR1cvQ0F4VkxcXG5BUDlLYUJyOTVvMzJvRU41ZW83dFdGQnlvT0NDazlKTWpzMzZDcTdvK3NSMzFBPT1cXG49ZVozQlxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IGJpdGdvLmNvaW4oJ3Rzb2wnKS5rZXljaGFpbnMoKS5jcmVhdGVUc3NCaXRHb0tleUZyb21PdmNTaGFyZXMob3ZjT3V0cHV0SnNvbikuc2hvdWxkLmJlLnJlamVjdGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnT3ZjU2hhcmUgY29kZWMgZGVjb2RlcyBjb3JyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0ID0ge1xuICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAnMDdiZmJiMDUyYTFmNGIxMDZiMzE1YmQ1YTlkNmE3MTYwNDY1MzI4OWY4NjEzMjBkOTgwMTg4MWU5NTJmODU1MDc1M2M4OTUxMWEzNjBlM2I1OTlkOWYyMzlhOGQzNmE0OTU2NDM3ZWQwYjE1MjE4MGUyMmNiOTRmYjA4ZmRjODEnLFxuICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNERVUThYaEdWR2NUSVNBZ01FZC93US9BaHdJUnNTZi82aUh3bUhLdkVZQXdmYUx0VFFvdFM2QndabVxcbmFYMDBUN0x1bUdJck5aekJnY2dnQktNbCs4T21vbThtWDVzUDhGVUU0NTFpWmpCbVhsa3BIbHBBcXNrU1xcbkVpNVNmamxzVDMxdXRvTGFCTEE3TmpOU215WUhJaXlmaDZZbndmVjVVNzJrNmhoZnB1RFNzUUd5OFl4cFxcbk0yZFZsTjR1b08zMXpnUVBmK2ZnSmtadkFQd3ZqWUxCTDRPOGhzMjFIR2YwVnZHOTlicms0eGxGVlJod1xcblFudVBwTTUxR09zNHZVdGJMTlNZbkF1aFU0UmVYd3dEVjlYdTBNWEFqZlFNazJFM3dRTEdRKzgydXYyQlxcbjFoUEQ5bkRIVHRBZFdyWGQ2WmpYRnJHNE1mMk1RQnh5U0Z2VlNuRmk2eVN0amZaZWlLY0Q1VmczOFBqR1xcbldnMU81TjMvcGFxOThIZkgwUTRxTktHWmxqd28zb0VRWnpsWW0ya1ZuSTBQVUxvTVlnPT1cXG49b3ZBeFxcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICB2c3NQcm9vZjogJ2JlODE5OGMyY2VmOTRjYjM4MWFhOGFhOTI3N2EwYTQ2YmE1YTU0YjBhYzk5MzAwMzRiNGFmNjZiMWI4MDUyMzQnLFxuICAgICAgICBpOiAzLFxuICAgICAgICBqOiAxLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGRlY29kZWRSZXMgPSBkZWNvZGVPckVsc2UoT3ZjU2hhcmUubmFtZSwgT3ZjU2hhcmUsIHRlc3QsIChlcnJvcnMpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBlcnJvcihzKSBwYXJzaW5nIHBhcnNpbmcganNvbjogJHtlcnJvcnN9YCk7XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5vayhkZWNvZGVkUmVzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBiYWNrdXAgd2l0aG91dCBlbmNyeXB0ZWRQcnYgd2hlbiBwYXNzcGhyYXNlIG5vdCBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIChib2R5KSA9PiB7XG4gICAgICAgIHJldHVybiBib2R5LmVuY3J5cHRlZFBydiA9PT0gdW5kZWZpbmVkICYmIGJvZHkucHJ2ID09PSB1bmRlZmluZWQ7XG4gICAgICB9KVxuICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICBjb25zdCBiYWNrdXAgPSBhd2FpdCBrZXljaGFpbnMuY3JlYXRlQmFja3VwKHt9KTtcbiAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIGJhY2t1cC5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgIGJhY2t1cC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJ2Jyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZ2VuZXJhdGUgYmFja3VwIGFuZCBjYWxsIGVuZHBvaW50IHdpdGggZW5jcnlwdGVkUHJ2IHdoZW4gcGFzc3BocmFzZSBpcyBwcm92aWRlZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIChib2R5KSA9PiB7XG4gICAgICAgIHJldHVybiBib2R5LmVuY3J5cHRlZFBydiAhPT0gdW5kZWZpbmVkICYmIGJvZHkucHJ2ID09PSB1bmRlZmluZWQ7XG4gICAgICB9KVxuICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICBjb25zdCBiYWNrdXAgPSBhd2FpdCBrZXljaGFpbnMuY3JlYXRlQmFja3VwKHsgcGFzc3BocmFzZTogJ3Qzc3RTaWNyZXRseSEnIH0pO1xuICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgYmFja3VwLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRQcnYnKTtcbiAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IGJhY2t1cC5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiAndDNzdFNpY3JldGx5IScgfSk7XG4gICAgZGVjcnlwdGVkUHJ2LnNob3VsZC5zdGFydFdpdGgoJ3hwcnYnKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JvdGF0ZSBPRkMgbXVsdGktdXNlci1rZXkga2V5Y2hhaW5zJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBvZmNCYXNlQ29pbjtcbiAgICBsZXQgb2ZjS2V5Y2hhaW5zO1xuICAgIGNvbnN0IG1vY2tPZmNLZXljaGFpbjogS2V5Y2hhaW4gPSB7XG4gICAgICBpZDogJ29mY0tleWNoYWluSWQnLFxuICAgICAgcHViOiAnb2ZjS2V5Y2hhaW5QdWInLFxuICAgICAgZW5jcnlwdGVkUHJ2OiAnb2ZjRW5jcnlwdGVkUHJ2JyxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgIG9mYzoge1xuICAgICAgICAgIGZlYXR1cmVzOiBbJ211bHRpLXVzZXIta2V5J10sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdHlwZTogJ3RzcycsXG4gICAgfTtcbiAgICBsZXQgbm9uT2ZjQmFzZUNvaW47XG4gICAgbGV0IG5vbk9mY0tleWNoYWlucztcbiAgICBjb25zdCBtb2NrTm9uT2ZjS2V5Y2hhaW46IEtleWNoYWluID0ge1xuICAgICAgaWQ6ICdub25PZmNLZXljaGFpbklkJyxcbiAgICAgIHB1YjogJ25vbk9mY0tleWNoYWluUHViJyxcbiAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgdHlwZTogJ3RzcycsXG4gICAgfTtcblxuICAgIGNvbnN0IG1vY2tOZXdLZXlwYWlyID0ge1xuICAgICAgcHViOiAnbmV3UHViJyxcbiAgICAgIHBydjogJ25ld1BydicsXG4gICAgfTtcblxuICAgIGxldCBzYW5kYm94O1xuICAgIGxldCB1cGRhdGVLZXljaGFpblN0dWI6IFNpbm9uU3R1YjtcbiAgICBsZXQgY3JlYXRlS2V5cGFpclN0dWI6IFNpbm9uU3R1YjtcbiAgICBsZXQgZW5jcnlwdGlvblN0dWI6IFNpbm9uU3R1YjtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgb2ZjQmFzZUNvaW4gPSBiaXRnby5jb2luKCdvZmMnKTtcbiAgICAgIG9mY0tleWNoYWlucyA9IG9mY0Jhc2VDb2luLmtleWNoYWlucygpO1xuXG4gICAgICBub25PZmNCYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBub25PZmNLZXljaGFpbnMgPSBub25PZmNCYXNlQ29pbi5rZXljaGFpbnMoKTtcblxuICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICAgIHVwZGF0ZUtleWNoYWluU3R1YiA9IHNhbmRib3guc3R1YigpLnJldHVybnMoeyByZXN1bHQ6IHNhbmRib3guc3R1YigpLnJlc29sdmVzKCkgfSk7XG4gICAgICBzYW5kYm94LnN0dWIoQml0R28ucHJvdG90eXBlLCAncHV0JykucmV0dXJucyh7IHNlbmQ6IHVwZGF0ZUtleWNoYWluU3R1YiB9KTtcbiAgICAgIGNyZWF0ZUtleXBhaXJTdHViID0gc2FuZGJveC5zdHViKG9mY0tleWNoYWlucywgJ2NyZWF0ZScpLnJldHVybnMobW9ja05ld0tleXBhaXIpO1xuICAgICAgZW5jcnlwdGlvblN0dWIgPSBzYW5kYm94LnN0dWIoQml0R28ucHJvdG90eXBlLCAnZW5jcnlwdCcpLnJlc29sdmVzKCduZXdFbmNyeXB0ZWRQcnYnKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcm90YXRlIG9mYyBtdWx0aS11c2VyLWtleSBwcm9wZXJseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9vZmMva2V5LyR7bW9ja09mY0tleWNoYWluLmlkfWApLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgbW9ja09mY0tleWNoYWluKTtcblxuICAgICAgYXdhaXQgb2ZjS2V5Y2hhaW5zLnJvdGF0ZUtleWNoYWluKHsgaWQ6IG1vY2tPZmNLZXljaGFpbi5pZCwgcGFzc3dvcmQ6ICcxMjM0JyB9KTtcbiAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWQoY3JlYXRlS2V5cGFpclN0dWIpO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgoZW5jcnlwdGlvblN0dWIsIHsgaW5wdXQ6IG1vY2tOZXdLZXlwYWlyLnBydiwgcGFzc3dvcmQ6ICcxMjM0JywgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aCh1cGRhdGVLZXljaGFpblN0dWIsIHtcbiAgICAgICAgcHViOiBtb2NrTmV3S2V5cGFpci5wdWIsXG4gICAgICAgIGVuY3J5cHRlZFBydjogJ25ld0VuY3J5cHRlZFBydicsXG4gICAgICAgIHJlcUlkOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWxsb3cgdXNlciB0byBzdXBwbHkgcHViIGFuZCBlbmNyeXB0ZWRQcnYgZGlyZWN0bHknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvb2ZjL2tleS8ke21vY2tPZmNLZXljaGFpbi5pZH1gKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIG1vY2tPZmNLZXljaGFpbik7XG5cbiAgICAgIGF3YWl0IG9mY0tleWNoYWlucy5yb3RhdGVLZXljaGFpbih7IGlkOiBtb2NrT2ZjS2V5Y2hhaW4uaWQsIHB1YjogJ3B1YicsIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicgfSk7XG4gICAgICBzaW5vbi5hc3NlcnQubm90Q2FsbGVkKGNyZWF0ZUtleXBhaXJTdHViKTtcbiAgICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQoZW5jcnlwdGlvblN0dWIpO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZFdpdGgodXBkYXRlS2V5Y2hhaW5TdHViLCB7XG4gICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgIHJlcUlkOiB1bmRlZmluZWQsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgd2hlbiB0cnlpbmcgdG8gcm90YXRlIG5vbi1vZmMga2V5Y2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LyR7bW9ja05vbk9mY0tleWNoYWluLmlkfWApLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgbW9ja05vbk9mY0tleWNoYWluKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IG5vbk9mY0tleWNoYWlucy5yb3RhdGVLZXljaGFpbih7IGlkOiBtb2NrTm9uT2ZjS2V5Y2hhaW4uaWQsIHBhc3N3b3JkOiAnMTIzNCcgfSksXG4gICAgICAgIChlcnI6IEVycm9yKSA9PiBlcnIubWVzc2FnZSA9PT0gJ3JvdGF0ZUtleWNoYWluIGlzIG9ubHkgcGVybWl0dGVkIGZvciBvZmMgbXVsdGktdXNlci1rZXkgd2FsbGV0J1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldEVuY3J5cHRpb25WZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyZXR1cm5zIDEgd2hlbiB0aGUgdiBmaWVsZCBpcyBhYnNlbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04uc3RyaW5naWZ5KHsgY3Q6ICdjaXBoZXInLCBpdjogJ2l2JywgczogJ3NhbHQnIH0pO1xuICAgICAga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKGVudmVsb3BlKS5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgncmV0dXJucyAxIHdoZW4gdiBpcyBleHBsaWNpdGx5IDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oSlNPTi5zdHJpbmdpZnkoeyB2OiAxLCBjdDogJ2FiYycgfSkpLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIDIgd2hlbiB2IGlzIDInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBjdDogJ2FiYycgfSkpLnNob3VsZC5lcXVhbCgyKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgb24gYW4gdW5yZWNvZ25pemVkIHZlcnNpb24gbnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKEpTT04uc3RyaW5naWZ5KHsgdjogMywgY3Q6ICdhYmMnIH0pKSxcbiAgICAgICAgL1VucmVjb2duaXplZCBlbmNyeXB0aW9uIHZlcnNpb246IDMvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHRoZSBpbnB1dCBpcyBub3QgdmFsaWQgSlNPTicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4ga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKCdub3QtanNvbicpLCAvRmFpbGVkIHRvIHBhcnNlIGNpcGhlcnRleHQgZW52ZWxvcGUvKTtcbiAgICB9KTtcblxuICAgIGl0KCd0aHJvd3Mgd2hlbiB0aGUgaW5wdXQgaXMgYW4gZW1wdHkgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oJycpLCAvRmFpbGVkIHRvIHBhcnNlIGNpcGhlcnRleHQgZW52ZWxvcGUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdoYW5kbGVzIGEgcmVhbCBTSkNMIHYxIGVudmVsb3BlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2pjbCA9IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgaXY6ICdhYWFhJyxcbiAgICAgICAgdjogMSxcbiAgICAgICAgaXRlcjogMTAwMDAsXG4gICAgICAgIGtzOiAyNTYsXG4gICAgICAgIHRzOiA2NCxcbiAgICAgICAgbW9kZTogJ2NjbScsXG4gICAgICAgIGFkYXRhOiAnJyxcbiAgICAgICAgY2lwaGVyOiAnYWVzJyxcbiAgICAgICAgc2FsdDogJ3Nzc3MnLFxuICAgICAgICBjdDogJ2NjY2MnLFxuICAgICAgfSk7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oc2pjbCkuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hhbmRsZXMgYSByZWFsIEFyZ29uMmlkIHYyIGVudmVsb3BlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYXJnb24yID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICB2OiAyLFxuICAgICAgICBjdDogJ2NjY2MnLFxuICAgICAgICBpdjogJ2lpaWknLFxuICAgICAgICB0YWc6ICd0dHR0JyxcbiAgICAgICAgc2FsdDogJ3Nzc3MnLFxuICAgICAgICBtOiA2NTUzNixcbiAgICAgICAgdDogMyxcbiAgICAgICAgcDogNCxcbiAgICAgIH0pO1xuICAgICAga2V5Y2hhaW5zLmdldEVuY3J5cHRpb25WZXJzaW9uKGFyZ29uMikuc2hvdWxkLmVxdWFsKDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVlbmNyeXB0QXNWMicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnZGVjcnlwdHMgYSB2MSBlbnZlbG9wZSB3aXRoIHRoZSBwYXNzcGhyYXNlIGFuZCByZS1lbmNyeXB0cyBhcyB2MicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBydiA9ICd0aGVQcml2YXRlS2V5JztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiAnbXlQYXNzJywgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG4gICAgICBKU09OLnBhcnNlKGVuY3J5cHRlZFYxKS52LnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2V5Y2hhaW5zLnJlZW5jcnlwdEFzVjIoZW5jcnlwdGVkVjEsICdteVBhc3MnKTtcbiAgICAgIEpTT04ucGFyc2UocmVzdWx0KS52LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIChhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3VsdCwgcGFzc3dvcmQ6ICdteVBhc3MnIH0pKS5zaG91bGQuZXF1YWwocHJ2KTtcbiAgICB9KTtcblxuICAgIGl0KCdhY2NlcHRzIGEgdjIgZW52ZWxvcGUgYW5kIHJlLWVuY3J5cHRzIGl0IGFzIHYyIChpZGVtcG90ZW50KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBydiA9ICd4cHJ2LXYyJztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiAncGFzcycsIGVuY3J5cHRpb25WZXJzaW9uOiAyIH0pO1xuICAgICAgSlNPTi5wYXJzZShlbmNyeXB0ZWRWMikudi5zaG91bGQuZXF1YWwoMik7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGtleWNoYWlucy5yZWVuY3J5cHRBc1YyKGVuY3J5cHRlZFYyLCAncGFzcycpO1xuICAgICAgSlNPTi5wYXJzZShyZXN1bHQpLnYuc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgKGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzdWx0LCBwYXNzd29yZDogJ3Bhc3MnIH0pKS5zaG91bGQuZXF1YWwocHJ2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzdXJmYWNlcyBkZWNyeXB0IGVycm9ycyBkaXJlY3RseSAobm8gZmFsbGJhY2sgbG9naWMgaW4gdGhlIHByaW1pdGl2ZSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbmNyeXB0ZWQgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICdwcnYnLCBwYXNzd29yZDogJ3JlYWxQYXNzJywgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG4gICAgICBhd2FpdCBrZXljaGFpbnMucmVlbmNyeXB0QXNWMihlbmNyeXB0ZWQsICd3cm9uZ1Bhc3MnKS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==