PHP WebShell
Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/v2/unit/tss
Просмотр файла: eddsa.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_core_1 = require("@bitgo/sdk-core");
const openpgp = require("openpgp");
const should = require("should");
const _ = require("lodash");
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("../../../../src/bitgo");
const helpers_1 = require("./helpers");
const sinon = require("sinon");
const nock = require("nock");
describe('test tss helper functions', function () {
let mpc;
let userKeyShare;
let backupKeyShare;
let bitgoKeyShare;
let userKey;
let backupKey;
let bitgoKey;
let userGpgKeypair;
let backupGpgKeypair;
let bitgoGpgKeypair;
let commonKeychain;
before(async function () {
const hdTree = await sdk_core_1.Ed25519BIP32.initialize();
mpc = await sdk_core_1.Eddsa.initialize(hdTree);
userKeyShare = mpc.keyShare(1, 2, 3);
backupKeyShare = mpc.keyShare(2, 2, 3);
bitgoKeyShare = mpc.keyShare(3, 2, 3);
userKey = mpc.keyCombine(userKeyShare.uShare, [backupKeyShare.yShares[1], bitgoKeyShare.yShares[1]]);
backupKey = mpc.keyCombine(backupKeyShare.uShare, [userKeyShare.yShares[2], bitgoKeyShare.yShares[2]]);
bitgoKey = mpc.keyCombine(bitgoKeyShare.uShare, [backupKeyShare.yShares[3], userKeyShare.yShares[3]]);
(userKey.pShare.y + userKey.pShare.chaincode).should.equal(backupKey.pShare.y + backupKey.pShare.chaincode);
(userKey.pShare.y + userKey.pShare.chaincode).should.equal(bitgoKey.pShare.y + bitgoKey.pShare.chaincode);
commonKeychain = userKey.pShare.y + userKey.pShare.chaincode;
userGpgKeypair = await openpgp.generateKey({
userIDs: [
{
name: 'user',
email: 'user@bitgo.com',
},
],
});
backupGpgKeypair = await openpgp.generateKey({
userIDs: [
{
name: 'backup',
email: 'backup@bitgo.com',
},
],
});
bitgoGpgKeypair = await openpgp.generateKey({
userIDs: [
{
name: 'bitgo',
email: 'bitgo@bitgo.com',
},
],
});
});
after(function () {
nock.cleanAll();
});
describe('encryptYShare', function () {
it('should encrypt y share', async function () {
for (let i = 2; i <= 3; i++) {
const encryptedYShare = await (0, sdk_core_1.encryptYShare)({
keyShare: userKeyShare,
recipientIndex: i,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
});
const decryptedMessage = await (0, sdk_core_1.readSignedMessage)(encryptedYShare.encryptedPrivateShare, userGpgKeypair.publicKey, bitgoGpgKeypair.privateKey);
decryptedMessage.should.equal(userKeyShare.yShares[i].u + userKeyShare.yShares[i].chaincode);
encryptedYShare.i.should.equal(i);
encryptedYShare.j.should.equal(1);
encryptedYShare.publicShare.should.equal(userKeyShare.uShare.y + userKeyShare.yShares[3].v + userKeyShare.uShare.chaincode);
}
});
it('should error for invalid recipient index', async function () {
await (0, sdk_core_1.encryptYShare)({
keyShare: userKeyShare,
recipientIndex: 1,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
}).should.be.rejectedWith('Invalid recipient');
await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 2,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
}).should.be.rejectedWith('Invalid recipient');
await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 3,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
}).should.be.rejectedWith('Invalid recipient');
});
});
describe('createCombinedKey', function () {
it('should create combined user key', async function () {
const bitgoToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const backupToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: backupGpgKeypair.privateKey,
});
const combinedUserKey = await (0, sdk_core_1.createCombinedKey)({
keyShare: userKeyShare,
commonKeychain,
encryptedYShares: [
{
yShare: bitgoToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
});
combinedUserKey.commonKeychain.should.equal(commonKeychain);
combinedUserKey.signingMaterial.uShare.should.deepEqual(userKeyShare.uShare);
combinedUserKey.signingMaterial.backupYShare.should.deepEqual(backupKeyShare.yShares[1]);
combinedUserKey.signingMaterial.bitgoYShare.should.deepEqual(bitgoKeyShare.yShares[1]);
should.not.exist(combinedUserKey.signingMaterial.userYShare);
});
it('should create combined backup key', async function () {
const bitgoToBackupShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 2,
recipientGpgPublicArmor: backupGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const userToBackupShare = await (0, sdk_core_1.encryptYShare)({
keyShare: userKeyShare,
recipientIndex: 2,
recipientGpgPublicArmor: backupGpgKeypair.publicKey,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
});
const combinedBackupKey = await (0, sdk_core_1.createCombinedKey)({
keyShare: backupKeyShare,
commonKeychain,
encryptedYShares: [
{
yShare: bitgoToBackupShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: userToBackupShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: userGpgKeypair.publicKey,
},
],
});
combinedBackupKey.commonKeychain.should.equal(commonKeychain);
combinedBackupKey.signingMaterial.uShare.should.deepEqual(backupKeyShare.uShare);
combinedBackupKey.signingMaterial.userYShare.should.deepEqual(userKeyShare.yShares[2]);
combinedBackupKey.signingMaterial.bitgoYShare.should.deepEqual(bitgoKeyShare.yShares[2]);
should.not.exist(combinedBackupKey.signingMaterial.backupYShare);
});
it('should fail if common keychains do not match', async function () {
const bitgoToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const backupToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: backupGpgKeypair.privateKey,
});
await (0, sdk_core_1.createCombinedKey)({
keyShare: userKeyShare,
commonKeychain: 'nottherightkeychain',
encryptedYShares: [
{
yShare: bitgoToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
}).should.be.rejectedWith('Common keychains do not match');
});
it('should fail if gpg keys are mismatched', async function () {
const bitgoToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const backupToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: backupGpgKeypair.privateKey,
});
await (0, sdk_core_1.createCombinedKey)({
keyShare: userKeyShare,
commonKeychain: 'nottherightkeychain',
encryptedYShares: [
{
yShare: bitgoToUserShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
}).should.be.rejectedWith('Error decrypting message: Session key decryption failed.');
});
});
describe('Eddsa tss signing helper function', async function () {
const bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'mock' });
bitgo.initializeTestVars();
let wallet;
const path = 'm/0';
const validUserSigningMaterial = {
uShare: {
i: 1,
t: 2,
n: 3,
y: '093c8603ad86c41d5ee25a814b88185b435dd3a9ceccf9c9fd691a465ac4a8b0',
seed: 'ca40c789813250c334ddd2ba19050f6ed20b5a08853ceca492358f2711ad4b15',
chaincode: '596d5404a7eb918ee78247b952d06539619884091fdd9e0ff5a665f349e32fca',
},
commonChaincode: '596d5404a7eb918ee78247b952d06539619884091fdd9e0ff5a665f349e32fca',
bitgoYShare: {
i: 1,
j: 3,
y: '59d8000ba5e85fa402f39382960e7d5ede82b1b6e22b146a18b7df238c3a3225',
v: '01ea3f425b1adf8aec6cfe4fc8f9b94755c34657965f32397655dcd784f1b517',
u: '9ce3204a8c9757738967f3f81b463d87267bf6f2c0e5eaf2843167537b872b0b',
chaincode: 'd21dbd8eae5d4789292ecea2efa53e0165b2439d57f5158eb4dd57dc26b59236',
},
backupYShare: {
i: 1,
j: 2,
y: 'e0ae75077715686a121acb41b29a55bde426971154f40a41fc317f7f774a9424',
v: 'f76ef629dfc15ab5e4531e532b5d67f2176637ca752b195876b7e3172459c969',
u: 'fe6b89fb6acfcd7392c35c084f58bde0846b888c4df57e466caf0a3271b06a05',
chaincode: '1c34e5dfbbd4a870f4479caaa5e6a46e3438f976ad5aefd4905b8fe8bca1101e',
},
};
const validUserSignShare = {
xShare: {
i: 1,
y: '4d9343988e68191aac945a6963031dddde3490f9020d0571a6e6c6e15cca0296',
u: '1e159d6a0ae3a8dccc74615113e7c3e25d3080e5e0ffeb0ae04dd6a967268102',
r: 'c8f64cc48926216c3f60e1d8ff1e24eba060d7c1ff020d0fc1d735d4564efd03',
R: '9be2208ee28cd4b2577a9a66f6aab1ed8b08a300969eeb9b203a52aa54d2c23c',
},
rShares: {
3: {
i: 3,
j: 1,
u: 'd675f9099fbef03aa9fcdca4009286f435e56369c374d0042f03cc60b49e690a',
v: '3c090e88ed42da0dd0bade35c8d6b88bc050284536b98e5b27d33ff45da9755b',
r: '7f16224dbf5b02adb6c21380fcb2a8ee00323daae62cac3575a4d328fd23a905',
R: '9be2208ee28cd4b2577a9a66f6aab1ed8b08a300969eeb9b203a52aa54d2c23c',
commitment: '445c8cb1dee0166b6bdd5ad1d0a53fbfe86c4d3a470f184745530a863eedff28',
},
},
};
const validUserToBitgoGShare = {
i: 1,
y: '4d9343988e68191aac945a6963031dddde3490f9020d0571a6e6c6e15cca0296',
gamma: 'ce87a00d17e52b91bc5bb6e275983b84fc1998b2b37f7166c671a019c33d3905',
R: 'aa6e5bad24ad4131b8793dcb95c72e03c5426456ab0b52fc99d61d7103c2f01b',
};
const validBitgoToUserSignShare = {
xShare: {
i: 3,
y: '4d9343988e68191aac945a6963031dddde3490f9020d0571a6e6c6e15cca0296',
u: '1315dbe18069825b4a27188b813eae7ff2917a614499ed553e70d65d4fa4820b',
r: 'd0539375e6566f2fe540cba48c5e56bd1cdf68cfe1f0d527d2b730fe4e879809',
R: 'c883fe2ae9b8da1764cc36a526cfa1a21f81d604320b209867f8de9223f1de32',
},
rShares: {
1: {
i: 1,
j: 3,
u: '9ce3204a8c9757738967f3f81b463d87267bf6f2c0e5eaf2843167537b872b0b',
v: '01ea3f425b1adf8aec6cfe4fc8f9b94755c34657965f32397655dcd784f1b517',
r: '0375e8c5a5691a73c21df00d49d423e3f83fe08d7b5d5af33c5c6aa9cae59d0a',
R: 'c883fe2ae9b8da1764cc36a526cfa1a21f81d604320b209867f8de9223f1de32',
commitment: '62b21f98bf885841ad469145192d4df0697b3f42c581e3e926394eae0b101ecb',
},
},
};
const txRequest = {
txRequestId: 'randomId',
unsignedTxs: [{ signableHex: 'MPC on a Friday night', serializedTxHex: 'MPC on a Friday night' }],
signatureShares: [
{
from: 'bitgo',
to: 'user',
share: validBitgoToUserSignShare.rShares[1].r + validBitgoToUserSignShare.rShares[1].R,
},
],
};
const signablePayload = Buffer.from(txRequest.unsignedTxs[0].signableHex);
const bitgoToUserCommitment = {
from: sdk_core_1.SignatureShareType.BITGO,
to: sdk_core_1.SignatureShareType.USER,
share: validBitgoToUserSignShare.rShares[1].commitment,
type: sdk_core_1.CommitmentType.COMMITMENT,
};
let MPC;
before('initializes', async function () {
const hdTree = await sdk_core_1.Ed25519BIP32.initialize();
MPC = await sdk_core_1.Eddsa.initialize(hdTree);
const baseCoin = bitgo.coin('tsol');
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'tsol',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
};
wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
});
describe('createUserSignShare:', async function () {
it('should succeed to create User SignShare', async function () {
const signingKey = MPC.keyDerive(validUserSigningMaterial.uShare, [validUserSigningMaterial.bitgoYShare, validUserSigningMaterial.backupYShare], path);
const userSignShare = await (0, sdk_core_1.createUserSignShare)(signablePayload, signingKey.pShare);
userSignShare.should.have.properties(['xShare', 'rShares']);
const { xShare, rShares } = userSignShare;
xShare.should.have.property('i').and.be.a.Number();
xShare.should.have.property('y').and.be.a.String();
xShare.should.have.property('u').and.be.a.String();
xShare.should.have.property('r').and.be.a.String();
xShare.should.have.property('R').and.be.a.String();
rShares.should.have.property('3').and.be.an.Object();
rShares[3].should.have.property('i').and.be.a.Number();
rShares[3].should.have.property('j').and.be.a.Number();
rShares[3].should.have.property('r').and.be.a.String();
rShares[3].should.have.property('R').and.be.a.String();
});
it('should fail if the Pshare doesnt belong to the User', async function () {
const invalidUserSigningMaterial = JSON.parse('{"uShare":{"i":2,"t":2,"n":3,"y":"e2b844934b56f278b4a8a3665d43d14de80732241622ec7a8bd6cffc0f74452a","seed":"5259ee23a364429919f969247323eee2f4af5786457b4af67d423f8944d3a691","chaincode":"7460de17d732969c3bc9bddbac1055aff168fad5668917b8ed3fd9628fc6e4f8"},"bitgoYShare":{"i":2,"j":3,"y":"141fd5cbb901d46b8c2c783f3d4ee968ae91c38f71aba05146b3ba8bd4309596","u":"581cfacb3de956cc434a35a3ac927f7d0a4daaef48a95c162cadb7878ef2270b","chaincode":"67d33063052606f341cae40877709de725abda41f2df7f4765e3f58ce5030e1a"},"backupYShare":{"i":2,"j":1,"y":"9e69e3e92978896e872d71ff7a9e63a963ab0f59583d4fcbe79f82cde9ea6bf9","u":"52a539f79df448a2f5108a5e410377cbd1574b7c3d9864bb310ebf7beb13460d","chaincode":"bda980c34aa06916f25c4c7934ea09a928bff7730a100902f4d53bb9236771a7"}}');
const signingKey = MPC.keyDerive(invalidUserSigningMaterial.uShare, [invalidUserSigningMaterial.bitgoYShare, invalidUserSigningMaterial.backupYShare], path);
await (0, sdk_core_1.createUserSignShare)(signablePayload, signingKey.pShare).should.be.rejectedWith('Invalid PShare, PShare doesnt belong to the User');
});
});
describe('sendSignatureShare:', async function () {
it('should succeed to send Signature Share', async function () {
const signatureShare = { from: 'user', to: 'bitgo', share: '128bytestring' };
await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
signerShare: 'signerShare',
});
const response = await (0, sdk_core_1.sendSignatureShare)(bitgo, wallet.id(), txRequest.txRequestId, signatureShare, sdk_core_1.RequestType.tx, 'signerShare');
response.should.deepEqual(signatureShare);
});
it('should fail to send Signature Share', async function () {
const invalidSignatureShare = { from: 'bitgo', to: 'user', share: '128bytestring' };
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare: invalidSignatureShare,
signerShare: 'signerShare',
}, 400);
await (0, sdk_core_1.sendSignatureShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidSignatureShare, sdk_core_1.RequestType.tx, 'signerShare').should.be.rejectedWith('some error');
nock.isDone().should.equal(true);
});
});
describe('offerUserToBitgoRShare:', async function () {
it('should succeed to send Signature Share', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserSignShare.rShares[3].r + validUserSignShare.rShares[3].R,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
signerShare: 'signerShare',
});
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserSignShare, 'signerShare').should.be.fulfilled();
nock.isDone().should.equal(true);
});
it('should fail if no rShare is found', async function () {
const invalidUserSignShare = _.cloneDeep(validUserSignShare);
delete invalidUserSignShare.rShares[3];
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserSignShare, 'signerShare').should.be.rejectedWith('userToBitgo RShare not found');
});
it('should fail if the rShare found is invalid', async function () {
const invalidUserSignShare = _.cloneDeep(validUserSignShare);
invalidUserSignShare.rShares[3].i = 1;
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserSignShare, 'signerShare').should.be.rejectedWith('Invalid RShare, is not from User to Bitgo');
const invalidUserSignShare2 = _.cloneDeep(validUserSignShare);
invalidUserSignShare2.rShares[3].j = 3;
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserSignShare2, 'signerShare').should.be.rejectedWith('Invalid RShare, is not from User to Bitgo');
});
it('should call setRequestTracer', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserSignShare.rShares[3].r + validUserSignShare.rShares[3].R,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
signerShare: 'signerShare',
});
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserSignShare, 'signerShare', undefined, reqId).should.be.fulfilled();
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('getBitgoToUserRShare:', async function () {
it('should succeed to get the Bitgo to User RShare', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const bitgoToUserRShare = await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId);
bitgoToUserRShare.should.deepEqual(txRequest.signatureShares[0]);
nock.isDone().should.equal(true);
});
it('should fail if there is no bitgo to user RShare', async function () {
const invalidTxRequest = _.cloneDeep(txRequest);
invalidTxRequest.signatureShares[0].to = 'bitgo';
invalidTxRequest.signatureShares[0].from = 'user';
const response = { txRequests: [invalidTxRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith('Bitgo to User RShare not found for id: ' + txRequest.txRequestId);
nock.isDone().should.equal(true);
});
it('should fail if there is no signaturesShares', async function () {
const invalidTxRequest = _.cloneDeep(txRequest);
invalidTxRequest.signatureShares = [];
const response = { txRequests: [invalidTxRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith('No signatures shares found for id: ' + txRequest.txRequestId);
nock.isDone().should.equal(true);
});
it('should call setRequestTracer', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
const bitgoToUserRShare = await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId, reqId);
bitgoToUserRShare.should.deepEqual(txRequest.signatureShares[0]);
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('sendUserToBitgoGShare:', async function () {
it('should succeed to send User to Bitgo GShare', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserToBitgoGShare.R + validUserToBitgoGShare.gamma,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
});
await (0, sdk_core_1.sendUserToBitgoGShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserToBitgoGShare).should.be.fulfilled();
nock.isDone().should.equal(true);
});
it('should fail when the GShare is not from the User', async function () {
const invalidUserToBitgoGShare = _.cloneDeep(validUserToBitgoGShare);
invalidUserToBitgoGShare.i = 3;
await (0, sdk_core_1.sendUserToBitgoGShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserToBitgoGShare).should.be.rejectedWith('Invalid GShare, doesnt belong to the User');
});
it('should call setRequestTracer', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserToBitgoGShare.R + validUserToBitgoGShare.gamma,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
});
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
await (0, sdk_core_1.sendUserToBitgoGShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserToBitgoGShare, undefined, reqId).should.be.fulfilled();
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('getTxRequest:', async function () {
it('should succeed to get txRequest by id', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const txReq = await (0, sdk_core_1.getTxRequest)(bitgo, wallet.id(), txRequest.txRequestId);
txReq.should.deepEqual(txRequest);
nock.isDone().should.equal(true);
});
it('should fail if there are no txRequests', async function () {
const response = { txRequests: [] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await (0, sdk_core_1.getTxRequest)(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith('Unable to find TxRequest with id randomId');
nock.isDone().should.equal(true);
});
it('should call setRequestTracer', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
const txReq = await (0, sdk_core_1.getTxRequest)(bitgo, wallet.id(), txRequest.txRequestId, reqId);
txReq.should.deepEqual(txRequest);
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('createUserToBitGoGShare:', async function () {
it('should succeed to create a UserToBitGo GShare', async function () {
const userToBitgoGShare = await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, txRequest.signatureShares[0], validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment);
userToBitgoGShare.should.deepEqual(validUserToBitgoGShare);
});
it('should fail when XShare doesnt belong to the user', async function () {
const invalidUserSignShare = _.cloneDeep(validUserSignShare);
invalidUserSignShare.xShare.i = 3;
await (0, sdk_core_1.createUserToBitGoGShare)(invalidUserSignShare, txRequest.signatureShares[0], validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment).should.be.rejectedWith('Invalid XShare, doesnt belong to the User');
});
it('should fail when commitment is invalid', async function () {
const invalidBitgoToUserCommitment = _.cloneDeep(bitgoToUserCommitment);
invalidBitgoToUserCommitment.share = 'deadbeef';
await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, txRequest.signatureShares[0], validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, invalidBitgoToUserCommitment).should.be.rejectedWith('Could not verify other player share');
});
it('should fail when RShare doesnt belong to Bitgo', async function () {
const invalidBitgoRShare = _.cloneDeep(txRequest.signatureShares[0]);
invalidBitgoRShare.from = 'user';
await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, invalidBitgoRShare, validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment).should.be.rejectedWith('Invalid RShare, is not from Bitgo to User');
const invalidBitgoRShare2 = _.cloneDeep(txRequest.signatureShares[0]);
invalidBitgoRShare2.to = 'bitgo';
await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, invalidBitgoRShare2, validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment).should.be.rejectedWith('Invalid RShare, is not from Bitgo to User');
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2EuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZXN0L3YyL3VuaXQvdHNzL2VkZHNhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOENBc0J5QjtBQUN6QixtQ0FBbUM7QUFDbkMsaUNBQWlDO0FBQ2pDLDRCQUE0QjtBQUM1Qiw4Q0FBNEM7QUFDNUMsaURBQThDO0FBQzlDLHVDQUFxRTtBQUNyRSwrQkFBK0I7QUFDL0IsNkJBQThCO0FBRTlCLFFBQVEsQ0FBQywyQkFBMkIsRUFBRTtJQUNwQyxJQUFJLEdBQVUsQ0FBQztJQUVmLElBQUksWUFBc0IsQ0FBQztJQUMzQixJQUFJLGNBQXdCLENBQUM7SUFDN0IsSUFBSSxhQUF1QixDQUFDO0lBRTVCLElBQUksT0FBTyxDQUFDO0lBQ1osSUFBSSxTQUFTLENBQUM7SUFDZCxJQUFJLFFBQVEsQ0FBQztJQUViLElBQUksY0FBeUQsQ0FBQztJQUM5RCxJQUFJLGdCQUEyRCxDQUFDO0lBQ2hFLElBQUksZUFBMEQsQ0FBQztJQUUvRCxJQUFJLGNBQXNCLENBQUM7SUFFM0IsTUFBTSxDQUFDLEtBQUs7UUFDVixNQUFNLE1BQU0sR0FBRyxNQUFNLHVCQUFZLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDL0MsR0FBRyxHQUFHLE1BQU0sZ0JBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFckMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyQyxjQUFjLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLGFBQWEsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFdEMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLE1BQU0s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QyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbkQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNuRCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ25ELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbkQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNyRCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZELE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkQsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN2RCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENB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QyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgZW5jcnlwdFlTaGFyZSxcbiAgY3JlYXRlQ29tYmluZWRLZXksXG4gIGNyZWF0ZVVzZXJTaWduU2hhcmUsXG4gIHNlbmRTaWduYXR1cmVTaGFyZSxcbiAgZ2V0Qml0Z29Ub1VzZXJSU2hhcmUsXG4gIGdldFR4UmVxdWVzdCxcbiAgb2ZmZXJVc2VyVG9CaXRnb1JTaGFyZSxcbiAgY3JlYXRlVXNlclRvQml0R29HU2hhcmUsXG4gIHNlbmRVc2VyVG9CaXRnb0dTaGFyZSxcbiAgcmVhZFNpZ25lZE1lc3NhZ2UsXG4gIFJlcXVlc3RUeXBlLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgV2FsbGV0LFxuICBLZXlTaGFyZSxcbiAgRWQyNTUxOUJJUDMyLFxuICBFZGRzYSxcbiAgU2lnblNoYXJlLFxuICBDb21taXRtZW50U2hhcmVSZWNvcmQsXG4gIENvbW1pdG1lbnRUeXBlLFxuICBTaWduYXR1cmVTaGFyZVR5cGUsXG4gIFJlcXVlc3RUcmFjZXIsXG59IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyBvcGVucGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICcuLi8uLi8uLi8uLi9zcmMvYml0Z28nO1xuaW1wb3J0IHsgbm9ja0dldFR4UmVxdWVzdCwgbm9ja1NlbmRTaWduYXR1cmVTaGFyZSB9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgbm9jayA9IHJlcXVpcmUoJ25vY2snKTtcblxuZGVzY3JpYmUoJ3Rlc3QgdHNzIGhlbHBlciBmdW5jdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBtcGM6IEVkZHNhO1xuXG4gIGxldCB1c2VyS2V5U2hhcmU6IEtleVNoYXJlO1xuICBsZXQgYmFja3VwS2V5U2hhcmU6IEtleVNoYXJlO1xuICBsZXQgYml0Z29LZXlTaGFyZTogS2V5U2hhcmU7XG5cbiAgbGV0IHVzZXJLZXk7XG4gIGxldCBiYWNrdXBLZXk7XG4gIGxldCBiaXRnb0tleTtcblxuICBsZXQgdXNlckdwZ0tleXBhaXI6IHsgcHVibGljS2V5OiBzdHJpbmc7IHByaXZhdGVLZXk6IHN0cmluZyB9O1xuICBsZXQgYmFja3VwR3BnS2V5cGFpcjogeyBwdWJsaWNLZXk6IHN0cmluZzsgcHJpdmF0ZUtleTogc3RyaW5nIH07XG4gIGxldCBiaXRnb0dwZ0tleXBhaXI6IHsgcHVibGljS2V5OiBzdHJpbmc7IHByaXZhdGVLZXk6IHN0cmluZyB9O1xuXG4gIGxldCBjb21tb25LZXljaGFpbjogc3RyaW5nO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgaGRUcmVlID0gYXdhaXQgRWQyNTUxOUJJUDMyLmluaXRpYWxpemUoKTtcbiAgICBtcGMgPSBhd2FpdCBFZGRzYS5pbml0aWFsaXplKGhkVHJlZSk7XG5cbiAgICB1c2VyS2V5U2hhcmUgPSBtcGMua2V5U2hhcmUoMSwgMiwgMyk7XG4gICAgYmFja3VwS2V5U2hhcmUgPSBtcGMua2V5U2hhcmUoMiwgMiwgMyk7XG4gICAgYml0Z29LZXlTaGFyZSA9IG1wYy5rZXlTaGFyZSgzLCAyLCAzKTtcblxuICAgIHVzZXJLZXkgPSBtcGMua2V5Q29tYmluZSh1c2VyS2V5U2hhcmUudVNoYXJlLCBbYmFja3VwS2V5U2hhcmUueVNoYXJlc1sxXSwgYml0Z29LZXlTaGFyZS55U2hhcmVzWzFdXSk7XG4gICAgYmFja3VwS2V5ID0gbXBjLmtleUNvbWJpbmUoYmFja3VwS2V5U2hhcmUudVNoYXJlLCBbdXNlcktleVNoYXJlLnlTaGFyZXNbMl0sIGJpdGdvS2V5U2hhcmUueVNoYXJlc1syXV0pO1xuICAgIGJpdGdvS2V5ID0gbXBjLmtleUNvbWJpbmUoYml0Z29LZXlTaGFyZS51U2hhcmUsIFtiYWNrdXBLZXlTaGFyZS55U2hhcmVzWzNdLCB1c2VyS2V5U2hhcmUueVNoYXJlc1szXV0pO1xuXG4gICAgKHVzZXJLZXkucFNoYXJlLnkgKyB1c2VyS2V5LnBTaGFyZS5jaGFpbmNvZGUpLnNob3VsZC5lcXVhbChiYWNrdXBLZXkucFNoYXJlLnkgKyBiYWNrdXBLZXkucFNoYXJlLmNoYWluY29kZSk7XG4gICAgKHVzZXJLZXkucFNoYXJlLnkgKyB1c2VyS2V5LnBTaGFyZS5jaGFpbmNvZGUpLnNob3VsZC5lcXVhbChiaXRnb0tleS5wU2hhcmUueSArIGJpdGdvS2V5LnBTaGFyZS5jaGFpbmNvZGUpO1xuICAgIGNvbW1vbktleWNoYWluID0gdXNlcktleS5wU2hhcmUueSArIHVzZXJLZXkucFNoYXJlLmNoYWluY29kZTtcblxuICAgIHVzZXJHcGdLZXlwYWlyID0gYXdhaXQgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICB1c2VySURzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAndXNlcicsXG4gICAgICAgICAgZW1haWw6ICd1c2VyQGJpdGdvLmNvbScsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICAgIGJhY2t1cEdwZ0tleXBhaXIgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgIHVzZXJJRHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdiYWNrdXAnLFxuICAgICAgICAgIGVtYWlsOiAnYmFja3VwQGJpdGdvLmNvbScsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICAgIGJpdGdvR3BnS2V5cGFpciA9IGF3YWl0IG9wZW5wZ3AuZ2VuZXJhdGVLZXkoe1xuICAgICAgdXNlcklEczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ2JpdGdvJyxcbiAgICAgICAgICBlbWFpbDogJ2JpdGdvQGJpdGdvLmNvbScsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnZW5jcnlwdFlTaGFyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGVuY3J5cHQgeSBzaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGZvciAobGV0IGkgPSAyOyBpIDw9IDM7IGkrKykge1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRZU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAgICBrZXlTaGFyZTogdXNlcktleVNoYXJlLFxuICAgICAgICAgIHJlY2lwaWVudEluZGV4OiBpLFxuICAgICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogYml0Z29HcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZGVjcnlwdGVkTWVzc2FnZSA9IGF3YWl0IHJlYWRTaWduZWRNZXNzYWdlKFxuICAgICAgICAgIGVuY3J5cHRlZFlTaGFyZS5lbmNyeXB0ZWRQcml2YXRlU2hhcmUsXG4gICAgICAgICAgdXNlckdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICAgIGJpdGdvR3BnS2V5cGFpci5wcml2YXRlS2V5XG4gICAgICAgICk7XG4gICAgICAgIGRlY3J5cHRlZE1lc3NhZ2Uuc2hvdWxkLmVxdWFsKHVzZXJLZXlTaGFyZS55U2hhcmVzW2ldLnUgKyB1c2VyS2V5U2hhcmUueVNoYXJlc1tpXS5jaGFpbmNvZGUpO1xuXG4gICAgICAgIGVuY3J5cHRlZFlTaGFyZS5pLnNob3VsZC5lcXVhbChpKTtcbiAgICAgICAgZW5jcnlwdGVkWVNoYXJlLmouc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBlbmNyeXB0ZWRZU2hhcmUucHVibGljU2hhcmUuc2hvdWxkLmVxdWFsKFxuICAgICAgICAgIHVzZXJLZXlTaGFyZS51U2hhcmUueSArIHVzZXJLZXlTaGFyZS55U2hhcmVzWzNdLnYgKyB1c2VyS2V5U2hhcmUudVNoYXJlLmNoYWluY29kZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlcnJvciBmb3IgaW52YWxpZCByZWNpcGllbnQgaW5kZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IHVzZXJLZXlTaGFyZSxcbiAgICAgICAgcmVjaXBpZW50SW5kZXg6IDEsXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHJlY2lwaWVudCcpO1xuICAgICAgYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgcmVjaXBpZW50SW5kZXg6IDIsXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHJlY2lwaWVudCcpO1xuICAgICAgYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiaXRnb0tleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMyxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiB1c2VyR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogYml0Z29HcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQgcmVjaXBpZW50Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVDb21iaW5lZEtleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBjb21iaW5lZCB1c2VyIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvVG9Vc2VyU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IGJpdGdvS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAxLFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogdXNlckdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBiYWNrdXBUb1VzZXJTaGFyZSA9IGF3YWl0IGVuY3J5cHRZU2hhcmUoe1xuICAgICAgICBrZXlTaGFyZTogYmFja3VwS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAxLFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogdXNlckdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb21iaW5lZFVzZXJLZXkgPSBhd2FpdCBjcmVhdGVDb21iaW5lZEtleSh7XG4gICAgICAgIGtleVNoYXJlOiB1c2VyS2V5U2hhcmUsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBlbmNyeXB0ZWRZU2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgeVNoYXJlOiBiaXRnb1RvVXNlclNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiB1c2VyR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB5U2hhcmU6IGJhY2t1cFRvVXNlclNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiB1c2VyR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29tYmluZWRVc2VyS2V5LmNvbW1vbktleWNoYWluLnNob3VsZC5lcXVhbChjb21tb25LZXljaGFpbik7XG4gICAgICBjb21iaW5lZFVzZXJLZXkuc2lnbmluZ01hdGVyaWFsLnVTaGFyZS5zaG91bGQuZGVlcEVxdWFsKHVzZXJLZXlTaGFyZS51U2hhcmUpO1xuICAgICAgY29tYmluZWRVc2VyS2V5LnNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUhLnNob3VsZC5kZWVwRXF1YWwoYmFja3VwS2V5U2hhcmUueVNoYXJlc1sxXSk7XG4gICAgICBjb21iaW5lZFVzZXJLZXkuc2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLnNob3VsZC5kZWVwRXF1YWwoYml0Z29LZXlTaGFyZS55U2hhcmVzWzFdKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QoY29tYmluZWRVc2VyS2V5LnNpZ25pbmdNYXRlcmlhbC51c2VyWVNoYXJlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGNvbWJpbmVkIGJhY2t1cCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb1RvQmFja3VwU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IGJpdGdvS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAyLFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogYml0Z29HcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHVzZXJUb0JhY2t1cFNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiB1c2VyS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAyLFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb21iaW5lZEJhY2t1cEtleSA9IGF3YWl0IGNyZWF0ZUNvbWJpbmVkS2V5KHtcbiAgICAgICAga2V5U2hhcmU6IGJhY2t1cEtleVNoYXJlLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgZW5jcnlwdGVkWVNoYXJlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHlTaGFyZTogYml0Z29Ub0JhY2t1cFNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZW5kZXJQdWJsaWNBcm1vcjogYml0Z29HcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHlTaGFyZTogdXNlclRvQmFja3VwU2hhcmUsXG4gICAgICAgICAgICByZWNpcGllbnRQcml2YXRlQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgICAgIHNlbmRlclB1YmxpY0FybW9yOiB1c2VyR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb21iaW5lZEJhY2t1cEtleS5jb21tb25LZXljaGFpbi5zaG91bGQuZXF1YWwoY29tbW9uS2V5Y2hhaW4pO1xuICAgICAgY29tYmluZWRCYWNrdXBLZXkuc2lnbmluZ01hdGVyaWFsLnVTaGFyZS5zaG91bGQuZGVlcEVxdWFsKGJhY2t1cEtleVNoYXJlLnVTaGFyZSk7XG4gICAgICBjb21iaW5lZEJhY2t1cEtleS5zaWduaW5nTWF0ZXJpYWwudXNlcllTaGFyZSEuc2hvdWxkLmRlZXBFcXVhbCh1c2VyS2V5U2hhcmUueVNoYXJlc1syXSk7XG4gICAgICBjb21iaW5lZEJhY2t1cEtleS5zaWduaW5nTWF0ZXJpYWwuYml0Z29ZU2hhcmUuc2hvdWxkLmRlZXBFcXVhbChiaXRnb0tleVNoYXJlLnlTaGFyZXNbMl0pO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChjb21iaW5lZEJhY2t1cEtleS5zaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBpZiBjb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvVG9Vc2VyU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IGJpdGdvS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAxLFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogdXNlckdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBiYWNrdXBUb1VzZXJTaGFyZSA9IGF3YWl0IGVuY3J5cHRZU2hhcmUoe1xuICAgICAgICBrZXlTaGFyZTogYmFja3VwS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAxLFxuICAgICAgICByZWNpcGllbnRHcGdQdWJsaWNBcm1vcjogdXNlckdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBjcmVhdGVDb21iaW5lZEtleSh7XG4gICAgICAgIGtleVNoYXJlOiB1c2VyS2V5U2hhcmUsXG4gICAgICAgIGNvbW1vbktleWNoYWluOiAnbm90dGhlcmlnaHRrZXljaGFpbicsXG4gICAgICAgIGVuY3J5cHRlZFlTaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB5U2hhcmU6IGJpdGdvVG9Vc2VyU2hhcmUsXG4gICAgICAgICAgICByZWNpcGllbnRQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZW5kZXJQdWJsaWNBcm1vcjogYml0Z29HcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHlTaGFyZTogYmFja3VwVG9Vc2VyU2hhcmUsXG4gICAgICAgICAgICByZWNpcGllbnRQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZW5kZXJQdWJsaWNBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0NvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgaWYgZ3BnIGtleXMgYXJlIG1pc21hdGNoZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb1RvVXNlclNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiaXRnb0tleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiBiaXRnb0dwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYmFja3VwVG9Vc2VyU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IGJhY2t1cEtleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgY3JlYXRlQ29tYmluZWRLZXkoe1xuICAgICAgICBrZXlTaGFyZTogdXNlcktleVNoYXJlLFxuICAgICAgICBjb21tb25LZXljaGFpbjogJ25vdHRoZXJpZ2h0a2V5Y2hhaW4nLFxuICAgICAgICBlbmNyeXB0ZWRZU2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgeVNoYXJlOiBiaXRnb1RvVXNlclNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZW5kZXJQdWJsaWNBcm1vcjogYml0Z29HcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHlTaGFyZTogYmFja3VwVG9Vc2VyU2hhcmUsXG4gICAgICAgICAgICByZWNpcGllbnRQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZW5kZXJQdWJsaWNBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0Vycm9yIGRlY3J5cHRpbmcgbWVzc2FnZTogU2Vzc2lvbiBrZXkgZGVjcnlwdGlvbiBmYWlsZWQuJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFZGRzYSB0c3Mgc2lnbmluZyBoZWxwZXIgZnVuY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG5cbiAgICBsZXQgd2FsbGV0OiBXYWxsZXQ7XG4gICAgY29uc3QgcGF0aCA9ICdtLzAnO1xuICAgIGNvbnN0IHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbCA9IHtcbiAgICAgIHVTaGFyZToge1xuICAgICAgICBpOiAxLFxuICAgICAgICB0OiAyLFxuICAgICAgICBuOiAzLFxuICAgICAgICB5OiAnMDkzYzg2MDNhZDg2YzQxZDVlZTI1YTgxNGI4ODE4NWI0MzVkZDNhOWNlY2NmOWM5ZmQ2OTFhNDY1YWM0YThiMCcsXG4gICAgICAgIHNlZWQ6ICdjYTQwYzc4OTgxMzI1MGMzMzRkZGQyYmExOTA1MGY2ZWQyMGI1YTA4ODUzY2VjYTQ5MjM1OGYyNzExYWQ0YjE1JyxcbiAgICAgICAgY2hhaW5jb2RlOiAnNTk2ZDU0MDRhN2ViOTE4ZWU3ODI0N2I5NTJkMDY1Mzk2MTk4ODQwOTFmZGQ5ZTBmZjVhNjY1ZjM0OWUzMmZjYScsXG4gICAgICB9LFxuICAgICAgY29tbW9uQ2hhaW5jb2RlOiAnNTk2ZDU0MDRhN2ViOTE4ZWU3ODI0N2I5NTJkMDY1Mzk2MTk4ODQwOTFmZGQ5ZTBmZjVhNjY1ZjM0OWUzMmZjYScsXG4gICAgICBiaXRnb1lTaGFyZToge1xuICAgICAgICBpOiAxLFxuICAgICAgICBqOiAzLFxuICAgICAgICB5OiAnNTlkODAwMGJhNWU4NWZhNDAyZjM5MzgyOTYwZTdkNWVkZTgyYjFiNmUyMmIxNDZhMThiN2RmMjM4YzNhMzIyNScsXG4gICAgICAgIHY6ICcwMWVhM2Y0MjViMWFkZjhhZWM2Y2ZlNGZjOGY5Yjk0NzU1YzM0NjU3OTY1ZjMyMzk3NjU1ZGNkNzg0ZjFiNTE3JyxcbiAgICAgICAgdTogJzljZTMyMDRhOGM5NzU3NzM4OTY3ZjNmODFiNDYzZDg3MjY3YmY2ZjJjMGU1ZWFmMjg0MzE2NzUzN2I4NzJiMGInLFxuICAgICAgICBjaGFpbmNvZGU6ICdkMjFkYmQ4ZWFlNWQ0Nzg5MjkyZWNlYTJlZmE1M2UwMTY1YjI0MzlkNTdmNTE1OGViNGRkNTdkYzI2YjU5MjM2JyxcbiAgICAgIH0sXG4gICAgICBiYWNrdXBZU2hhcmU6IHtcbiAgICAgICAgaTogMSxcbiAgICAgICAgajogMixcbiAgICAgICAgeTogJ2UwYWU3NTA3NzcxNTY4NmExMjFhY2I0MWIyOWE1NWJkZTQyNjk3MTE1NGY0MGE0MWZjMzE3ZjdmNzc0YTk0MjQnLFxuICAgICAgICB2OiAnZjc2ZWY2MjlkZmMxNWFiNWU0NTMxZTUzMmI1ZDY3ZjIxNzY2MzdjYTc1MmIxOTU4NzZiN2UzMTcyNDU5Yzk2OScsXG4gICAgICAgIHU6ICdmZTZiODlmYjZhY2ZjZDczOTJjMzVjMDg0ZjU4YmRlMDg0NmI4ODhjNGRmNTdlNDY2Y2FmMGEzMjcxYjA2YTA1JyxcbiAgICAgICAgY2hhaW5jb2RlOiAnMWMzNGU1ZGZiYmQ0YTg3MGY0NDc5Y2FhYTVlNmE0NmUzNDM4Zjk3NmFkNWFlZmQ0OTA1YjhmZThiY2ExMTAxZScsXG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgdmFsaWRVc2VyU2lnblNoYXJlOiBTaWduU2hhcmUgPSB7XG4gICAgICB4U2hhcmU6IHtcbiAgICAgICAgaTogMSxcbiAgICAgICAgeTogJzRkOTM0Mzk4OGU2ODE5MWFhYzk0NWE2OTYzMDMxZGRkZGUzNDkwZjkwMjBkMDU3MWE2ZTZjNmUxNWNjYTAyOTYnLFxuICAgICAgICB1OiAnMWUxNTlkNmEwYWUzYThkY2NjNzQ2MTUxMTNlN2MzZTI1ZDMwODBlNWUwZmZlYjBhZTA0ZGQ2YTk2NzI2ODEwMicsXG4gICAgICAgIHI6ICdjOGY2NGNjNDg5MjYyMTZjM2Y2MGUxZDhmZjFlMjRlYmEwNjBkN2MxZmYwMjBkMGZjMWQ3MzVkNDU2NGVmZDAzJyxcbiAgICAgICAgUjogJzliZTIyMDhlZTI4Y2Q0YjI1NzdhOWE2NmY2YWFiMWVkOGIwOGEzMDA5NjllZWI5YjIwM2E1MmFhNTRkMmMyM2MnLFxuICAgICAgfSxcbiAgICAgIHJTaGFyZXM6IHtcbiAgICAgICAgMzoge1xuICAgICAgICAgIGk6IDMsXG4gICAgICAgICAgajogMSxcbiAgICAgICAgICB1OiAnZDY3NWY5MDk5ZmJlZjAzYWE5ZmNkY2E0MDA5Mjg2ZjQzNWU1NjM2OWMzNzRkMDA0MmYwM2NjNjBiNDllNjkwYScsXG4gICAgICAgICAgdjogJzNjMDkwZTg4ZWQ0MmRhMGRkMGJhZGUzNWM4ZDZiODhiYzA1MDI4NDUzNmI5OGU1YjI3ZDMzZmY0NWRhOTc1NWInLFxuICAgICAgICAgIHI6ICc3ZjE2MjI0ZGJmNWIwMmFkYjZjMjEzODBmY2IyYThlZTAwMzIzZGFhZTYyY2FjMzU3NWE0ZDMyOGZkMjNhOTA1JyxcbiAgICAgICAgICBSOiAnOWJlMjIwOGVlMjhjZDRiMjU3N2E5YTY2ZjZhYWIxZWQ4YjA4YTMwMDk2OWVlYjliMjAzYTUyYWE1NGQyYzIzYycsXG4gICAgICAgICAgY29tbWl0bWVudDogJzQ0NWM4Y2IxZGVlMDE2NmI2YmRkNWFkMWQwYTUzZmJmZTg2YzRkM2E0NzBmMTg0NzQ1NTMwYTg2M2VlZGZmMjgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdmFsaWRVc2VyVG9CaXRnb0dTaGFyZSA9IHtcbiAgICAgIGk6IDEsXG4gICAgICB5OiAnNGQ5MzQzOTg4ZTY4MTkxYWFjOTQ1YTY5NjMwMzFkZGRkZTM0OTBmOTAyMGQwNTcxYTZlNmM2ZTE1Y2NhMDI5NicsXG4gICAgICBnYW1tYTogJ2NlODdhMDBkMTdlNTJiOTFiYzViYjZlMjc1OTgzYjg0ZmMxOTk4YjJiMzdmNzE2NmM2NzFhMDE5YzMzZDM5MDUnLFxuICAgICAgUjogJ2FhNmU1YmFkMjRhZDQxMzFiODc5M2RjYjk1YzcyZTAzYzU0MjY0NTZhYjBiNTJmYzk5ZDYxZDcxMDNjMmYwMWInLFxuICAgIH07XG4gICAgY29uc3QgdmFsaWRCaXRnb1RvVXNlclNpZ25TaGFyZTogU2lnblNoYXJlID0ge1xuICAgICAgeFNoYXJlOiB7XG4gICAgICAgIGk6IDMsXG4gICAgICAgIHk6ICc0ZDkzNDM5ODhlNjgxOTFhYWM5NDVhNjk2MzAzMWRkZGRlMzQ5MGY5MDIwZDA1NzFhNmU2YzZlMTVjY2EwMjk2JyxcbiAgICAgICAgdTogJzEzMTVkYmUxODA2OTgyNWI0YTI3MTg4YjgxM2VhZTdmZjI5MTdhNjE0NDk5ZWQ1NTNlNzBkNjVkNGZhNDgyMGInLFxuICAgICAgICByOiAnZDA1MzkzNzVlNjU2NmYyZmU1NDBjYmE0OGM1ZTU2YmQxY2RmNjhjZmUxZjBkNTI3ZDJiNzMwZmU0ZTg3OTgwOScsXG4gICAgICAgIFI6ICdjODgzZmUyYWU5YjhkYTE3NjRjYzM2YTUyNmNmYTFhMjFmODFkNjA0MzIwYjIwOTg2N2Y4ZGU5MjIzZjFkZTMyJyxcbiAgICAgIH0sXG4gICAgICByU2hhcmVzOiB7XG4gICAgICAgIDE6IHtcbiAgICAgICAgICBpOiAxLFxuICAgICAgICAgIGo6IDMsXG4gICAgICAgICAgdTogJzljZTMyMDRhOGM5NzU3NzM4OTY3ZjNmODFiNDYzZDg3MjY3YmY2ZjJjMGU1ZWFmMjg0MzE2NzUzN2I4NzJiMGInLFxuICAgICAgICAgIHY6ICcwMWVhM2Y0MjViMWFkZjhhZWM2Y2ZlNGZjOGY5Yjk0NzU1YzM0NjU3OTY1ZjMyMzk3NjU1ZGNkNzg0ZjFiNTE3JyxcbiAgICAgICAgICByOiAnMDM3NWU4YzVhNTY5MWE3M2MyMWRmMDBkNDlkNDIzZTNmODNmZTA4ZDdiNWQ1YWYzM2M1YzZhYTljYWU1OWQwYScsXG4gICAgICAgICAgUjogJ2M4ODNmZTJhZTliOGRhMTc2NGNjMzZhNTI2Y2ZhMWEyMWY4MWQ2MDQzMjBiMjA5ODY3ZjhkZTkyMjNmMWRlMzInLFxuICAgICAgICAgIGNvbW1pdG1lbnQ6ICc2MmIyMWY5OGJmODg1ODQxYWQ0NjkxNDUxOTJkNGRmMDY5N2IzZjQyYzU4MWUzZTkyNjM5NGVhZTBiMTAxZWNiJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IHR4UmVxdWVzdCA9IHtcbiAgICAgIHR4UmVxdWVzdElkOiAncmFuZG9tSWQnLFxuICAgICAgdW5zaWduZWRUeHM6IFt7IHNpZ25hYmxlSGV4OiAnTVBDIG9uIGEgRnJpZGF5IG5pZ2h0Jywgc2VyaWFsaXplZFR4SGV4OiAnTVBDIG9uIGEgRnJpZGF5IG5pZ2h0JyB9XSxcbiAgICAgIHNpZ25hdHVyZVNoYXJlczogW1xuICAgICAgICB7XG4gICAgICAgICAgZnJvbTogJ2JpdGdvJyxcbiAgICAgICAgICB0bzogJ3VzZXInLFxuICAgICAgICAgIHNoYXJlOiB2YWxpZEJpdGdvVG9Vc2VyU2lnblNoYXJlLnJTaGFyZXNbMV0uciArIHZhbGlkQml0Z29Ub1VzZXJTaWduU2hhcmUuclNoYXJlc1sxXS5SLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICAgIGNvbnN0IHNpZ25hYmxlUGF5bG9hZCA9IEJ1ZmZlci5mcm9tKHR4UmVxdWVzdC51bnNpZ25lZFR4c1swXS5zaWduYWJsZUhleCk7XG4gICAgY29uc3QgYml0Z29Ub1VzZXJDb21taXRtZW50OiBDb21taXRtZW50U2hhcmVSZWNvcmQgPSB7XG4gICAgICBmcm9tOiBTaWduYXR1cmVTaGFyZVR5cGUuQklUR08sXG4gICAgICB0bzogU2lnbmF0dXJlU2hhcmVUeXBlLlVTRVIsXG4gICAgICBzaGFyZTogdmFsaWRCaXRnb1RvVXNlclNpZ25TaGFyZS5yU2hhcmVzWzFdLmNvbW1pdG1lbnQhLFxuICAgICAgdHlwZTogQ29tbWl0bWVudFR5cGUuQ09NTUlUTUVOVCxcbiAgICB9O1xuXG4gICAgbGV0IE1QQzogRWRkc2E7XG5cbiAgICBiZWZvcmUoJ2luaXRpYWxpemVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaGRUcmVlID0gYXdhaXQgRWQyNTUxOUJJUDMyLmluaXRpYWxpemUoKTtcbiAgICAgIE1QQyA9IGF3YWl0IEVkZHNhLmluaXRpYWxpemUoaGRUcmVlKTtcblxuICAgICAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICAgIF0sXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICB9O1xuICAgICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZUNvaW4sIHdhbGxldERhdGEpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2NyZWF0ZVVzZXJTaWduU2hhcmU6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIGNyZWF0ZSBVc2VyIFNpZ25TaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2lnbmluZ0tleSA9IE1QQy5rZXlEZXJpdmUoXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLnVTaGFyZSxcbiAgICAgICAgICBbdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLCB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlXSxcbiAgICAgICAgICBwYXRoXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHVzZXJTaWduU2hhcmUgPSBhd2FpdCBjcmVhdGVVc2VyU2lnblNoYXJlKHNpZ25hYmxlUGF5bG9hZCwgc2lnbmluZ0tleS5wU2hhcmUpO1xuICAgICAgICB1c2VyU2lnblNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnRpZXMoWyd4U2hhcmUnLCAnclNoYXJlcyddKTtcbiAgICAgICAgY29uc3QgeyB4U2hhcmUsIHJTaGFyZXMgfSA9IHVzZXJTaWduU2hhcmU7XG4gICAgICAgIHhTaGFyZS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaScpLmFuZC5iZS5hLk51bWJlcigpO1xuICAgICAgICB4U2hhcmUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3knKS5hbmQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgeFNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1JykuYW5kLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIHhTaGFyZS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncicpLmFuZC5iZS5hLlN0cmluZygpO1xuICAgICAgICB4U2hhcmUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ1InKS5hbmQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgclNoYXJlcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnMycpLmFuZC5iZS5hbi5PYmplY3QoKTtcbiAgICAgICAgclNoYXJlc1szXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaScpLmFuZC5iZS5hLk51bWJlcigpO1xuICAgICAgICByU2hhcmVzWzNdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdqJykuYW5kLmJlLmEuTnVtYmVyKCk7XG4gICAgICAgIHJTaGFyZXNbM10uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3InKS5hbmQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgclNoYXJlc1szXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnUicpLmFuZC5iZS5hLlN0cmluZygpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGUgUHNoYXJlIGRvZXNudCBiZWxvbmcgdG8gdGhlIFVzZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsID0gSlNPTi5wYXJzZShcbiAgICAgICAgICAne1widVNoYXJlXCI6e1wiaVwiOjIsXCJ0XCI6MixcIm5cIjozLFwieVwiOlwiZTJiODQ0OTM0YjU2ZjI3OGI0YThhMzY2NWQ0M2QxNGRlODA3MzIyNDE2MjJlYzdhOGJkNmNmZmMwZjc0NDUyYVwiLFwic2VlZFwiOlwiNTI1OWVlMjNhMzY0NDI5OTE5Zjk2OTI0NzMyM2VlZTJmNGFmNTc4NjQ1N2I0YWY2N2Q0MjNmODk0NGQzYTY5MVwiLFwiY2hhaW5jb2RlXCI6XCI3NDYwZGUxN2Q3MzI5NjljM2JjOWJkZGJhYzEwNTVhZmYxNjhmYWQ1NjY4OTE3YjhlZDNmZDk2MjhmYzZlNGY4XCJ9LFwiYml0Z29ZU2hhcmVcIjp7XCJpXCI6MixcImpcIjozLFwieVwiOlwiMTQxZmQ1Y2JiOTAxZDQ2YjhjMmM3ODNmM2Q0ZWU5NjhhZTkxYzM4ZjcxYWJhMDUxNDZiM2JhOGJkNDMwOTU5NlwiLFwidVwiOlwiNTgxY2ZhY2IzZGU5NTZjYzQzNGEzNWEzYWM5MjdmN2QwYTRkYWFlZjQ4YTk1YzE2MmNhZGI3ODc4ZWYyMjcwYlwiLFwiY2hhaW5jb2RlXCI6XCI2N2QzMzA2MzA1MjYwNmYzNDFjYWU0MDg3NzcwOWRlNzI1YWJkYTQxZjJkZjdmNDc2NWUzZjU4Y2U1MDMwZTFhXCJ9LFwiYmFja3VwWVNoYXJlXCI6e1wiaVwiOjIsXCJqXCI6MSxcInlcIjpcIjllNjllM2U5Mjk3ODg5NmU4NzJkNzFmZjdhOWU2M2E5NjNhYjBmNTk1ODNkNGZjYmU3OWY4MmNkZTllYTZiZjlcIixcInVcIjpcIjUyYTUzOWY3OWRmNDQ4YTJmNTEwOGE1ZTQxMDM3N2NiZDE1NzRiN2MzZDk4NjRiYjMxMGViZjdiZWIxMzQ2MGRcIixcImNoYWluY29kZVwiOlwiYmRhOTgwYzM0YWEwNjkxNmYyNWM0Yzc5MzRlYTA5YTkyOGJmZjc3MzBhMTAwOTAyZjRkNTNiYjkyMzY3NzFhN1wifX0nXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHNpZ25pbmdLZXkgPSBNUEMua2V5RGVyaXZlKFxuICAgICAgICAgIGludmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLnVTaGFyZSxcbiAgICAgICAgICBbaW52YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYml0Z29ZU2hhcmUsIGludmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJhY2t1cFlTaGFyZV0sXG4gICAgICAgICAgcGF0aFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBjcmVhdGVVc2VyU2lnblNoYXJlKHNpZ25hYmxlUGF5bG9hZCwgc2lnbmluZ0tleS5wU2hhcmUpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0ludmFsaWQgUFNoYXJlLCBQU2hhcmUgZG9lc250IGJlbG9uZyB0byB0aGUgVXNlcidcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NlbmRTaWduYXR1cmVTaGFyZTonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gc2VuZCBTaWduYXR1cmUgU2hhcmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlID0geyBmcm9tOiAndXNlcicsIHRvOiAnYml0Z28nLCBzaGFyZTogJzEyOGJ5dGVzdHJpbmcnIH0gYXMgU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgICAgIGF3YWl0IG5vY2tTZW5kU2lnbmF0dXJlU2hhcmUoe1xuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlLFxuICAgICAgICAgIHNpZ25lclNoYXJlOiAnc2lnbmVyU2hhcmUnLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlLFxuICAgICAgICAgIFJlcXVlc3RUeXBlLnR4LFxuICAgICAgICAgICdzaWduZXJTaGFyZSdcbiAgICAgICAgKTtcbiAgICAgICAgcmVzcG9uc2Uuc2hvdWxkLmRlZXBFcXVhbChzaWduYXR1cmVTaGFyZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHNlbmQgU2lnbmF0dXJlIFNoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnZhbGlkU2lnbmF0dXJlU2hhcmUgPSB7IGZyb206ICdiaXRnbycsIHRvOiAndXNlcicsIHNoYXJlOiAnMTI4Ynl0ZXN0cmluZycgfSBhcyBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgICAgICAgY29uc3Qgbm9jayA9IGF3YWl0IG5vY2tTZW5kU2lnbmF0dXJlU2hhcmUoXG4gICAgICAgICAge1xuICAgICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLFxuICAgICAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICAgIHNpZ25hdHVyZVNoYXJlOiBpbnZhbGlkU2lnbmF0dXJlU2hhcmUsXG4gICAgICAgICAgICBzaWduZXJTaGFyZTogJ3NpZ25lclNoYXJlJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIDQwMFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBzZW5kU2lnbmF0dXJlU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIGludmFsaWRTaWduYXR1cmVTaGFyZSxcbiAgICAgICAgICBSZXF1ZXN0VHlwZS50eCxcbiAgICAgICAgICAnc2lnbmVyU2hhcmUnXG4gICAgICAgICkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnc29tZSBlcnJvcicpO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ29mZmVyVXNlclRvQml0Z29SU2hhcmU6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHNlbmQgU2lnbmF0dXJlIFNoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmVTaGFyZSA9IHtcbiAgICAgICAgICBmcm9tOiAndXNlcicsXG4gICAgICAgICAgdG86ICdiaXRnbycsXG4gICAgICAgICAgc2hhcmU6IHZhbGlkVXNlclNpZ25TaGFyZS5yU2hhcmVzWzNdLnIgKyB2YWxpZFVzZXJTaWduU2hhcmUuclNoYXJlc1szXS5SLFxuICAgICAgICB9IGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja1NlbmRTaWduYXR1cmVTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmUsXG4gICAgICAgICAgc2lnbmVyU2hhcmU6ICdzaWduZXJTaGFyZScsXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBvZmZlclVzZXJUb0JpdGdvUlNoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgJ3NpZ25lclNoYXJlJ1xuICAgICAgICApLnNob3VsZC5iZS5mdWxmaWxsZWQoKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIG5vIHJTaGFyZSBpcyBmb3VuZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFVzZXJTaWduU2hhcmUgPSBfLmNsb25lRGVlcCh2YWxpZFVzZXJTaWduU2hhcmUpIGFzIGFueTtcbiAgICAgICAgZGVsZXRlIGludmFsaWRVc2VyU2lnblNoYXJlLnJTaGFyZXNbM107XG4gICAgICAgIGF3YWl0IG9mZmVyVXNlclRvQml0Z29SU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIGludmFsaWRVc2VyU2lnblNoYXJlLFxuICAgICAgICAgICdzaWduZXJTaGFyZSdcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd1c2VyVG9CaXRnbyBSU2hhcmUgbm90IGZvdW5kJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZSByU2hhcmUgZm91bmQgaXMgaW52YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFVzZXJTaWduU2hhcmUgPSBfLmNsb25lRGVlcCh2YWxpZFVzZXJTaWduU2hhcmUpIGFzIGFueTtcbiAgICAgICAgaW52YWxpZFVzZXJTaWduU2hhcmUuclNoYXJlc1szXS5pID0gMTtcbiAgICAgICAgYXdhaXQgb2ZmZXJVc2VyVG9CaXRnb1JTaGFyZShcbiAgICAgICAgICBiaXRnbyxcbiAgICAgICAgICB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgaW52YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgJ3NpZ25lclNoYXJlJ1xuICAgICAgICApLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQgUlNoYXJlLCBpcyBub3QgZnJvbSBVc2VyIHRvIEJpdGdvJyk7XG5cbiAgICAgICAgY29uc3QgaW52YWxpZFVzZXJTaWduU2hhcmUyID0gXy5jbG9uZURlZXAodmFsaWRVc2VyU2lnblNoYXJlKSBhcyBhbnk7XG4gICAgICAgIGludmFsaWRVc2VyU2lnblNoYXJlMi5yU2hhcmVzWzNdLmogPSAzO1xuICAgICAgICBhd2FpdCBvZmZlclVzZXJUb0JpdGdvUlNoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBpbnZhbGlkVXNlclNpZ25TaGFyZTIsXG4gICAgICAgICAgJ3NpZ25lclNoYXJlJ1xuICAgICAgICApLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQgUlNoYXJlLCBpcyBub3QgZnJvbSBVc2VyIHRvIEJpdGdvJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBjYWxsIHNldFJlcXVlc3RUcmFjZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZVNoYXJlID0ge1xuICAgICAgICAgIGZyb206ICd1c2VyJyxcbiAgICAgICAgICB0bzogJ2JpdGdvJyxcbiAgICAgICAgICBzaGFyZTogdmFsaWRVc2VyU2lnblNoYXJlLnJTaGFyZXNbM10uciArIHZhbGlkVXNlclNpZ25TaGFyZS5yU2hhcmVzWzNdLlIsXG4gICAgICAgIH0gYXMgU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrU2VuZFNpZ25hdHVyZVNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZSxcbiAgICAgICAgICBzaWduZXJTaGFyZTogJ3NpZ25lclNoYXJlJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgICAgICAgY29uc3Qgc2V0UmVxdWVzdFRyYWNlclNweSA9IHNpbm9uLnNweShiaXRnbywgJ3NldFJlcXVlc3RUcmFjZXInKTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS53aXRoQXJncyhyZXFJZCk7XG4gICAgICAgIGF3YWl0IG9mZmVyVXNlclRvQml0Z29SU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25TaGFyZSxcbiAgICAgICAgICAnc2lnbmVyU2hhcmUnLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICByZXFJZFxuICAgICAgICApLnNob3VsZC5iZS5mdWxmaWxsZWQoKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHNldFJlcXVlc3RUcmFjZXJTcHkpO1xuICAgICAgICBzZXRSZXF1ZXN0VHJhY2VyU3B5LnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2dldEJpdGdvVG9Vc2VyUlNoYXJlOicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byBnZXQgdGhlIEJpdGdvIHRvIFVzZXIgUlNoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdF0gfTtcbiAgICAgICAgY29uc3Qgbm9jayA9IGF3YWl0IG5vY2tHZXRUeFJlcXVlc3QoeyB3YWxsZXRJZDogd2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlc3BvbnNlIH0pO1xuICAgICAgICBjb25zdCBiaXRnb1RvVXNlclJTaGFyZSA9IGF3YWl0IGdldEJpdGdvVG9Vc2VyUlNoYXJlKGJpdGdvLCB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0LnR4UmVxdWVzdElkKTtcbiAgICAgICAgYml0Z29Ub1VzZXJSU2hhcmUuc2hvdWxkLmRlZXBFcXVhbCh0eFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZXJlIGlzIG5vIGJpdGdvIHRvIHVzZXIgUlNoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnZhbGlkVHhSZXF1ZXN0ID0gXy5jbG9uZURlZXAodHhSZXF1ZXN0KTtcbiAgICAgICAgaW52YWxpZFR4UmVxdWVzdC5zaWduYXR1cmVTaGFyZXNbMF0udG8gPSAnYml0Z28nO1xuICAgICAgICBpbnZhbGlkVHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlc1swXS5mcm9tID0gJ3VzZXInO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgdHhSZXF1ZXN0czogW2ludmFsaWRUeFJlcXVlc3RdIH07XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZSB9KTtcbiAgICAgICAgYXdhaXQgZ2V0Qml0Z29Ub1VzZXJSU2hhcmUoYml0Z28sIHdhbGxldC5pZCgpLCB0eFJlcXVlc3QudHhSZXF1ZXN0SWQpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0JpdGdvIHRvIFVzZXIgUlNoYXJlIG5vdCBmb3VuZCBmb3IgaWQ6ICcgKyB0eFJlcXVlc3QudHhSZXF1ZXN0SWRcbiAgICAgICAgKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZXJlIGlzIG5vIHNpZ25hdHVyZXNTaGFyZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRUeFJlcXVlc3QgPSBfLmNsb25lRGVlcCh0eFJlcXVlc3QpO1xuICAgICAgICBpbnZhbGlkVHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlcyA9IFtdO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgdHhSZXF1ZXN0czogW2ludmFsaWRUeFJlcXVlc3RdIH07XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZSB9KTtcbiAgICAgICAgYXdhaXQgZ2V0Qml0Z29Ub1VzZXJSU2hhcmUoYml0Z28sIHdhbGxldC5pZCgpLCB0eFJlcXVlc3QudHhSZXF1ZXN0SWQpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ05vIHNpZ25hdHVyZXMgc2hhcmVzIGZvdW5kIGZvciBpZDogJyArIHR4UmVxdWVzdC50eFJlcXVlc3RJZFxuICAgICAgICApO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgc2V0UmVxdWVzdFRyYWNlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7IHR4UmVxdWVzdHM6IFt0eFJlcXVlc3RdIH07XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZSB9KTtcbiAgICAgICAgY29uc3QgcmVxSWQgPSBuZXcgUmVxdWVzdFRyYWNlcigpO1xuICAgICAgICBjb25zdCBzZXRSZXF1ZXN0VHJhY2VyU3B5ID0gc2lub24uc3B5KGJpdGdvLCAnc2V0UmVxdWVzdFRyYWNlcicpO1xuICAgICAgICBzZXRSZXF1ZXN0VHJhY2VyU3B5LndpdGhBcmdzKHJlcUlkKTtcbiAgICAgICAgY29uc3QgYml0Z29Ub1VzZXJSU2hhcmUgPSBhd2FpdCBnZXRCaXRnb1RvVXNlclJTaGFyZShiaXRnbywgd2FsbGV0LmlkKCksIHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVxSWQpO1xuICAgICAgICBiaXRnb1RvVXNlclJTaGFyZS5zaG91bGQuZGVlcEVxdWFsKHR4UmVxdWVzdC5zaWduYXR1cmVTaGFyZXNbMF0pO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uoc2V0UmVxdWVzdFRyYWNlclNweSk7XG4gICAgICAgIHNldFJlcXVlc3RUcmFjZXJTcHkucmVzdG9yZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2VuZFVzZXJUb0JpdGdvR1NoYXJlOicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byBzZW5kIFVzZXIgdG8gQml0Z28gR1NoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmVTaGFyZSA9IHtcbiAgICAgICAgICBmcm9tOiAndXNlcicsXG4gICAgICAgICAgdG86ICdiaXRnbycsXG4gICAgICAgICAgc2hhcmU6IHZhbGlkVXNlclRvQml0Z29HU2hhcmUuUiArIHZhbGlkVXNlclRvQml0Z29HU2hhcmUuZ2FtbWEsXG4gICAgICAgIH0gYXMgU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrU2VuZFNpZ25hdHVyZVNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHNlbmRVc2VyVG9CaXRnb0dTaGFyZShcbiAgICAgICAgICBiaXRnbyxcbiAgICAgICAgICB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgdmFsaWRVc2VyVG9CaXRnb0dTaGFyZVxuICAgICAgICApLnNob3VsZC5iZS5mdWxmaWxsZWQoKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gdGhlIEdTaGFyZSBpcyBub3QgZnJvbSB0aGUgVXNlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFVzZXJUb0JpdGdvR1NoYXJlID0gXy5jbG9uZURlZXAodmFsaWRVc2VyVG9CaXRnb0dTaGFyZSk7XG4gICAgICAgIGludmFsaWRVc2VyVG9CaXRnb0dTaGFyZS5pID0gMztcbiAgICAgICAgYXdhaXQgc2VuZFVzZXJUb0JpdGdvR1NoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBpbnZhbGlkVXNlclRvQml0Z29HU2hhcmVcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIEdTaGFyZSwgZG9lc250IGJlbG9uZyB0byB0aGUgVXNlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgY2FsbCBzZXRSZXF1ZXN0VHJhY2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmVTaGFyZSA9IHtcbiAgICAgICAgICBmcm9tOiAndXNlcicsXG4gICAgICAgICAgdG86ICdiaXRnbycsXG4gICAgICAgICAgc2hhcmU6IHZhbGlkVXNlclRvQml0Z29HU2hhcmUuUiArIHZhbGlkVXNlclRvQml0Z29HU2hhcmUuZ2FtbWEsXG4gICAgICAgIH0gYXMgU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrU2VuZFNpZ25hdHVyZVNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgICAgICAgY29uc3Qgc2V0UmVxdWVzdFRyYWNlclNweSA9IHNpbm9uLnNweShiaXRnbywgJ3NldFJlcXVlc3RUcmFjZXInKTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS53aXRoQXJncyhyZXFJZCk7XG4gICAgICAgIGF3YWl0IHNlbmRVc2VyVG9CaXRnb0dTaGFyZShcbiAgICAgICAgICBiaXRnbyxcbiAgICAgICAgICB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgdmFsaWRVc2VyVG9CaXRnb0dTaGFyZSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgcmVxSWRcbiAgICAgICAgKS5zaG91bGQuYmUuZnVsZmlsbGVkKCk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShzZXRSZXF1ZXN0VHJhY2VyU3B5KTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS5yZXN0b3JlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRUeFJlcXVlc3Q6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIGdldCB0eFJlcXVlc3QgYnkgaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0geyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0XSB9O1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja0dldFR4UmVxdWVzdCh7IHdhbGxldElkOiB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVzcG9uc2UgfSk7XG4gICAgICAgIGNvbnN0IHR4UmVxID0gYXdhaXQgZ2V0VHhSZXF1ZXN0KGJpdGdvLCB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0LnR4UmVxdWVzdElkKTtcbiAgICAgICAgdHhSZXEuc2hvdWxkLmRlZXBFcXVhbCh0eFJlcXVlc3QpO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgdGhlcmUgYXJlIG5vIHR4UmVxdWVzdHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0geyB0eFJlcXVlc3RzOiBbXSB9O1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja0dldFR4UmVxdWVzdCh7IHdhbGxldElkOiB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVzcG9uc2UgfSk7XG4gICAgICAgIGF3YWl0IGdldFR4UmVxdWVzdChiaXRnbywgd2FsbGV0LmlkKCksIHR4UmVxdWVzdC50eFJlcXVlc3RJZCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnVW5hYmxlIHRvIGZpbmQgVHhSZXF1ZXN0IHdpdGggaWQgcmFuZG9tSWQnXG4gICAgICAgICk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgY2FsbCBzZXRSZXF1ZXN0VHJhY2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdF0gfTtcbiAgICAgICAgY29uc3Qgbm9jayA9IGF3YWl0IG5vY2tHZXRUeFJlcXVlc3QoeyB3YWxsZXRJZDogd2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlc3BvbnNlIH0pO1xuICAgICAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgICAgIGNvbnN0IHNldFJlcXVlc3RUcmFjZXJTcHkgPSBzaW5vbi5zcHkoYml0Z28sICdzZXRSZXF1ZXN0VHJhY2VyJyk7XG4gICAgICAgIHNldFJlcXVlc3RUcmFjZXJTcHkud2l0aEFyZ3MocmVxSWQpO1xuICAgICAgICBjb25zdCB0eFJlcSA9IGF3YWl0IGdldFR4UmVxdWVzdChiaXRnbywgd2FsbGV0LmlkKCksIHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVxSWQpO1xuICAgICAgICB0eFJlcS5zaG91bGQuZGVlcEVxdWFsKHR4UmVxdWVzdCk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShzZXRSZXF1ZXN0VHJhY2VyU3B5KTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS5yZXN0b3JlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGVVc2VyVG9CaXRHb0dTaGFyZTonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gY3JlYXRlIGEgVXNlclRvQml0R28gR1NoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB1c2VyVG9CaXRnb0dTaGFyZSA9IGF3YWl0IGNyZWF0ZVVzZXJUb0JpdEdvR1NoYXJlKFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25TaGFyZSxcbiAgICAgICAgICB0eFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdIGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgICBiaXRnb1RvVXNlckNvbW1pdG1lbnRcbiAgICAgICAgKTtcbiAgICAgICAgdXNlclRvQml0Z29HU2hhcmUuc2hvdWxkLmRlZXBFcXVhbCh2YWxpZFVzZXJUb0JpdGdvR1NoYXJlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgd2hlbiBYU2hhcmUgZG9lc250IGJlbG9uZyB0byB0aGUgdXNlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFVzZXJTaWduU2hhcmUgPSBfLmNsb25lRGVlcCh2YWxpZFVzZXJTaWduU2hhcmUpO1xuICAgICAgICBpbnZhbGlkVXNlclNpZ25TaGFyZS54U2hhcmUuaSA9IDM7XG4gICAgICAgIGF3YWl0IGNyZWF0ZVVzZXJUb0JpdEdvR1NoYXJlKFxuICAgICAgICAgIGludmFsaWRVc2VyU2lnblNoYXJlLFxuICAgICAgICAgIHR4UmVxdWVzdC5zaWduYXR1cmVTaGFyZXNbMF0gYXMgU2lnbmF0dXJlU2hhcmVSZWNvcmQsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJhY2t1cFlTaGFyZSxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYml0Z29ZU2hhcmUsXG4gICAgICAgICAgc2lnbmFibGVQYXlsb2FkLFxuICAgICAgICAgIGJpdGdvVG9Vc2VyQ29tbWl0bWVudFxuICAgICAgICApLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQgWFNoYXJlLCBkb2VzbnQgYmVsb25nIHRvIHRoZSBVc2VyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gY29tbWl0bWVudCBpcyBpbnZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnZhbGlkQml0Z29Ub1VzZXJDb21taXRtZW50ID0gXy5jbG9uZURlZXAoYml0Z29Ub1VzZXJDb21taXRtZW50KTtcbiAgICAgICAgaW52YWxpZEJpdGdvVG9Vc2VyQ29tbWl0bWVudC5zaGFyZSA9ICdkZWFkYmVlZic7XG4gICAgICAgIGF3YWl0IGNyZWF0ZVVzZXJUb0JpdEdvR1NoYXJlKFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25TaGFyZSxcbiAgICAgICAgICB0eFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdIGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgICBpbnZhbGlkQml0Z29Ub1VzZXJDb21taXRtZW50XG4gICAgICAgICkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQ291bGQgbm90IHZlcmlmeSBvdGhlciBwbGF5ZXIgc2hhcmUnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgd2hlbiBSU2hhcmUgZG9lc250IGJlbG9uZyB0byBCaXRnbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZEJpdGdvUlNoYXJlID0gXy5jbG9uZURlZXAodHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlc1swXSk7XG4gICAgICAgIGludmFsaWRCaXRnb1JTaGFyZS5mcm9tID0gJ3VzZXInO1xuICAgICAgICBhd2FpdCBjcmVhdGVVc2VyVG9CaXRHb0dTaGFyZShcbiAgICAgICAgICB2YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgaW52YWxpZEJpdGdvUlNoYXJlIGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgICBiaXRnb1RvVXNlckNvbW1pdG1lbnRcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIFJTaGFyZSwgaXMgbm90IGZyb20gQml0Z28gdG8gVXNlcicpO1xuXG4gICAgICAgIGNvbnN0IGludmFsaWRCaXRnb1JTaGFyZTIgPSBfLmNsb25lRGVlcCh0eFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdKTtcbiAgICAgICAgaW52YWxpZEJpdGdvUlNoYXJlMi50byA9ICdiaXRnbyc7XG4gICAgICAgIGF3YWl0IGNyZWF0ZVVzZXJUb0JpdEdvR1NoYXJlKFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25TaGFyZSxcbiAgICAgICAgICBpbnZhbGlkQml0Z29SU2hhcmUyIGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgICBiaXRnb1RvVXNlckNvbW1pdG1lbnRcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIFJTaGFyZSwgaXMgbm90IGZyb20gQml0Z28gdG8gVXNlcicpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!