bitgo
Version:
BitGo JavaScript SDK
1,087 lines • 160 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const sdk_test_1 = require("@bitgo/sdk-test");
const nock = require("nock");
const sdk_core_1 = require("@bitgo/sdk-core");
const abstract_lightning_1 = require("@bitgo/abstract-lightning");
const src_1 = require("../../../../src");
describe('Lightning wallets', function () {
const coinName = 'tlnbtc';
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
let basecoin;
let wallets;
let bgUrl;
const userAuthKey = {
id: 'def',
pub: 'xpub661MyMwAqRbcGYjYsnsDj1SHdiXynWEXNnfNgMSpokN54FKyMqbu7rWEfVNDs6uAJmz86UVFtq4sefhQpXZhSAzQcL9zrEPtiLNNZoeSxCG',
encryptedPrv: '{"iv":"zYhhaNdW0wPfJEoBjZ4pvg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"tgAMua9jjhw=","ct":"HcrbxQvNlWG5tLMndYzdNCYa1l+1h7o+vSsweA0+q1le3tWt6jLUJSEjZN+JI8lTZ2KPFQgLulQQhsUa+ytUCBi0vSgjF7x7CprT7l2Cfjkew00XsEd7wnmtJUsrQk8m69Co7tIRA3oEgzrnYwy4qOM81lbNNyQ="}',
source: 'user',
coinSpecific: {
tlnbtc: {
purpose: 'userAuth',
},
},
};
const nodeAuthKey = {
id: 'ghi',
pub: 'xpub661MyMwAqRbcG9xnTnAnRbJPo3MAHyRtH4zeehN8exYk4VFz5buepUzebhix33BKhS5Eb4V3LEfW5pYiSR8qmaEnyrpeghhKY8JfzAsUDpq',
encryptedPrv: '{"iv":"bH6eGbnl9x8PZECPrgvcng==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"o8yknV6nTI8=","ct":"nGyzAToIzYkQeIdcVafoWHtMx7+Fgj0YldCme3WA1yxJAA0QulZVhblMZN/7efCRIumA0NNmpH7dxH6n8cVlz/Z+RUgC2q9lgvZKUoJcYNTjWUfkmkJutXX2tr8yVxm+eC/hnRiyfVLZ2qPxctvDlBVBfgLuPyc="}',
source: 'user',
coinSpecific: {
tlnbtc: {
purpose: 'nodeAuth',
},
},
};
before(function () {
bitgo.initializeTestVars();
basecoin = bitgo.coin(coinName);
wallets = basecoin.wallets();
bgUrl = src_1.common.Environments[bitgo.getEnv()].uri;
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
describe('Generate lightning wallet', function () {
it('should validate parameters', async function () {
await wallets
.generateWallet({
passphrase: 'pass123',
enterprise: 'ent123',
passcodeEncryptionCode: 'code123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value 'undefined' supplied to GenerateLightningWalletOptions.label, expected string.");
await wallets
.generateWallet({
label: 'my ln wallet',
enterprise: 'ent123',
passcodeEncryptionCode: 'code123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value 'undefined' supplied to GenerateLightningWalletOptions.passphrase, expected string.");
await wallets
.generateWallet({
label: 'my ln wallet',
passphrase: 'pass123',
passcodeEncryptionCode: 'code123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value 'undefined' supplied to GenerateLightningWalletOptions.enterprise, expected string.");
await wallets
.generateWallet({
label: 'my ln wallet',
passphrase: 'pass123',
enterprise: 'ent123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value 'undefined' supplied to GenerateLightningWalletOptions.passcodeEncryptionCode, expected string.");
await wallets
.generateWallet({
label: 123,
passphrase: 'pass123',
enterprise: 'ent123',
passcodeEncryptionCode: 'code123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value '123' supplied to GenerateLightningWalletOptions.label, expected string.");
await wallets
.generateWallet({
label: 'my ln wallet',
passphrase: 123,
enterprise: 'ent123',
passcodeEncryptionCode: 'code123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value '123' supplied to GenerateLightningWalletOptions.passphrase, expected string.");
await wallets
.generateWallet({
label: 'my ln wallet',
passphrase: 'pass123',
enterprise: 123,
passcodeEncryptionCode: 'code123',
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value '123' supplied to GenerateLightningWalletOptions.enterprise, expected string.");
await wallets
.generateWallet({
label: 'my ln wallet',
passphrase: 'pass123',
enterprise: 'ent123',
passcodeEncryptionCode: 123,
subType: 'lightningCustody',
})
.should.be.rejectedWith("error(s) parsing generate lightning wallet request params: Invalid value '123' supplied to GenerateLightningWalletOptions.passcodeEncryptionCode, expected string.");
});
for (const subType of ['lightningCustody', 'lightningSelfCustody']) {
it(`should generate ${subType} lightning wallet`, async function () {
const params = {
label: 'my ln wallet',
passphrase: 'pass123',
enterprise: 'ent123',
passcodeEncryptionCode: 'code123',
subType: subType,
};
const validateKeyRequest = (body) => {
const baseChecks = body.pub.startsWith('xpub') &&
!!body.encryptedPrv &&
body.keyType === 'independent' &&
body.source === 'user';
if (body.originalPasscodeEncryptionCode !== undefined) {
return baseChecks && body.originalPasscodeEncryptionCode === 'code123' && body.coinSpecific === undefined;
}
else {
const coinSpecific = body.coinSpecific && body.coinSpecific.tlnbtc;
return baseChecks && !!coinSpecific && ['userAuth', 'nodeAuth'].includes(coinSpecific.purpose);
}
};
const validateWalletRequest = (body) => {
return (body.label === 'my ln wallet' &&
body.m === 1 &&
body.n === 1 &&
body.type === 'hot' &&
body.subType === subType &&
body.enterprise === 'ent123' &&
Array.isArray(body.keys) &&
body.keys.length === 1 &&
body.keys[0] === 'keyId1' &&
body.coinSpecific &&
body.coinSpecific.tlnbtc &&
Array.isArray(body.coinSpecific.tlnbtc.keys) &&
body.coinSpecific.tlnbtc.keys.length === 2 &&
body.coinSpecific.tlnbtc.keys.includes('keyId2') &&
body.coinSpecific.tlnbtc.keys.includes('keyId3'));
};
nock(bgUrl)
.post('/api/v2/' + coinName + '/key', (body) => validateKeyRequest(body))
.reply(200, { id: 'keyId1' });
nock(bgUrl)
.post('/api/v2/' + coinName + '/key', (body) => validateKeyRequest(body))
.reply(200, { id: 'keyId2' });
nock(bgUrl)
.post('/api/v2/' + coinName + '/key', (body) => validateKeyRequest(body))
.reply(200, { id: 'keyId3' });
nock(bgUrl)
.post('/api/v2/' + coinName + '/wallet/add', (body) => validateWalletRequest(body))
.reply(200, { id: 'walletId' });
const response = await wallets.generateWallet(params);
assert.ok(response.wallet);
assert.ok(response.encryptedWalletPassphrase);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
}
});
describe('invoices', function () {
let wallet;
beforeEach(function () {
wallet = (0, abstract_lightning_1.getLightningWallet)(new src_1.Wallet(bitgo, basecoin, {
id: 'walletId',
coin: 'tlnbtc',
subType: 'lightningCustody',
coinSpecific: { keys: ['def', 'ghi'] },
}));
});
it('should list invoices', async function () {
const invoice = {
valueMsat: 1000n,
paymentHash: 'foo',
invoice: 'tlnfoobar',
walletId: wallet.wallet.id(),
status: 'open',
expiresAt: new Date(),
createdAt: new Date(),
updatedAt: new Date(),
};
const query = {
status: 'open',
startDate: new Date(),
limit: 100n,
};
const listInvoicesNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`)
.query(abstract_lightning_1.InvoiceQuery.encode(query))
.reply(200, { invoices: [abstract_lightning_1.Invoice.encode(invoice)] });
const invoiceResponse = await wallet.listInvoices(query);
assert.strictEqual(invoiceResponse.invoices.length, 1);
assert.deepStrictEqual(invoiceResponse.invoices[0], invoice);
listInvoicesNock.done();
});
it('should work properly with pagination while listing invoices', async function () {
const invoice1 = {
valueMsat: 1000n,
paymentHash: 'foo1',
invoice: 'tlnfoobar1',
walletId: wallet.wallet.id(),
status: 'open',
expiresAt: new Date(),
createdAt: new Date(),
updatedAt: new Date(),
};
const invoice2 = {
...invoice1,
paymentHash: 'foo2',
invoice: 'tlnfoobar2',
};
const invoice3 = {
...invoice1,
paymentHash: 'foo3',
invoice: 'tlnfoobar3',
};
const allInvoices = [abstract_lightning_1.Invoice.encode(invoice1), abstract_lightning_1.Invoice.encode(invoice2), abstract_lightning_1.Invoice.encode(invoice3)];
const query = {
status: 'open',
startDate: new Date(),
limit: 2n,
};
const listInvoicesNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`)
.query(abstract_lightning_1.InvoiceQuery.encode(query))
.reply(200, { invoices: allInvoices.slice(0, 2), nextBatchPrevId: invoice2.paymentHash });
const invoiceResponse = await wallet.listInvoices(query);
assert.strictEqual(invoiceResponse.invoices.length, 2);
assert.deepStrictEqual(invoiceResponse.invoices[0], invoice1);
assert.deepStrictEqual(invoiceResponse.invoices[1], invoice2);
assert.strictEqual(invoiceResponse.nextBatchPrevId, invoice2.paymentHash);
listInvoicesNock.done();
});
it('listInvoices should throw error if wp response is invalid', async function () {
const listInvoicesNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`)
.reply(200, { invoices: [{ valueMsat: '1000' }] });
await assert.rejects(async () => await wallet.listInvoices({}), /Invalid list invoices response/);
listInvoicesNock.done();
});
it('should create invoice', async function () {
const createInvoice = {
valueMsat: 1000n,
memo: 'test invoice',
expiry: 100,
};
const invoice = {
invoice: 'tlnabc',
paymentHash: '123',
expiresAt: new Date(),
status: 'open',
walletId: wallet.wallet.id(),
valueMsat: 1000n,
createdAt: new Date(),
updatedAt: new Date(),
memo: 'test invoice',
};
const createInvoiceNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`, abstract_lightning_1.CreateInvoiceBody.encode(createInvoice))
.reply(200, abstract_lightning_1.Invoice.encode(invoice));
const createInvoiceResponse = await wallet.createInvoice(createInvoice);
assert.deepStrictEqual(createInvoiceResponse, invoice);
createInvoiceNock.done();
});
it('createInvoice should throw error if wp response is invalid', async function () {
const createInvoice = {
valueMsat: 1000n,
memo: 'test invoice',
expiry: 100,
};
const createInvoiceNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/lightning/invoice`)
.reply(200, { valueMsat: '1000' });
await assert.rejects(async () => await wallet.createInvoice(createInvoice), /Invalid create invoice response/);
createInvoiceNock.done();
});
it('should pay invoice', async function () {
const params = {
invoice: 'lnbc1...',
amountMsat: 1000n,
feeLimitMsat: 100n,
feeLimitRatio: 0.1,
sequenceId: '123',
comment: 'test payment',
passphrase: 'password123',
};
const txRequestResponse = {
txRequestId: 'txReq123',
state: 'delivered',
};
const lndResponse = {
status: 'settled',
paymentHash: 'paymentHash123',
amountMsat: params.amountMsat !== undefined ? params.amountMsat.toString() : undefined,
feeMsat: params.feeLimitMsat !== undefined ? params.feeLimitMsat.toString() : undefined,
paymentPreimage: 'preimage123',
};
const finalPaymentResponse = {
txRequestId: 'txReq123',
state: 'delivered',
transactions: [
{
unsignedTx: {
coinSpecific: {
...lndResponse,
},
},
},
],
};
const createTransferData = {
id: 'fake_id',
coin: 'tlnbtc',
state: 'initialized',
};
const createTxRequestNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests`)
.reply(200, txRequestResponse);
const createTransferNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests/${txRequestResponse.txRequestId}/transfers`)
.reply(200, createTransferData);
const sendTxRequestNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests/${txRequestResponse.txRequestId}/transactions/0/send`)
.reply(200, finalPaymentResponse);
const userAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, userAuthKey);
const nodeAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKey);
const response = await wallet.payInvoice(params);
assert.strictEqual(response.txRequestId, 'txReq123');
assert.strictEqual(response.txRequestState, 'delivered');
assert.ok(response.paymentStatus);
assert.strictEqual(response.paymentStatus.status, finalPaymentResponse.transactions[0].unsignedTx.coinSpecific.status);
assert.strictEqual(response.paymentStatus.paymentHash, finalPaymentResponse.transactions[0].unsignedTx.coinSpecific.paymentHash);
assert.strictEqual(response.paymentStatus.amountMsat, finalPaymentResponse.transactions[0].unsignedTx.coinSpecific.amountMsat);
assert.strictEqual(response.paymentStatus.feeMsat, finalPaymentResponse.transactions[0].unsignedTx.coinSpecific.feeMsat);
assert.strictEqual(response.paymentStatus.paymentPreimage, finalPaymentResponse.transactions[0].unsignedTx.coinSpecific.paymentPreimage);
createTxRequestNock.done();
sendTxRequestNock.done();
createTransferNock.done();
userAuthKeyNock.done();
nodeAuthKeyNock.done();
});
it('should handle pending approval when paying invoice', async function () {
const params = {
invoice: 'lnbc1...',
amountMsat: 1000n,
feeLimitMsat: 100n,
feeLimitRatio: 0.1,
sequenceId: '123',
comment: 'test payment',
passphrase: 'password123',
};
const txRequestResponse = {
txRequestId: 'txReq123',
state: 'pendingApproval',
pendingApprovalId: 'approval123',
};
const pendingApprovalData = {
id: 'approval123',
state: sdk_core_1.State.PENDING,
creator: 'user123',
info: {
type: sdk_core_1.Type.TRANSACTION_REQUEST,
},
};
const createTxRequestNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests`)
.reply(200, txRequestResponse);
const getPendingApprovalNock = nock(bgUrl)
.get(`/api/v2/${coinName}/pendingapprovals/${txRequestResponse.pendingApprovalId}`)
.reply(200, pendingApprovalData);
const userAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, userAuthKey);
const nodeAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKey);
const response = await wallet.payInvoice(params);
assert.strictEqual(response.txRequestId, 'txReq123');
assert.strictEqual(response.txRequestState, 'pendingApproval');
assert.ok(response.pendingApproval);
assert.strictEqual(response.paymentStatus, undefined);
createTxRequestNock.done();
getPendingApprovalNock.done();
userAuthKeyNock.done();
nodeAuthKeyNock.done();
});
});
describe('payments', function () {
let wallet;
beforeEach(function () {
wallet = (0, abstract_lightning_1.getLightningWallet)(new src_1.Wallet(bitgo, basecoin, {
id: 'walletId',
coin: 'tlnbtc',
subType: 'lightningCustody',
coinSpecific: { keys: ['def', 'ghi'] },
}));
});
it('should get payments', async function () {
const payment = {
id: '8308fddb-2356-49aa-8548-10c23099854c',
paymentHash: 'foo',
walletId: wallet.wallet.id(),
txRequestId: 'txReqId',
status: 'settled',
invoice: 'tlnfoobar',
destination: 'destination',
feeLimitMsat: 100n,
amountMsat: 1000n,
createdAt: new Date(),
updatedAt: new Date(),
};
const query = {
status: 'settled',
startDate: new Date(),
limit: 100n,
};
const listPaymentsNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/payment`)
.query(abstract_lightning_1.PaymentQuery.encode(query))
.reply(200, { payments: [abstract_lightning_1.PaymentInfo.encode(payment)] });
const listPaymentsResponse = await wallet.listPayments(query);
assert.strictEqual(listPaymentsResponse.payments.length, 1);
assert.deepStrictEqual(listPaymentsResponse.payments[0], payment);
listPaymentsNock.done();
});
it('should work properly with pagination while listing payments', async function () {
const payment1 = {
id: '8308fddb-2356-49aa-8548-10c23099854c',
paymentHash: 'foo1',
walletId: wallet.wallet.id(),
txRequestId: 'txReqId1',
status: 'settled',
invoice: 'tlnfoobar1',
destination: 'destination',
feeLimitMsat: 100n,
amountMsat: 1000n,
createdAt: new Date(),
updatedAt: new Date(),
};
const payment2 = {
...payment1,
id: '8308fddb-2356-49aa-8548-10c23099854d',
paymentHash: 'foo2',
txRequestId: 'txReqId2',
invoice: 'tlnfoobar2',
};
const payment3 = {
...payment1,
id: '8308fddb-2356-49aa-8548-10c23099854e',
paymentHash: 'foo3',
txRequestId: 'txReqId3',
invoice: 'tlnfoobar3',
};
const allPayments = [abstract_lightning_1.PaymentInfo.encode(payment1), abstract_lightning_1.PaymentInfo.encode(payment2), abstract_lightning_1.PaymentInfo.encode(payment3)];
const query = {
status: 'settled',
startDate: new Date(),
limit: 2n,
};
const listPaymentsNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/payment`)
.query(abstract_lightning_1.PaymentQuery.encode(query))
.reply(200, { payments: allPayments.slice(0, 2), nextBatchPrevId: payment2.paymentHash });
const listPaymentsResponse = await wallet.listPayments(query);
assert.strictEqual(listPaymentsResponse.payments.length, 2);
assert.deepStrictEqual(listPaymentsResponse.payments[0], payment1);
assert.deepStrictEqual(listPaymentsResponse.payments[1], payment2);
assert.strictEqual(listPaymentsResponse.nextBatchPrevId, payment2.paymentHash);
listPaymentsNock.done();
});
it('listPayments should throw error if wp response is invalid', async function () {
const listPaymentsNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/payment`)
.reply(200, { payments: [{ amountMsat: '1000' }] });
await assert.rejects(async () => await wallet.listPayments({}), /Invalid payment list response/);
listPaymentsNock.done();
});
});
describe('Get lightning key(s)', function () {
const walletData = {
id: 'fakeid',
coin: coinName,
keys: ['abc'],
coinSpecific: { keys: ['def', 'ghi'] },
subType: 'lightningCustody',
};
const userKeyData = {
id: 'abc',
pub: 'xpub1',
encryptedPrv: 'encryptedPrv1',
source: 'user',
};
const userAuthKeyData = {
id: 'def',
pub: 'xpub2',
encryptedPrv: 'encryptedPrv2',
source: 'user',
coinSpecific: {
tlnbtc: {
purpose: 'userAuth',
},
},
};
const nodeAuthKeyData = {
id: 'ghi',
pub: 'xpub3',
encryptedPrv: 'encryptedPrv3',
source: 'user',
coinSpecific: {
tlnbtc: {
purpose: 'nodeAuth',
},
},
};
it('should get lightning key', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, walletData);
const keyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/abc')
.reply(200, userKeyData);
const key = await (0, abstract_lightning_1.getLightningKeychain)(wallet);
assert.deepStrictEqual(key, userKeyData);
keyNock.done();
});
it('should get lightning auth keys', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, walletData);
const userAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, userAuthKeyData);
const nodeAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKeyData);
const { userAuthKey, nodeAuthKey } = await (0, abstract_lightning_1.getLightningAuthKeychains)(wallet);
assert.deepStrictEqual(userAuthKey, userAuthKeyData);
assert.deepStrictEqual(nodeAuthKey, nodeAuthKeyData);
userAuthKeyNock.done();
nodeAuthKeyNock.done();
});
it('should fail to get lightning key for invalid number of keys', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, { ...walletData, keys: [] });
await assert.rejects(async () => await (0, abstract_lightning_1.getLightningKeychain)(wallet), /Error: Invalid number of key in lightning wallet: 0/);
});
it('should fail to get lightning auth keys for invalid number of keys', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, { ...walletData, coinSpecific: { keys: ['def'] } });
await assert.rejects(async () => await (0, abstract_lightning_1.getLightningAuthKeychains)(wallet), /Error: Invalid number of auth keys in lightning wallet: 1/);
});
it('should fail to get lightning key for invalid response', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, walletData);
nock(bgUrl)
.get('/api/v2/' + coinName + '/key/abc')
.reply(200, { ...userKeyData, source: 'backup' });
await assert.rejects(async () => await (0, abstract_lightning_1.getLightningKeychain)(wallet), /Error: Invalid user key/);
});
it('should fail to get lightning auth keys for invalid response', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, walletData);
nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, { ...userAuthKeyData, source: 'backup' });
nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKeyData);
await assert.rejects(async () => await (0, abstract_lightning_1.getLightningAuthKeychains)(wallet), /Error: Invalid lightning auth key: def/);
});
});
describe('Update lightning wallet coin specific', function () {
const walletData = {
id: 'fakeid',
coin: coinName,
keys: ['abc'],
coinSpecific: { keys: ['def', 'ghi'] },
subType: 'lightningSelfCustody',
};
const watchOnlyAccounts = {
master_key_birthday_timestamp: 'dummy',
master_key_fingerprint: 'dummy',
accounts: [
{
xpub: 'upub5Eep7H5q39PzQZLVEYLBytDyBNeV74E8mQsyeL6UozFq9Y3MsZ52G7YGuqrJPgoyAqF7TBeJdnkrHrVrB5pkWkPJ9cJGAePMU6F1Gyw6aFH',
purpose: 49,
coin_type: 0,
account: 0,
},
{
xpub: 'vpub5ZU1PHGpQoDSHckYico4nsvwsD3mTh6UjqL5zyGWXZXzBjTYMNKot7t9eRPQY71hJcnNN9r1ss25g3xA9rmoJ5nWPg8jEWavrttnsVa1qw1',
purpose: 84,
coin_type: 0,
account: 0,
},
],
};
it('should update wallet', async function () {
const wallet = new src_1.Wallet(bitgo, basecoin, walletData);
const userAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, userAuthKey);
const nodeAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKey);
let capturedBody;
const wpWalletUpdateNock = nock(bgUrl)
.put(`/api/v2/tlnbtc/wallet/${walletData.id}`)
.reply(function (uri, requestBody) {
capturedBody = requestBody;
return [200];
});
const params = {
signerMacaroon: 'signerMacaroon',
signerAdminMacaroon: 'signerAdminMacaroon',
signerTlsKey: 'signerTlsKey',
signerTlsCert: 'signerTlsCert',
watchOnlyAccounts,
passphrase: 'password123',
};
await assert.doesNotReject(async () => await (0, abstract_lightning_1.updateWalletCoinSpecific)(wallet, params));
assert.ok(userAuthKeyNock.isDone());
assert.ok(nodeAuthKeyNock.isDone());
assert.ok(wpWalletUpdateNock.isDone());
// Verify structure and required fields
assert.ok(capturedBody.coinSpecific?.tlnbtc?.signedRequest, 'signedRequest should exist');
const signedRequest = capturedBody.coinSpecific.tlnbtc.signedRequest;
assert.ok(signedRequest.signerTlsCert, 'signerTlsCert should exist');
assert.ok(signedRequest.watchOnlyAccounts, 'watchOnlyAccounts should exist');
assert.ok(signedRequest.encryptedSignerTlsKey, 'encryptedSignerTlsKey should exist');
assert.ok(signedRequest.encryptedSignerAdminMacaroon, 'encryptedSignerAdminMacaroon should exist');
assert.ok(signedRequest.encryptedSignerMacaroon, 'encryptedSignerMacaroon should exist');
// Verify signature exists
assert.ok(capturedBody.coinSpecific.tlnbtc.signature, 'signature should exist');
// we should not pass passphrase to the backend
assert.strictEqual(signedRequest.passphrase, undefined, 'passphrase should not exist in request');
});
});
describe('On chain withdrawal', function () {
let wallet;
beforeEach(function () {
const watchOnlyAccounts = {
master_key_birthday_timestamp: 'dummy',
master_key_fingerprint: 'dummy',
accounts: [
{
xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA',
purpose: 49,
coin_type: 0,
account: 0,
},
{
xpub: 'tpubDCFN7bsxR9UTKggdH2pmv5HeHGQNiDrJwa1EZFtP9sH5PF28i37FHpoYSYARQkKZ6Mi98pkp7oypDcxFmE4dQGq8jV8Gv3L6gmWBeRwPxkP',
purpose: 84,
coin_type: 0,
account: 0,
},
],
};
wallet = (0, abstract_lightning_1.getLightningWallet)(new src_1.Wallet(bitgo, basecoin, {
id: 'walletId',
coin: 'tlnbtc',
subType: 'lightningCustody',
coinSpecific: { keys: ['def', 'ghi'], watchOnlyAccounts },
}));
});
it('should withdraw on chain', async function () {
const params = {
recipients: [
{
amountSat: 100000n,
address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k',
},
],
satsPerVbyte: 15n,
passphrase: 'password123',
};
const unsignedPsbtHex = '70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000';
const txRequestResponse = {
txRequestId: 'txReq123',
state: 'pendingDelivery',
transactions: [
{
unsignedTx: {
serializedTxHex: unsignedPsbtHex,
},
},
],
};
const txRequestWithSignatureResponse = {
txRequestId: 'txReq123',
state: 'pendingDelivery',
transactions: [
{
unsignedTx: {
serializedTxHex: unsignedPsbtHex,
coinSpecific: {
signature: 'someSignature',
},
},
},
],
};
const finalWithdrawResponse = {
txRequestId: 'txReq123',
state: 'delivered',
transactions: [
{
unsignedTx: {
serializedTxHex: unsignedPsbtHex,
coinSpecific: {
signature: 'someSignature',
status: 'delivered',
txid: 'tx123',
},
},
},
],
};
const transferResponse = {
entries: [
{
address: 'tb1qr54zqkf0sjwdycygulkcuw0audm8n6r77xj3q6',
wallet: '6846918381f118cc42c335b037929665',
value: -1000000,
valueString: '-1000000',
},
{
address: 'tb1qmddle8nhnjcv93t0qnr2tmhvvxfem4ppxq4rzc',
value: 498590,
valueString: '498590',
isChange: true,
isPayGo: false,
},
{
address: 'tb1qjq48cqk2u80hewdcndf539m8nnnvt8453kr23h',
value: 500000,
valueString: '500000',
isChange: false,
isPayGo: false,
},
],
id: '6846918481f118cc42c33611410906e5',
coin: 'tlnbtc',
wallet: 'walletId',
walletType: 'hot',
enterprise: '6846918381f118cc42c3354ff05d72d8',
organization: '6846918381f118cc42c3355f6807d11e',
txidType: 'transactionHash',
txRequestId: 'txReq123',
height: 999999999,
heightId: '999999999-6846918481f118cc42c33611410906e5',
date: '2025-06-09T07:47:16.090Z',
type: 'send',
value: -1000000,
valueString: '-1000000',
intendedValueString: '-1000000',
baseValue: -998590,
baseValueString: '-998590',
baseValueWithoutFees: -998590,
baseValueWithoutFeesString: '-998590',
feeString: '1410',
payGoFee: 0,
payGoFeeString: '0',
usd: -1.23456,
usdRate: 123456,
state: 'initialized',
instant: false,
isReward: false,
isUnlock: false,
isFee: false,
senderInformationVerified: false,
tags: ['6846918381f118cc42c335b037929665', '6846918381f118cc42c3354ff05d72d8'],
history: [
{
date: '2025-06-09T07:47:16.102Z',
user: '6846918281f118cc42c33352779df88f',
action: 'created',
},
],
coinSpecific: {
isOffchain: false,
},
metadata: [],
createdTime: '2025-06-09T07:47:16.102Z',
};
const createTxRequestNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests`)
.reply(200, txRequestResponse);
const storeSignatureNock = nock(bgUrl)
.put(`/api/v2/wallet/${wallet.wallet.id()}/txrequests/${txRequestResponse.txRequestId}/coinSpecific`)
.reply(200, txRequestWithSignatureResponse);
const createTransferNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests/${txRequestResponse.txRequestId}/transfers`)
.reply(200, transferResponse);
const sendTxRequestNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests/${txRequestResponse.txRequestId}/transactions/0/send`)
.reply(200, finalWithdrawResponse);
const userAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, userAuthKey);
const nodeAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKey);
const response = await wallet.withdrawOnchain(params);
assert.strictEqual(response.txRequestId, 'txReq123');
assert.strictEqual(response.txRequestState, 'delivered');
assert.strictEqual(response.withdrawStatus?.status, 'delivered');
assert.strictEqual(response.withdrawStatus?.txid, 'tx123');
assert.strictEqual(response.withdrawStatus.signature, undefined);
userAuthKeyNock.done();
nodeAuthKeyNock.done();
createTxRequestNock.done();
storeSignatureNock.done();
createTransferNock.done();
sendTxRequestNock.done();
});
it('should handle pending approval when withdrawing onchain', async function () {
const params = {
recipients: [
{
amountSat: 100000n,
address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k',
},
],
satsPerVbyte: 15n,
passphrase: 'password123',
};
const unsignedPsbtHex = '70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000';
const txRequestResponse = {
txRequestId: 'txReq123',
state: 'pendingApproval',
pendingApprovalId: 'approval123',
transactions: [
{
unsignedTx: {
serializedTxHex: unsignedPsbtHex,
},
},
],
};
const txRequestWithSignatureResponse = {
txRequestId: 'txReq123',
state: 'pendingApproval',
pendingApprovalId: 'approval123',
transactions: [
{
unsignedTx: {
serializedTxHex: unsignedPsbtHex,
coinSpecific: {
signature: 'someSignature',
},
},
},
],
};
const pendingApprovalData = {
id: 'approval123',
state: sdk_core_1.State.PENDING,
creator: 'user123',
info: {
type: sdk_core_1.Type.TRANSACTION_REQUEST,
},
};
const createTxRequestNock = nock(bgUrl)
.post(`/api/v2/wallet/${wallet.wallet.id()}/txrequests`)
.reply(200, txRequestResponse);
const getPendingApprovalNock = nock(bgUrl)
.get(`/api/v2/${coinName}/pendingapprovals/${txRequestResponse.pendingApprovalId}`)
.reply(200, pendingApprovalData);
const userAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/def')
.reply(200, userAuthKey);
const nodeAuthKeyNock = nock(bgUrl)
.get('/api/v2/' + coinName + '/key/ghi')
.reply(200, nodeAuthKey);
const storeSignatureNock = nock(bgUrl)
.put(`/api/v2/wallet/${wallet.wallet.id()}/txrequests/${txRequestResponse.txRequestId}/coinSpecific`)
.reply(200, txRequestWithSignatureResponse);
const response = await wallet.withdrawOnchain(params);
assert.strictEqual(response.txRequestId, 'txReq123');
assert.strictEqual(response.txRequestState, 'pendingApproval');
assert.ok(response.pendingApproval);
userAuthKeyNock.done();
nodeAuthKeyNock.done();
storeSignatureNock.done();
createTxRequestNock.done();
getPendingApprovalNock.done();
});
});
describe('transactions', function () {
let wallet;
beforeEach(function () {
wallet = (0, abstract_lightning_1.getLightningWallet)(new src_1.Wallet(bitgo, basecoin, {
id: 'walletId',
coin: 'tlnbtc',
subType: 'lightningCustody',
coinSpecific: { keys: ['def', 'ghi'] },
}));
});
it('should list transactions', async function () {
const transaction = {
id: 'tx123',
normalizedTxHash: 'normalizedHash123',
blockHeight: 100000,
inputIds: ['input1', 'input2'],
entries: [
{
inputs: 1,
outputs: 2,
value: 50000,
valueString: '50000',
address: 'testAddress',
wallet: wallet.wallet.id(),
},
],
inputs: [
{
id: 'input1',
value: 50000,
valueString: '50000',
address: 'inputAddress',
wallet: wallet.wallet.id(),
},
],
outputs: [
{
id: 'output1',
value: 49500,
valueString: '49500',
address: 'outputAddress',
wallet: wallet.wallet.id(),
},
],
size: 250,
date: new Date('2023-01-01T00:00:00Z'),
fee: 500,
feeString: '500',
hex: 'deadbeef',
confirmations: 6,
};
const query = {
limit: 100n,
startDate: new Date(),
};
const listTransactionsNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/transaction`)
.query(abstract_lightning_1.TransactionQuery.encode(query))
.reply(200, { transactions: [transaction] });
const listTransactionsResponse = await wallet.listTransactions(query);
assert.strictEqual(listTransactionsResponse.transactions.length, 1);
assert.deepStrictEqual(listTransactionsResponse.transactions[0], transaction);
assert.strictEqual(listTransactionsResponse.nextBatchPrevId, undefined);
listTransactionsNock.done();
});
it('should work properly with pagination while listing transactions', async function () {
const transaction1 = {
id: 'tx123',
normalizedTxHash: 'normalizedHash123',
blockHeight: 100000,
inputIds: ['input1', 'input2'],
entries: [
{
inputs: 1,
outputs: 2,
value: 50000,
valueString: '50000',
address: 'testAddress',
wallet: wallet.wallet.id(),
},
],
inputs: [
{
id: 'input1',
value: 50000,
valueString: '50000',
address: 'inputAddress',
wallet: wallet.wallet.id(),
},
],
outputs: [
{
id: 'output1',
value: 49500,
valueString: '49500',
address: 'outputAddress',
wallet: wallet.wallet.id(),
},
],
size: 250,
date: new Date('2023-01-01T00:00:00Z'),
fee: 500,
feeString: '500',
hex: 'deadbeef',
confirmations: 6,
};
const transaction2 = {
...transaction1,
id: 'tx456',
normalizedTxHash: 'normalizedHash456',
blockHeight: 100001,
date: new Date('2023-01-02T00:00:00Z'),
};
const query = {
limit: 2n,
startDate: new Date('2023-01-01'),
};
const listTransactionsNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/transaction`)
.query(abstract_lightning_1.TransactionQuery.encode(query))
.reply(200, { transactions: [transaction1, transaction2], nextBatchPrevId: transaction2.id });
const listTransactionsResponse = await wallet.listTransactions(query);
assert.strictEqual(listTransactionsResponse.transactions.length, 2);
assert.deepStrictEqual(listTransactionsResponse.transactions[0], transaction1);
assert.deepStrictEqual(listTransactionsResponse.transactions[1], transaction2);
assert.strictEqual(listTransactionsResponse.nextBatchPrevId, transaction2.id);
listTransactionsNock.done();
});
it('should handle prevId parameter for pagination cursor', async function () {
const transaction3 = {
id: 'tx789',
normalizedTxHash: 'normalizedHash789',
blockHeight: 100002,
inputIds: ['input1'],
entries: [
{
inputs: 1,
outputs: 1,
value: 40000,
valueString: '40000',
address: 'testAddress',
wallet: wallet.wallet.id(),
},
],
inputs: [
{
id: 'input1',
value: 40000,
valueString: '40000',
address: 'inputAddress',
wallet: wallet.wallet.id(),
},
],
outputs: [
{
id: 'output1',
value: 39500,
valueString: '39500',
address: 'outputAddress',
wallet: wallet.wallet.id(),
},
],
size: 200,
date: new Date('2023-01-03T00:00:00Z'),
fee: 500,
feeString: '500',
hex: 'cafebabe',
confirmations: 4,
};
const query = {
limit: 1n,
prevId: 'tx456', // Continue from this transaction ID
};
const listTransactionsNock = nock(bgUrl)
.get(`/api/v2/wallet/${wallet.wallet.id()}/lightning/transaction`)
.query(abstract_lightning_1.TransactionQuery.encode(query))
.reply(200, { transactions: [transaction3] });
const listTransactionsResponse = await wallet.listTransactions(query);
assert.strictEqual(listTransactionsResponse.transactions.length, 1);
assert.deepStrictEqual(listTransactionsResponse.transactions[0], transaction3);
assert.strictEqual(listTransactionsResponse.nextBatchPrevId, undefined);
listTransactionsNock.done();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nV2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC9saWdodG5pbmcvbGlnaHRuaW5nV2FsbGV0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlDQUFpQztBQUNqQyw4Q0FBNEM7QUFDNUMsNkJBQThCO0FBQzlCLDhDQUE2RTtBQUM3RSxrRUFnQm1DO0FBRW5DLHlDQUFpRztBQUVqRyxRQUFRLENBQUMsbUJBQW1CLEVBQUU7SUFDNUIsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzFCLE1BQU0sS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLFdBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELElBQUksUUFBa0IsQ0FBQztJQUN2QixJQUFJLE9BQWdCLENBQUM7SUFDckIsSUFBSSxLQUFhLENBQUM7SUFFbEIsTUFBTSxXQUFXLEdBQUc7UUFDbEIsRUFBRSxFQUFFLEtBQUs7UUFDVCxHQUFHLEVBQUUsaUhBQWlIO1FBQ3RILFlBQVksRUFDViw0U0FBNFM7UUFDOVMsTUFBTSxFQUFFLE1BQU07UUFDZCxZQUFZLEVBQUU7WUFDWixNQUFNLEVBQUU7Z0JBQ04sT0FBTyxFQUFFLFVBQVU7YUFDcEI7U0FDRjtLQUNGLENBQUM7SUFFRixNQUFNLFdBQVcsR0FBRztRQUNsQixFQUFFLEVBQUUsS0FBSztRQUNULEdBQUcsRUFBRSxpSEFBaUg7UUFDdEgsWUFBWSxFQUNWLDRTQUE0UztRQUM5UyxNQUFNLEVBQUUsTUFBTTtRQUNkLFlBQVksRUFBRTtZQUNaLE1BQU0sRUFBRTtnQkFDTixPQUFPLEVBQUUsVUFBVTthQUNwQjtTQUNGO0tBQ0YsQ0FBQztJQUVGLE1BQU0sQ0FBQztRQUNMLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBRTNCLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFD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QUksRUFBRSxJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FBQztnQkFDdEMsR0FBRyxFQUFFLEdBQUc7Z0JBQ1IsU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLEdBQUcsRUFBRSxVQUFVO2dCQUNmLGFBQWEsRUFBRSxDQUFDO2FBQ2pCLENBQUM7WUFDRixNQUFNLEtBQUssR0FBRztnQkFDWixLQUFLLEVBQUUsRUFBRTtnQkFDVCxNQUFNLEVBQUUsT0FBTyxFQUFFLG9DQUFvQzthQUN0RCxDQUFDO1lBQ0YsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNyQyxHQUFHLENBQUMsa0JBQWtCLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLHdCQUF3QixDQUFDO2lCQUNqRSxLQUFLLENBQUMscUNBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNyQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsWUFBWSxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sd0JBQXdCLEdBQUcsTUFBTSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEUsTUFBTSxDQUFDLFdBQVcsQ0FBQyx3QkFBd0IsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLE1BQU0sQ0FBQyxlQUFlLENBQUMsd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQy9FLE1BQU0sQ0FBQyxXQUFXLENBQUMsd0JBQXdCLENBQUMsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3hFLG9CQUFvQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCBub2NrID0gcmVxdWlyZSgnbm9jaycpO1xuaW1wb3J0IHsgQmFzZUNvaW4sIFBlbmRpbmdBcHByb3ZhbERhdGEsIFN0YXRlLCBUeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7XG4gIENyZWF0ZUludm9pY2VCb2R5LFxuICBnZXRMaWdodG5pbmdXYWxsZXQsXG4gIEludm9pY2UsXG4gIEludm9pY2VRdWVyeSxcbiAgTG5kQ3JlYXRlUGF5bWVudFJlc3BvbnNlLFxuICBMaWdodG5pbmdXYWxsZXQsXG4gIFN1Ym1pdFBheW1lbnRQYXJhbXMsXG4gIFVwZGF0ZUxpZ2h0bmluZ1dhbGxldENsaWVudFJlcXVlc3QsXG4gIGdldExpZ2h0bmluZ0tleWNoYWluLFxuICBnZXRMaWdodG5pbmdBdXRoS2V5Y2hhaW5zLFxuICB1cGRhdGVXYWxsZXRDb2luU3BlY2lmaWMsXG4gIExpZ2h0bmluZ09uY2hhaW5XaXRoZHJhd1BhcmFtcyxcbiAgUGF5bWVudEluZm8sXG4gIFBheW1lbnRRdWVyeSxcbiAgVHJhbnNhY3Rpb25RdWVyeSxcbn0gZnJvbSAnQGJpdGdvL2Fic3RyYWN0LWxpZ2h0bmluZyc7XG5cbmltcG9ydCB7IEJpdEdvLCBjb21tb24sIEdlbmVyYXRlTGlnaHRuaW5nV2FsbGV0T3B0aW9ucywgV2FsbGV0LCBXYWxsZXRzIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjJztcblxuZGVzY3JpYmUoJ0xpZ2h0bmluZyB3YWxsZXRzJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBjb2luTmFtZSA9ICd0bG5idGMnO1xuICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgbGV0IGJhc2Vjb2luOiBCYXNlQ29pbjtcbiAgbGV0IHdhbGxldHM6IFdhbGxldHM7XG4gIGxldCBiZ1VybDogc3RyaW5nO1xuXG4gIGNvbnN0IHVzZXJBdXRoS2V5ID0ge1xuICAgIGlkOiAnZGVmJyxcbiAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR1lqWXNuc0RqMVNIZGlYeW5XRVhObmZOZ01TcG9rTjU0Rkt5TXFidTdyV0VmVk5EczZ1QUptejg2VVZGdHE0c2VmaFFwWFpoU0F6UWNMOXpyRVB0aUxOTlpvZVN4Q0cnLFxuICAgIGVuY3J5cHRlZFBydjpcbiAgICAgICd7XCJpdlwiOlwielloaGFOZFcwd1BmSkVvQmpaNHB2Zz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInRnQU11YTlqamh3PVwiLFwiY3RcIjpcIkhjcmJ4UXZObFdHNXRMTW5kWXpkTkNZYTFsKzFoN28rdlNzd2VBMCtxMWxlM3RXdDZqTFVKU0VqWk4rSkk4bFRaMktQRlFnTHVsUVFoc1VhK3l0VUNCaTB2U2dqRjd4N0NwclQ3bDJDZmprZXcwMFhzRWQ3d25tdEpVc3JRazhtNjlDbzd0SVJBM29FZ3pybll3eTRxT004MWxiTk55UT1cIn0nLFxuICAgIHNvdXJjZTogJ3VzZXInLFxuICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgdGxuYnRjOiB7XG4gICAgICAgIHB1cnBvc2U6ICd1c2VyQXV0aCcsXG4gICAgICB9LFxuICAgIH0sXG4gIH07XG5cbiAgY29uc3Qgbm9kZUF1dGhLZXkgPSB7XG4gICAgaWQ6ICdnaGknLFxuICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHOXhuVG5BblJiSlBvM01BSHlSdEg0emVlaE44ZXhZazRWRno1YnVlcFV6ZWJoaXgzM0JLaFM1RWI0VjNMRWZXNXBZaVNSOHFtYUVueXJwZWdoaEtZOEpmekFzVURwcScsXG4gICAgZW5jcnlwdGVkUHJ2OlxuICAgICAgJ3tcIml2XCI6XCJiSDZlR2JubDl4OFBaRUNQcmd2Y25nPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwibzh5a25WNm5USTg9XCIsXCJjdFwiOlwibkd5ekFUb0l6WWtRZUlkY1ZhZm9XSHRNeDcrRmdqMFlsZENtZTNXQTF5eEpBQTBRdWxaVmhibE1aTi83ZWZDUkl1bUEwTk5tcEg3ZHhINm44Y1Zsei9aK1JVZ0MycTlsZ3ZaS1VvSmNZTlRqV1Vma21rSnV0WFgydHI4eVZ4bStlQy9oblJpeWZWTFoycVB4Y3R2RGxCVkJmZ0x1UHljPVwifScsXG4gICAgc291cmNlOiAndXNlcicsXG4gICAgY29pblNwZWNpZmljOiB7XG4gICAgICB0bG5idGM6IHtcbiAgICAgICAgcHVycG9zZTogJ25vZGVBdXRoJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuXG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKGNvaW5OYW1lKTtcbiAgICB3YWxsZXRzID0gYmFzZWNvaW4ud2FsbGV0cygpO1xuICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIG5vY2sucGVuZGluZ01vY2tzKCkubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIGxpZ2h0bmluZyB3YWxsZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzMTIzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50MTIzJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnY29kZTEyMycsXG4gICAgICAgICAgc3ViVHlwZTogJ2xpZ2h0bmluZ0N1c3RvZHknLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBcImVycm9yKHMpIHBhcnNpbmcgZ2VuZXJhdGUgbGlnaHRuaW5nIHdhbGxldCByZXF1ZXN0IHBhcmFtczogSW52YWxpZCB2YWx1ZSAndW5kZWZpbmVkJyBzdXBwbGllZCB0byBHZW5lcmF0ZUxpZ2h0bmluZ1dhbGxldE9wdGlvbnMubGFiZWwsIGV4cGVjdGVkIHN0cmluZy5cIlxuICAgICAgICApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICdteSBsbiB3YWxsZXQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnQxMjMnLFxuICAgICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdjb2RlMTIzJyxcbiAgICAgICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFwiZXJyb3IocykgcGFyc2luZyBnZW5lcmF0ZSBsaWdodG5pbmcgd2FsbGV0IHJlcXVlc3QgcGFyYW1zOiBJbnZhbGlkIHZhbHVlICd1bmRlZmluZWQnIHN1cHBsaWVkIHRvIEdlbmVyYXRlTGlnaHRuaW5nV2FsbGV0T3B0aW9ucy5wYXNzcGhyYXNlLCBleHBlY3RlZCBzdHJpbmcuXCJcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICAgIGxhYmVsOiAnbXkgbG4gd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzczEyMycsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ2NvZGUxMjMnLFxuICAgICAgICAgIHN1YlR5cGU6ICdsaWdodG5pbmdDdXN0b2R5JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgXCJlcnJvcihzKSBwYXJzaW5nIGdlbmVyYXRlIGxpZ2h0bmluZyB3YWxsZXQgcmVxdWVzdCBwYXJhbXM6IEludmFsaWQgdmFsdWUgJ3VuZGVmaW5lZCcgc3VwcGxpZWQgdG8gR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zLmVudGVycHJpc2UsIGV4cGVjdGVkIHN0cmluZy5cIlxuICAgICAgICApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICdteSBsbiB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzMTIzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50MTIzJyxcbiAgICAgICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFwiZXJyb3IocykgcGFyc2luZyBnZW5lcmF0ZSBsaWdodG5pbmcgd2FsbGV0IHJlcXVlc3QgcGFyYW1zOiBJbnZhbGlkIHZhbHVlICd1bmRlZmluZWQnIHN1cHBsaWVkIHRvIEdlbmVyYXRlTGlnaHRuaW5nV2FsbGV0T3B0aW9ucy5wYXNzY29kZUVuY3J5cHRpb25Db2RlLCBleHBlY3RlZCBzdHJpbmcuXCJcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICAgIGxhYmVsOiAxMjMgYXMgYW55LFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzMTIzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50MTIzJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnY29kZTEyMycsXG4gICAgICAgICAgc3ViVHlwZTogJ2xpZ2h0bmluZ0N1c3RvZHknLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICBcImVycm9yKHMpIHBhcnNpbmcgZ2VuZXJhdGUgbGlnaHRuaW5nIHdhbGxldCByZXF1ZXN0IHBhcmFtczogSW52YWxpZCB2YWx1ZSAnMTIzJyBzdXBwbGllZCB0byBHZW5lcmF0ZUxpZ2h0bmluZ1dhbGxldE9wdGlvbnMubGFiZWwsIGV4cGVjdGVkIHN0cmluZy5cIlxuICAgICAgICApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICdteSBsbiB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6IDEyMyBhcyBhbnksXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudDEyMycsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ2NvZGUxMjMnLFxuICAgICAgICAgIHN1YlR5cGU6ICdsaWdodG5pbmdDdXN0b2R5JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgXCJlcnJvcihzKSBwYXJzaW5nIGdlbmVyYXRlIGxpZ2h0bmluZyB3YWxsZXQgcmVxdWVzdCBwYXJhbXM6IEludmFsaWQgdmFsdWUgJzEyMycgc3VwcGxpZWQgdG8gR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zLnBhc3NwaHJhc2UsIGV4cGVjdGVkIHN0cmluZy5cIlxuICAgICAgICApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICdteSBsbiB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzMTIzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAxMjMgYXMgYW55LFxuICAgICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdjb2RlMTIzJyxcbiAgICAgICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFwiZXJyb3IocykgcGFyc2luZyBnZW5lcmF0ZSBsaWdodG5pbmcgd2FsbGV0IHJlcXVlc3QgcGFyYW1zOiBJbnZhbGlkIHZhbHVlICcxMjMnIHN1cHBsaWVkIHRvIEdlbmVyYXRlTGlnaHRuaW5nV2FsbGV0T3B0aW9ucy5lbnRlcnByaXNlLCBleHBlY3RlZCBzdHJpbmcuXCJcbiAgICAgICAgKTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICAgIGxhYmVsOiAnbXkgbG4gd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzczEyMycsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudDEyMycsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogMTIzIGFzIGFueSxcbiAgICAgICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIFwiZXJyb3IocykgcGFyc2luZyBnZW5lcmF0ZSBsaWdodG5pbmcgd2FsbGV0IHJlcXVlc3QgcGFyYW1zOiBJbnZhbGlkIHZhbHVlICcxMjMnIHN1cHBsaWVkIHRvIEdlbmVyYXRlTGlnaHRuaW5nV2FsbGV0T3B0aW9ucy5wYXNzY29kZUVuY3J5cHRpb25Db2RlLCBleHBlY3RlZCBzdHJpbmcuXCJcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgc3ViVHlwZSBvZiBbJ2xpZ2h0bmluZ0N1c3RvZHknLCAnbGlnaHRuaW5nU2VsZkN1c3RvZHknXSBhcyBjb25zdCkge1xuICAgICAgaXQoYHNob3VsZCBnZW5lcmF0ZSAke3N1YlR5cGV9IGxpZ2h0bmluZyB3YWxsZXRgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVMaWdodG5pbmdXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICAgIGxhYmVsOiAnbXkgbG4gd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzczEyMycsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudDEyMycsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ2NvZGUxMjMnLFxuICAgICAgICAgIHN1YlR5cGU6IHN1YlR5cGUgYXMgJ2xpZ2h0bmluZ0N1c3RvZHknIHwgJ2xpZ2h0bmluZ1NlbGZDdXN0b2R5JyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB2YWxpZGF0ZUtleVJlcXVlc3QgPSAoYm9keSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhc2VDaGVja3MgPVxuICAgICAgICAgICAgYm9keS5wdWIuc3RhcnRzV2l0aCgneHB1YicpICYmXG4gICAgICAgICAgICAhIWJvZHkuZW5jcnlwdGVkUHJ2ICYmXG4gICAgICAgICAgICBib2R5LmtleVR5cGUgPT09ICdpbmRlcGVuZGVudCcgJiZcbiAgICAgICAgICAgIGJvZHkuc291cmNlID09PSAndXNlcic7XG5cbiAgICAgICAgICBpZiAoYm9keS5vcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGJhc2VDaGVja3MgJiYgYm9keS5vcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgPT09ICdjb2RlMTIzJyAmJiBib2R5LmNvaW5TcGVjaWZpYyA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjb2luU3BlY2lmaWMgPSBib2R5LmNvaW5TcGVjaWZpYyAmJiBib2R5LmNvaW5TcGVjaWZpYy50bG5idGM7XG4gICAgICAgICAgICByZXR1cm4gYmFzZUNoZWNrcyAmJiAhIWNvaW5TcGVjaWZpYyAmJiBbJ3VzZXJBdXRoJywgJ25vZGVBdXRoJ10uaW5jbHVkZXMoY29pblNwZWNpZmljLnB1cnBvc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB2YWxpZGF0ZVdhbGxldFJlcXVlc3QgPSAoYm9keSkgPT4ge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBib2R5LmxhYmVsID09PSAnbXkgbG4gd2FsbGV0JyAmJlxuICAgICAgICAgICAgYm9keS5tID09PSAxICYmXG4gICAgICAgICAgICBib2R5Lm4gPT09IDEgJiZcbiAgICAgICAgICAgIGJvZHkudHlwZSA9PT0gJ2hvdCcgJiZcbiAgICAgICAgICAgIGJvZHkuc3ViVHlwZSA9PT0gc3ViVHlwZSAmJlxuICAgICAgICAgICAgYm9keS5lbnRlcnByaXNlID09PSAnZW50MTIzJyAmJlxuICAgICAgICAgICAgQXJyYXkuaXNBcnJheShib2R5LmtleXMpICYmXG4gICAgICAgICAgICBib2R5LmtleXMubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICBib2R5LmtleXNbMF0gPT09ICdrZXlJZDEnICYmXG4gICAgICAgICAgICBib2R5LmNvaW5TcGVjaWZpYyAmJlxuICAgICAgICAgICAgYm9keS5jb2luU3BlY2lmaWMudGxuYnRjICYmXG4gICAgICAgICAgICBBcnJheS5pc0FycmF5KGJvZHkuY29pblNwZWNpZmljLnRsbmJ0Yy5rZXlzKSAmJlxuICAgICAgICAgICAgYm9keS5jb2luU3BlY2lmaWMudGxuYnRjLmtleXMubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICBib2R5LmNvaW5TcGVjaWZpYy50bG5idGMua2V5cy5pbmNsdWRlcygna2V5SWQyJykgJiZcbiAgICAgICAgICAgIGJvZHkuY29pblNwZWNpZmljLnRsbmJ0Yy5rZXlzLmluY2x1ZGVzKCdrZXlJZDMnKVxuICAgICAgICAgICk7XG4gICAgICAgIH07XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92Mi8nICsgY29pbk5hbWUgKyAnL2tleScsIChib2R5KSA9PiB2YWxpZGF0ZUtleVJlcXVlc3QoYm9keSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBpZDogJ2tleUlkMScgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXknLCAoYm9keSkgPT4gdmFsaWRhdGVLZXlSZXF1ZXN0KGJvZHkpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6ICdrZXlJZDInIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5JywgKGJvZHkpID0+IHZhbGlkYXRlS2V5UmVxdWVzdChib2R5KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGlkOiAna2V5SWQzJyB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcvd2FsbGV0L2FkZCcsIChib2R5KSA9PiB2YWxpZGF0ZVdhbGxldFJlcXVlc3QoYm9keSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBpZDogJ3dhbGxldElkJyB9KTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2ludm9pY2VzJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCB3YWxsZXQ6IExpZ2h0bmluZ1dhbGxldDtcbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHdhbGxldCA9IGdldExpZ2h0bmluZ1dhbGxldChcbiAgICAgICAgbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHtcbiAgICAgICAgICBpZDogJ3dhbGxldElkJyxcbiAgICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7IGtleXM6IFsnZGVmJywgJ2doaSddIH0sXG4gICAgICAgIH0pXG4gICAgICApIGFzIExpZ2h0bmluZ1dhbGxldDtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbGlzdCBpbnZvaWNlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludm9pY2U6IEludm9pY2UgPSB7XG4gICAgICAgIHZhbHVlTXNhdDogMTAwMG4sXG4gICAgICAgIHBheW1lbnRIYXNoOiAnZm9vJyxcbiAgICAgICAgaW52b2ljZTogJ3RsbmZvb2JhcicsXG4gICAgICAgIHdhbGxldElkOiB3YWxsZXQud2FsbGV0LmlkKCksXG4gICAgICAgIHN0YXR1czogJ29wZW4nLFxuICAgICAgICBleHBpcmVzQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBzdGF0dXM6ICdvcGVuJyxcbiAgICAgICAgc3RhcnREYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgICBsaW1pdDogMTAwbixcbiAgICAgIH0gYXMgSW52b2ljZVF1ZXJ5O1xuICAgICAgY29uc3QgbGlzdEludm9pY2VzTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS9saWdodG5pbmcvaW52b2ljZWApXG4gICAgICAgIC5xdWVyeShJbnZvaWNlUXVlcnkuZW5jb2RlKHF1ZXJ5KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpbnZvaWNlczogW0ludm9pY2UuZW5jb2RlKGludm9pY2UpXSB9KTtcbiAgICAgIGNvbnN0IGludm9pY2VSZXNwb25zZSA9IGF3YWl0IHdhbGxldC5saXN0SW52b2ljZXMocXVlcnkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGludm9pY2VSZXNwb25zZS5pbnZvaWNlcy5sZW5ndGgsIDEpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChpbnZvaWNlUmVzcG9uc2UuaW52b2ljZXNbMF0sIGludm9pY2UpO1xuICAgICAgbGlzdEludm9pY2VzTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHdvcmsgcHJvcGVybHkgd2l0aCBwYWdpbmF0aW9uIHdoaWxlIGxpc3RpbmcgaW52b2ljZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZvaWNlMTogSW52b2ljZSA9IHtcbiAgICAgICAgdmFsdWVNc2F0OiAxMDAwbixcbiAgICAgICAgcGF5bWVudEhhc2g6ICdmb28xJyxcbiAgICAgICAgaW52b2ljZTogJ3RsbmZvb2JhcjEnLFxuICAgICAgICB3YWxsZXRJZDogd2FsbGV0LndhbGxldC5pZCgpLFxuICAgICAgICBzdGF0dXM6ICdvcGVuJyxcbiAgICAgICAgZXhwaXJlc0F0OiBuZXcgRGF0ZSgpLFxuICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIH07XG4gICAgICBjb25zdCBpbnZvaWNlMjogSW52b2ljZSA9IHtcbiAgICAgICAgLi4uaW52b2ljZTEsXG4gICAgICAgIHBheW1lbnRIYXNoOiAnZm9vMicsXG4gICAgICAgIGludm9pY2U6ICd0bG5mb29iYXIyJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBpbnZvaWNlMzogSW52b2ljZSA9IHtcbiAgICAgICAgLi4uaW52b2ljZTEsXG4gICAgICAgIHBheW1lbnRIYXNoOiAnZm9vMycsXG4gICAgICAgIGludm9pY2U6ICd0bG5mb29iYXIzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBhbGxJbnZvaWNlcyA9IFtJbnZvaWNlLmVuY29kZShpbnZvaWNlMSksIEludm9pY2UuZW5jb2RlKGludm9pY2UyKSwgSW52b2ljZS5lbmNvZGUoaW52b2ljZTMpXTtcbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBzdGF0dXM6ICdvcGVuJyxcbiAgICAgICAgc3RhcnREYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgICBsaW1pdDogMm4sXG4gICAgICB9IGFzIEludm9pY2VRdWVyeTtcbiAgICAgIGNvbnN0IGxpc3RJbnZvaWNlc05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vbGlnaHRuaW5nL2ludm9pY2VgKVxuICAgICAgICAucXVlcnkoSW52b2ljZVF1ZXJ5LmVuY29kZShxdWVyeSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaW52b2ljZXM6IGFsbEludm9pY2VzLnNsaWNlKDAsIDIpLCBuZXh0QmF0Y2hQcmV2SWQ6IGludm9pY2UyLnBheW1lbnRIYXNoIH0pO1xuICAgICAgY29uc3QgaW52b2ljZVJlc3BvbnNlID0gYXdhaXQgd2FsbGV0Lmxpc3RJbnZvaWNlcyhxdWVyeSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaW52b2ljZVJlc3BvbnNlLmludm9pY2VzLmxlbmd0aCwgMik7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGludm9pY2VSZXNwb25zZS5pbnZvaWNlc1swXSwgaW52b2ljZTEpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChpbnZvaWNlUmVzcG9uc2UuaW52b2ljZXNbMV0sIGludm9pY2UyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpbnZvaWNlUmVzcG9uc2UubmV4dEJhdGNoUHJldklkLCBpbnZvaWNlMi5wYXltZW50SGFzaCk7XG4gICAgICBsaXN0SW52b2ljZXNOb2NrLmRvbmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdsaXN0SW52b2ljZXMgc2hvdWxkIHRocm93IGVycm9yIGlmIHdwIHJlc3BvbnNlIGlzIGludmFsaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBsaXN0SW52b2ljZXNOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi93YWxsZXQvJHt3YWxsZXQud2FsbGV0LmlkKCl9L2xpZ2h0bmluZy9pbnZvaWNlYClcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpbnZvaWNlczogW3sgdmFsdWVNc2F0OiAnMTAwMCcgfV0gfSk7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBhd2FpdCB3YWxsZXQubGlzdEludm9pY2VzKHt9KSwgL0ludmFsaWQgbGlzdCBpbnZvaWNlcyByZXNwb25zZS8pO1xuICAgICAgbGlzdEludm9pY2VzTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBpbnZvaWNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY3JlYXRlSW52b2ljZTogQ3JlYXRlSW52b2ljZUJvZHkgPSB7XG4gICAgICAgIHZhbHVlTXNhdDogMTAwMG4sXG4gICAgICAgIG1lbW86ICd0ZXN0IGludm9pY2UnLFxuICAgICAgICBleHBpcnk6IDEwMCxcbiAgICAgIH07XG4gICAgICBjb25zdCBpbnZvaWNlOiBJbnZvaWNlID0ge1xuICAgICAgICBpbnZvaWNlOiAndGxuYWJjJyxcbiAgICAgICAgcGF5bWVudEhhc2g6ICcxMjMnLFxuICAgICAgICBleHBpcmVzQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIHN0YXR1czogJ29wZW4nLFxuICAgICAgICB3YWxsZXRJZDogd2FsbGV0LndhbGxldC5pZCgpLFxuICAgICAgICB2YWx1ZU1zYXQ6IDEwMDBuLFxuICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgbWVtbzogJ3Rlc3QgaW52b2ljZScsXG4gICAgICB9O1xuICAgICAgY29uc3QgY3JlYXRlSW52b2ljZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi93YWxsZXQvJHt3YWxsZXQud2FsbGV0LmlkKCl9L2xpZ2h0bmluZy9pbnZvaWNlYCwgQ3JlYXRlSW52b2ljZUJvZHkuZW5jb2RlKGNyZWF0ZUludm9pY2UpKVxuICAgICAgICAucmVwbHkoMjAwLCBJbnZvaWNlLmVuY29kZShpbnZvaWNlKSk7XG4gICAgICBjb25zdCBjcmVhdGVJbnZvaWNlUmVzcG9uc2UgPSBhd2FpdCB3YWxsZXQuY3JlYXRlSW52b2ljZShjcmVhdGVJbnZvaWNlKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoY3JlYXRlSW52b2ljZVJlc3BvbnNlLCBpbnZvaWNlKTtcbiAgICAgIGNyZWF0ZUludm9pY2VOb2NrLmRvbmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVJbnZvaWNlIHNob3VsZCB0aHJvdyBlcnJvciBpZiB3cCByZXNwb25zZSBpcyBpbnZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY3JlYXRlSW52b2ljZTogQ3JlYXRlSW52b2ljZUJvZHkgPSB7XG4gICAgICAgIHZhbHVlTXNhdDogMTAwMG4sXG4gICAgICAgIG1lbW86ICd0ZXN0IGludm9pY2UnLFxuICAgICAgICBleHBpcnk6IDEwMCxcbiAgICAgIH07XG4gICAgICBjb25zdCBjcmVhdGVJbnZvaWNlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vbGlnaHRuaW5nL2ludm9pY2VgKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHZhbHVlTXNhdDogJzEwMDAnIH0pO1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgd2FsbGV0LmNyZWF0ZUludm9pY2UoY3JlYXRlSW52b2ljZSksIC9JbnZhbGlkIGNyZWF0ZSBpbnZvaWNlIHJlc3BvbnNlLyk7XG4gICAgICBjcmVhdGVJbnZvaWNlTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBheSBpbnZvaWNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zOiBTdWJtaXRQYXltZW50UGFyYW1zID0ge1xuICAgICAgICBpbnZvaWNlOiAnbG5iYzEuLi4nLFxuICAgICAgICBhbW91bnRNc2F0OiAxMDAwbixcbiAgICAgICAgZmVlTGltaXRNc2F0OiAxMDBuLFxuICAgICAgICBmZWVMaW1pdFJhdGlvOiAwLjEsXG4gICAgICAgIHNlcXVlbmNlSWQ6ICcxMjMnLFxuICAgICAgICBjb21tZW50OiAndGVzdCBwYXltZW50JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UmVxdWVzdFJlc3BvbnNlID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxMTIzJyxcbiAgICAgICAgc3RhdGU6ICdkZWxpdmVyZWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbG5kUmVzcG9uc2U6IExuZENyZWF0ZVBheW1lbnRSZXNwb25zZSA9IHtcbiAgICAgICAgc3RhdHVzOiAnc2V0dGxlZCcsXG4gICAgICAgIHBheW1lbnRIYXNoOiAncGF5bWVudEhhc2gxMjMnLFxuICAgICAgICBhbW91bnRNc2F0OiBwYXJhbXMuYW1vdW50TXNhdCAhPT0gdW5kZWZpbmVkID8gcGFyYW1zLmFtb3VudE1zYXQudG9TdHJpbmcoKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZmVlTXNhdDogcGFyYW1zLmZlZUxpbWl0TXNhdCAhPT0gdW5kZWZpbmVkID8gcGFyYW1zLmZlZUxpbWl0TXNhdC50b1N0cmluZygpIDogdW5kZWZpbmVkLFxuICAgICAgICBwYXltZW50UHJlaW1hZ2U6ICdwcmVpbWFnZTEyMycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBmaW5hbFBheW1lbnRSZXNwb25zZSA9IHtcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eFJlcTEyMycsXG4gICAgICAgIHN0YXRlOiAnZGVsaXZlcmVkJyxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgICAuLi5sbmRSZXNwb25zZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNyZWF0ZVRyYW5zZmVyRGF0YSA9IHtcbiAgICAgICAgaWQ6ICdmYWtlX2lkJyxcbiAgICAgICAgY29pbjogJ3RsbmJ0YycsXG4gICAgICAgIHN0YXRlOiAnaW5pdGlhbGl6ZWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY3JlYXRlVHhSZXF1ZXN0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vdHhyZXF1ZXN0c2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHR4UmVxdWVzdFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgY3JlYXRlVHJhbnNmZXJOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0UmVzcG9uc2UudHhSZXF1ZXN0SWR9L3RyYW5zZmVyc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIGNyZWF0ZVRyYW5zZmVyRGF0YSk7XG5cbiAgICAgIGNvbnN0IHNlbmRUeFJlcXVlc3ROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0UmVzcG9uc2UudHhSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8wL3NlbmRgKVxuICAgICAgICAucmVwbHkoMjAwLCBmaW5hbFBheW1lbnRSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHVzZXJBdXRoS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXkvZGVmJylcbiAgICAgICAgLnJlcGx5KDIwMCwgdXNlckF1dGhLZXkpO1xuICAgICAgY29uc3Qgbm9kZUF1dGhLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldCgnL2FwaS92Mi8nICsgY29pbk5hbWUgKyAnL2tleS9naGknKVxuICAgICAgICAucmVwbHkoMjAwLCBub2RlQXV0aEtleSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0LnBheUludm9pY2UocGFyYW1zKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXNwb25zZS50eFJlcXVlc3RJZCwgJ3R4UmVxMTIzJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzcG9uc2UudHhSZXF1ZXN0U3RhdGUsICdkZWxpdmVyZWQnKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5wYXltZW50U3RhdHVzKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgcmVzcG9uc2UucGF5bWVudFN0YXR1cy5zdGF0dXMsXG4gICAgICAgIGZpbmFsUGF5bWVudFJlc3BvbnNlLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5zdGF0dXNcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIHJlc3BvbnNlLnBheW1lbnRTdGF0dXMucGF5bWVudEhhc2gsXG4gICAgICAgIGZpbmFsUGF5bWVudFJlc3BvbnNlLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5wYXltZW50SGFzaFxuICAgICAgKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgcmVzcG9uc2UucGF5bWVudFN0YXR1cy5hbW91bnRNc2F0LFxuICAgICAgICBmaW5hbFBheW1lbnRSZXNwb25zZS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luU3BlY2lmaWMuYW1vdW50TXNhdFxuICAgICAgKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgcmVzcG9uc2UucGF5bWVudFN0YXR1cy5mZWVNc2F0LFxuICAgICAgICBmaW5hbFBheW1lbnRSZXNwb25zZS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5jb2luU3BlY2lmaWMuZmVlTXNhdFxuICAgICAgKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgcmVzcG9uc2UucGF5bWVudFN0YXR1cy5wYXltZW50UHJlaW1hZ2UsXG4gICAgICAgIGZpbmFsUGF5bWVudFJlc3BvbnNlLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LmNvaW5TcGVjaWZpYy5wYXltZW50UHJlaW1hZ2VcbiAgICAgICk7XG5cbiAgICAgIGNyZWF0ZVR4UmVxdWVzdE5vY2suZG9uZSgpO1xuICAgICAgc2VuZFR4UmVxdWVzdE5vY2suZG9uZSgpO1xuICAgICAgY3JlYXRlVHJhbnNmZXJOb2NrLmRvbmUoKTtcbiAgICAgIHVzZXJBdXRoS2V5Tm9jay5kb25lKCk7XG4gICAgICBub2RlQXV0aEtleU5vY2suZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgcGVuZGluZyBhcHByb3ZhbCB3aGVuIHBheWluZyBpbnZvaWNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zOiBTdWJtaXRQYXltZW50UGFyYW1zID0ge1xuICAgICAgICBpbnZvaWNlOiAnbG5iYzEuLi4nLFxuICAgICAgICBhbW91bnRNc2F0OiAxMDAwbixcbiAgICAgICAgZmVlTGltaXRNc2F0OiAxMDBuLFxuICAgICAgICBmZWVMaW1pdFJhdGlvOiAwLjEsXG4gICAgICAgIHNlcXVlbmNlSWQ6ICcxMjMnLFxuICAgICAgICBjb21tZW50OiAndGVzdCBwYXltZW50JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UmVxdWVzdFJlc3BvbnNlID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxMTIzJyxcbiAgICAgICAgc3RhdGU6ICdwZW5kaW5nQXBwcm92YWwnLFxuICAgICAgICBwZW5kaW5nQXBwcm92YWxJZDogJ2FwcHJvdmFsMTIzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBlbmRpbmdBcHByb3ZhbERhdGE6IFBlbmRpbmdBcHByb3ZhbERhdGEgPSB7XG4gICAgICAgIGlkOiAnYXBwcm92YWwxMjMnLFxuICAgICAgICBzdGF0ZTogU3RhdGUuUEVORElORyxcbiAgICAgICAgY3JlYXRvcjogJ3VzZXIxMjMnLFxuICAgICAgICBpbmZvOiB7XG4gICAgICAgICAgdHlwZTogVHlwZS5UUkFOU0FDVElPTl9SRVFVRVNULFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY3JlYXRlVHhSZXF1ZXN0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vdHhyZXF1ZXN0c2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHR4UmVxdWVzdFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgZ2V0UGVuZGluZ0FwcHJvdmFsTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvJHtjb2luTmFtZX0vcGVuZGluZ2FwcHJvdmFscy8ke3R4UmVxdWVzdFJlc3BvbnNlLnBlbmRpbmdBcHByb3ZhbElkfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHBlbmRpbmdBcHByb3ZhbERhdGEpO1xuXG4gICAgICBjb25zdCB1c2VyQXV0aEtleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2RlZicpXG4gICAgICAgIC5yZXBseSgyMDAsIHVzZXJBdXRoS2V5KTtcbiAgICAgIGNvbnN0IG5vZGVBdXRoS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXkvZ2hpJylcbiAgICAgICAgLnJlcGx5KDIwMCwgbm9kZUF1dGhLZXkpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldC5wYXlJbnZvaWNlKHBhcmFtcyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzcG9uc2UudHhSZXF1ZXN0SWQsICd0eFJlcTEyMycpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3BvbnNlLnR4UmVxdWVzdFN0YXRlLCAncGVuZGluZ0FwcHJvdmFsJyk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UucGVuZGluZ0FwcHJvdmFsKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXNwb25zZS5wYXltZW50U3RhdHVzLCB1bmRlZmluZWQpO1xuXG4gICAgICBjcmVhdGVUeFJlcXVlc3ROb2NrLmRvbmUoKTtcbiAgICAgIGdldFBlbmRpbmdBcHByb3ZhbE5vY2suZG9uZSgpO1xuICAgICAgdXNlckF1dGhLZXlOb2NrLmRvbmUoKTtcbiAgICAgIG5vZGVBdXRoS2V5Tm9jay5kb25lKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXltZW50cycsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgd2FsbGV0OiBMaWdodG5pbmdXYWxsZXQ7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB3YWxsZXQgPSBnZXRMaWdodG5pbmdXYWxsZXQoXG4gICAgICAgIG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7XG4gICAgICAgICAgaWQ6ICd3YWxsZXRJZCcsXG4gICAgICAgICAgY29pbjogJ3RsbmJ0YycsXG4gICAgICAgICAgc3ViVHlwZTogJ2xpZ2h0bmluZ0N1c3RvZHknLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBrZXlzOiBbJ2RlZicsICdnaGknXSB9LFxuICAgICAgICB9KVxuICAgICAgKSBhcyBMaWdodG5pbmdXYWxsZXQ7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCBwYXltZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBheW1lbnQ6IFBheW1lbnRJbmZvID0ge1xuICAgICAgICBpZDogJzgzMDhmZGRiLTIzNTYtNDlhYS04NTQ4LTEwYzIzMDk5ODU0YycsXG4gICAgICAgIHBheW1lbnRIYXNoOiAnZm9vJyxcbiAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC53YWxsZXQuaWQoKSxcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eFJlcUlkJyxcbiAgICAgICAgc3RhdHVzOiAnc2V0dGxlZCcsXG4gICAgICAgIGludm9pY2U6ICd0bG5mb29iYXInLFxuICAgICAgICBkZXN0aW5hdGlvbjogJ2Rlc3RpbmF0aW9uJyxcbiAgICAgICAgZmVlTGltaXRNc2F0OiAxMDBuLFxuICAgICAgICBhbW91bnRNc2F0OiAxMDAwbixcbiAgICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLFxuICAgICAgICB1cGRhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICB9O1xuICAgICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICAgIHN0YXR1czogJ3NldHRsZWQnLFxuICAgICAgICBzdGFydERhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGxpbWl0OiAxMDBuLFxuICAgICAgfSBhcyBQYXltZW50UXVlcnk7XG4gICAgICBjb25zdCBsaXN0UGF5bWVudHNOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi93YWxsZXQvJHt3YWxsZXQud2FsbGV0LmlkKCl9L2xpZ2h0bmluZy9wYXltZW50YClcbiAgICAgICAgLnF1ZXJ5KFBheW1lbnRRdWVyeS5lbmNvZGUocXVlcnkpKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHBheW1lbnRzOiBbUGF5bWVudEluZm8uZW5jb2RlKHBheW1lbnQpXSB9KTtcbiAgICAgIGNvbnN0IGxpc3RQYXltZW50c1Jlc3BvbnNlID0gYXdhaXQgd2FsbGV0Lmxpc3RQYXltZW50cyhxdWVyeSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwobGlzdFBheW1lbnRzUmVzcG9uc2UucGF5bWVudHMubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwobGlzdFBheW1lbnRzUmVzcG9uc2UucGF5bWVudHNbMF0sIHBheW1lbnQpO1xuICAgICAgbGlzdFBheW1lbnRzTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHdvcmsgcHJvcGVybHkgd2l0aCBwYWdpbmF0aW9uIHdoaWxlIGxpc3RpbmcgcGF5bWVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXltZW50MTogUGF5bWVudEluZm8gPSB7XG4gICAgICAgIGlkOiAnODMwOGZkZGItMjM1Ni00OWFhLTg1NDgtMTBjMjMwOTk4NTRjJyxcbiAgICAgICAgcGF5bWVudEhhc2g6ICdmb28xJyxcbiAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC53YWxsZXQuaWQoKSxcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eFJlcUlkMScsXG4gICAgICAgIHN0YXR1czogJ3NldHRsZWQnLFxuICAgICAgICBpbnZvaWNlOiAndGxuZm9vYmFyMScsXG4gICAgICAgIGRlc3RpbmF0aW9uOiAnZGVzdGluYXRpb24nLFxuICAgICAgICBmZWVMaW1pdE1zYXQ6IDEwMG4sXG4gICAgICAgIGFtb3VudE1zYXQ6IDEwMDBuLFxuICAgICAgICBjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXltZW50MjogUGF5bWVudEluZm8gPSB7XG4gICAgICAgIC4uLnBheW1lbnQxLFxuICAgICAgICBpZDogJzgzMDhmZGRiLTIzNTYtNDlhYS04NTQ4LTEwYzIzMDk5ODU0ZCcsXG4gICAgICAgIHBheW1lbnRIYXNoOiAnZm9vMicsXG4gICAgICAgIHR4UmVxdWVzdElkOiAndHhSZXFJZDInLFxuICAgICAgICBpbnZvaWNlOiAndGxuZm9vYmFyMicsXG4gICAgICB9O1xuICAgICAgY29uc3QgcGF5bWVudDM6IFBheW1lbnRJbmZvID0ge1xuICAgICAgICAuLi5wYXltZW50MSxcbiAgICAgICAgaWQ6ICc4MzA4ZmRkYi0yMzU2LTQ5YWEtODU0OC0xMGMyMzA5OTg1NGUnLFxuICAgICAgICBwYXltZW50SGFzaDogJ2ZvbzMnLFxuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxSWQzJyxcbiAgICAgICAgaW52b2ljZTogJ3RsbmZvb2JhcjMnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGFsbFBheW1lbnRzID0gW1BheW1lbnRJbmZvLmVuY29kZShwYXltZW50MSksIFBheW1lbnRJbmZvLmVuY29kZShwYXltZW50MiksIFBheW1lbnRJbmZvLmVuY29kZShwYXltZW50MyldO1xuICAgICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICAgIHN0YXR1czogJ3NldHRsZWQnLFxuICAgICAgICBzdGFydERhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIGxpbWl0OiAybixcbiAgICAgIH0gYXMgUGF5bWVudFF1ZXJ5O1xuICAgICAgY29uc3QgbGlzdFBheW1lbnRzTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS9saWdodG5pbmcvcGF5bWVudGApXG4gICAgICAgIC5xdWVyeShQYXltZW50UXVlcnkuZW5jb2RlKHF1ZXJ5KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwYXltZW50czogYWxsUGF5bWVudHMuc2xpY2UoMCwgMiksIG5leHRCYXRjaFByZXZJZDogcGF5bWVudDIucGF5bWVudEhhc2ggfSk7XG4gICAgICBjb25zdCBsaXN0UGF5bWVudHNSZXNwb25zZSA9IGF3YWl0IHdhbGxldC5saXN0UGF5bWVudHMocXVlcnkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGxpc3RQYXltZW50c1Jlc3BvbnNlLnBheW1lbnRzLmxlbmd0aCwgMik7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGxpc3RQYXltZW50c1Jlc3BvbnNlLnBheW1lbnRzWzBdLCBwYXltZW50MSk7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGxpc3RQYXltZW50c1Jlc3BvbnNlLnBheW1lbnRzWzFdLCBwYXltZW50Mik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwobGlzdFBheW1lbnRzUmVzcG9uc2UubmV4dEJhdGNoUHJldklkLCBwYXltZW50Mi5wYXltZW50SGFzaCk7XG4gICAgICBsaXN0UGF5bWVudHNOb2NrLmRvbmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdsaXN0UGF5bWVudHMgc2hvdWxkIHRocm93IGVycm9yIGlmIHdwIHJlc3BvbnNlIGlzIGludmFsaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBsaXN0UGF5bWVudHNOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi93YWxsZXQvJHt3YWxsZXQud2FsbGV0LmlkKCl9L2xpZ2h0bmluZy9wYXltZW50YClcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwYXltZW50czogW3sgYW1vdW50TXNhdDogJzEwMDAnIH1dIH0pO1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgd2FsbGV0Lmxpc3RQYXltZW50cyh7fSksIC9JbnZhbGlkIHBheW1lbnQgbGlzdCByZXNwb25zZS8pO1xuICAgICAgbGlzdFBheW1lbnRzTm9jay5kb25lKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZXQgbGlnaHRuaW5nIGtleShzKScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICdmYWtlaWQnLFxuICAgICAgY29pbjogY29pbk5hbWUsXG4gICAgICBrZXlzOiBbJ2FiYyddLFxuICAgICAgY29pblNwZWNpZmljOiB7IGtleXM6IFsnZGVmJywgJ2doaSddIH0sXG4gICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgfTtcblxuICAgIGNvbnN0IHVzZXJLZXlEYXRhID0ge1xuICAgICAgaWQ6ICdhYmMnLFxuICAgICAgcHViOiAneHB1YjEnLFxuICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2MScsXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlckF1dGhLZXlEYXRhID0ge1xuICAgICAgaWQ6ICdkZWYnLFxuICAgICAgcHViOiAneHB1YjInLFxuICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2MicsXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICB0bG5idGM6IHtcbiAgICAgICAgICBwdXJwb3NlOiAndXNlckF1dGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3Qgbm9kZUF1dGhLZXlEYXRhID0ge1xuICAgICAgaWQ6ICdnaGknLFxuICAgICAgcHViOiAneHB1YjMnLFxuICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2MycsXG4gICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICB0bG5idGM6IHtcbiAgICAgICAgICBwdXJwb3NlOiAnbm9kZUF1dGgnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgbGlnaHRuaW5nIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgICAgY29uc3Qga2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXkvYWJjJylcbiAgICAgICAgLnJlcGx5KDIwMCwgdXNlcktleURhdGEpO1xuXG4gICAgICBjb25zdCBrZXkgPSBhd2FpdCBnZXRMaWdodG5pbmdLZXljaGFpbih3YWxsZXQpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChrZXksIHVzZXJLZXlEYXRhKTtcbiAgICAgIGtleU5vY2suZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgbGlnaHRuaW5nIGF1dGgga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcblxuICAgICAgY29uc3QgdXNlckF1dGhLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldCgnL2FwaS92Mi8nICsgY29pbk5hbWUgKyAnL2tleS9kZWYnKVxuICAgICAgICAucmVwbHkoMjAwLCB1c2VyQXV0aEtleURhdGEpO1xuICAgICAgY29uc3Qgbm9kZUF1dGhLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLmdldCgnL2FwaS92Mi8nICsgY29pbk5hbWUgKyAnL2tleS9naGknKVxuICAgICAgICAucmVwbHkoMjAwLCBub2RlQXV0aEtleURhdGEpO1xuXG4gICAgICBjb25zdCB7IHVzZXJBdXRoS2V5LCBub2RlQXV0aEtleSB9ID0gYXdhaXQgZ2V0TGlnaHRuaW5nQXV0aEtleWNoYWlucyh3YWxsZXQpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCh1c2VyQXV0aEtleSwgdXNlckF1dGhLZXlEYXRhKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwobm9kZUF1dGhLZXksIG5vZGVBdXRoS2V5RGF0YSk7XG4gICAgICB1c2VyQXV0aEtleU5vY2suZG9uZSgpO1xuICAgICAgbm9kZUF1dGhLZXlOb2NrLmRvbmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBnZXQgbGlnaHRuaW5nIGtleSBmb3IgaW52YWxpZCBudW1iZXIgb2Yga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7IC4uLndhbGxldERhdGEsIGtleXM6IFtdIH0pO1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IGdldExpZ2h0bmluZ0tleWNoYWluKHdhbGxldCksXG4gICAgICAgIC9FcnJvcjogSW52YWxpZCBudW1iZXIgb2Yga2V5IGluIGxpZ2h0bmluZyB3YWxsZXQ6IDAvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGdldCBsaWdodG5pbmcgYXV0aCBrZXlzIGZvciBpbnZhbGlkIG51bWJlciBvZiBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHsgLi4ud2FsbGV0RGF0YSwgY29pblNwZWNpZmljOiB7IGtleXM6IFsnZGVmJ10gfSB9KTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PiBhd2FpdCBnZXRMaWdodG5pbmdBdXRoS2V5Y2hhaW5zKHdhbGxldCksXG4gICAgICAgIC9FcnJvcjogSW52YWxpZCBudW1iZXIgb2YgYXV0aCBrZXlzIGluIGxpZ2h0bmluZyB3YWxsZXQ6IDEvXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGdldCBsaWdodG5pbmcga2V5IGZvciBpbnZhbGlkIHJlc3BvbnNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2FiYycpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4udXNlcktleURhdGEsIHNvdXJjZTogJ2JhY2t1cCcgfSk7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGF3YWl0IGdldExpZ2h0bmluZ0tleWNoYWluKHdhbGxldCksIC9FcnJvcjogSW52YWxpZCB1c2VyIGtleS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGdldCBsaWdodG5pbmcgYXV0aCBrZXlzIGZvciBpbnZhbGlkIHJlc3BvbnNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2RlZicpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4udXNlckF1dGhLZXlEYXRhLCBzb3VyY2U6ICdiYWNrdXAnIH0pO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2doaScpXG4gICAgICAgIC5yZXBseSgyMDAsIG5vZGVBdXRoS2V5RGF0YSk7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICBhc3luYyAoKSA9PiBhd2FpdCBnZXRMaWdodG5pbmdBdXRoS2V5Y2hhaW5zKHdhbGxldCksXG4gICAgICAgIC9FcnJvcjogSW52YWxpZCBsaWdodG5pbmcgYXV0aCBrZXk6IGRlZi9cbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdVcGRhdGUgbGlnaHRuaW5nIHdhbGxldCBjb2luIHNwZWNpZmljJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJ2Zha2VpZCcsXG4gICAgICBjb2luOiBjb2luTmFtZSxcbiAgICAgIGtleXM6IFsnYWJjJ10sXG4gICAgICBjb2luU3BlY2lmaWM6IHsga2V5czogWydkZWYnLCAnZ2hpJ10gfSxcbiAgICAgIHN1YlR5cGU6ICdsaWdodG5pbmdTZWxmQ3VzdG9keScsXG4gICAgfTtcblxuICAgIGNvbnN0IHdhdGNoT25seUFjY291bnRzID0ge1xuICAgICAgbWFzdGVyX2tleV9iaXJ0aGRheV90aW1lc3RhbXA6ICdkdW1teScsXG4gICAgICBtYXN0ZXJfa2V5X2ZpbmdlcnByaW50OiAnZHVtbXknLFxuICAgICAgYWNjb3VudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHhwdWI6ICd1cHViNUVlcDdINXEzOVB6UVpMVkVZTEJ5dER5Qk5lVjc0RThtUXN5ZUw2VW96RnE5WTNNc1o1Mkc3WUd1cXJKUGdveUFxRjdUQmVKZG5rckhyVnJCNXBrV2tQSjljSkdBZVBNVTZGMUd5dzZhRkgnLFxuICAgICAgICAgIHB1cnBvc2U6IDQ5LFxuICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgeHB1YjogJ3ZwdWI1WlUxUEhHcFFvRFNIY2tZaWNvNG5zdndzRDNtVGg2VWpxTDV6eUdXWFpYekJqVFlNTktvdDd0OWVSUFFZNzFoSmNuTk45cjFzczI1ZzN4QTlybW9KNW5XUGc4akVXYXZydHRuc1ZhMXF3MScsXG4gICAgICAgICAgcHVycG9zZTogODQsXG4gICAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG4gICAgaXQoJ3Nob3VsZCB1cGRhdGUgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuXG4gICAgICBjb25zdCB1c2VyQXV0aEtleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2RlZicpXG4gICAgICAgIC5yZXBseSgyMDAsIHVzZXJBdXRoS2V5KTtcbiAgICAgIGNvbnN0IG5vZGVBdXRoS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXkvZ2hpJylcbiAgICAgICAgLnJlcGx5KDIwMCwgbm9kZUF1dGhLZXkpO1xuICAgICAgbGV0IGNhcHR1cmVkQm9keTtcbiAgICAgIGNvbnN0IHdwV2FsbGV0VXBkYXRlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wdXQoYC9hcGkvdjIvdGxuYnRjL3dhbGxldC8ke3dhbGxldERhdGEuaWR9YClcbiAgICAgICAgLnJlcGx5KGZ1bmN0aW9uICh1cmksIHJlcXVlc3RCb2R5KSB7XG4gICAgICAgICAgY2FwdHVyZWRCb2R5ID0gcmVxdWVzdEJvZHk7XG4gICAgICAgICAgcmV0dXJuIFsyMDBdO1xuICAgICAgICB9KTtcblxuICAgICAgY29uc3QgcGFyYW1zOiBVcGRhdGVMaWdodG5pbmdXYWxsZXRDbGllbnRSZXF1ZXN0ID0ge1xuICAgICAgICBzaWduZXJNYWNhcm9vbjogJ3NpZ25lck1hY2Fyb29uJyxcbiAgICAgICAgc2lnbmVyQWRtaW5NYWNhcm9vbjogJ3NpZ25lckFkbWluTWFjYXJvb24nLFxuICAgICAgICBzaWduZXJUbHNLZXk6ICdzaWduZXJUbHNLZXknLFxuICAgICAgICBzaWduZXJUbHNDZXJ0OiAnc2lnbmVyVGxzQ2VydCcsXG4gICAgICAgIHdhdGNoT25seUFjY291bnRzLFxuICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQxMjMnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LmRvZXNOb3RSZWplY3QoYXN5bmMgKCkgPT4gYXdhaXQgdXBkYXRlV2FsbGV0Q29pblNwZWNpZmljKHdhbGxldCwgcGFyYW1zKSk7XG4gICAgICBhc3NlcnQub2sodXNlckF1dGhLZXlOb2NrLmlzRG9uZSgpKTtcbiAgICAgIGFzc2VydC5vayhub2RlQXV0aEtleU5vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKHdwV2FsbGV0VXBkYXRlTm9jay5pc0RvbmUoKSk7XG5cbiAgICAgIC8vIFZlcmlmeSBzdHJ1Y3R1cmUgYW5kIHJlcXVpcmVkIGZpZWxkc1xuICAgICAgYXNzZXJ0Lm9rKGNhcHR1cmVkQm9keS5jb2luU3BlY2lmaWM/LnRsbmJ0Yz8uc2lnbmVkUmVxdWVzdCwgJ3NpZ25lZFJlcXVlc3Qgc2hvdWxkIGV4aXN0Jyk7XG4gICAgICBjb25zdCBzaWduZWRSZXF1ZXN0ID0gY2FwdHVyZWRCb2R5LmNvaW5TcGVjaWZpYy50bG5idGMuc2lnbmVkUmVxdWVzdDtcblxuICAgICAgYXNzZXJ0Lm9rKHNpZ25lZFJlcXVlc3Quc2lnbmVyVGxzQ2VydCwgJ3NpZ25lclRsc0NlcnQgc2hvdWxkIGV4aXN0Jyk7XG4gICAgICBhc3NlcnQub2soc2lnbmVkUmVxdWVzdC53YXRjaE9ubHlBY2NvdW50cywgJ3dhdGNoT25seUFjY291bnRzIHNob3VsZCBleGlzdCcpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZ25lZFJlcXVlc3QuZW5jcnlwdGVkU2lnbmVyVGxzS2V5LCAnZW5jcnlwdGVkU2lnbmVyVGxzS2V5IHNob3VsZCBleGlzdCcpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZ25lZFJlcXVlc3QuZW5jcnlwdGVkU2lnbmVyQWRtaW5NYWNhcm9vbiwgJ2VuY3J5cHRlZFNpZ25lckFkbWluTWFjYXJvb24gc2hvdWxkIGV4aXN0Jyk7XG4gICAgICBhc3NlcnQub2soc2lnbmVkUmVxdWVzdC5lbmNyeXB0ZWRTaWduZXJNYWNhcm9vbiwgJ2VuY3J5cHRlZFNpZ25lck1hY2Fyb29uIHNob3VsZCBleGlzdCcpO1xuXG4gICAgICAvLyBWZXJpZnkgc2lnbmF0dXJlIGV4aXN0c1xuICAgICAgYXNzZXJ0Lm9rKGNhcHR1cmVkQm9keS5jb2luU3BlY2lmaWMudGxuYnRjLnNpZ25hdHVyZSwgJ3NpZ25hdHVyZSBzaG91bGQgZXhpc3QnKTtcblxuICAgICAgLy8gd2Ugc2hvdWxkIG5vdCBwYXNzIHBhc3NwaHJhc2UgdG8gdGhlIGJhY2tlbmRcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduZWRSZXF1ZXN0LnBhc3NwaHJhc2UsIHVuZGVmaW5lZCwgJ3Bhc3NwaHJhc2Ugc2hvdWxkIG5vdCBleGlzdCBpbiByZXF1ZXN0Jyk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnT24gY2hhaW4gd2l0aGRyYXdhbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgd2FsbGV0OiBMaWdodG5pbmdXYWxsZXQ7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YXRjaE9ubHlBY2NvdW50cyA9IHtcbiAgICAgICAgbWFzdGVyX2tleV9iaXJ0aGRheV90aW1lc3RhbXA6ICdkdW1teScsXG4gICAgICAgIG1hc3Rlcl9rZXlfZmluZ2VycHJpbnQ6ICdkdW1teScsXG4gICAgICAgIGFjY291bnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgeHB1YjogJ3RwdWJEQ21pV01rVEpyWjI0dDFaNkVDUjNIeXluQ3laOXpHc1dxaGNMaDZINHlGSzJDRG96U3N6RDFwUDJMaTROeDFZWXRSY3ZtTmJkYjNuRDFTekZlall0UEZmVG9jVHYyRWFBZ0pDZzR6cEpwQScsXG4gICAgICAgICAgICBwdXJwb3NlOiA0OSxcbiAgICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB4cHViOiAndHB1YkRDRk43YnN4UjlVVEtnZ2RIMnBtdjVIZUhHUU5pRHJKd2ExRVpGdFA5c0g1UEYyOGkzN0ZIcG9ZU1lBUlFrS1o2TWk5OHBrcDdveXBEY3hGbUU0ZFFHcThqVjhHdjNMNmdtV0JlUndQeGtQJyxcbiAgICAgICAgICAgIHB1cnBvc2U6IDg0LFxuICAgICAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICAgICAgYWNjb3VudDogMCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIHdhbGxldCA9IGdldExpZ2h0bmluZ1dhbGxldChcbiAgICAgICAgbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHtcbiAgICAgICAgICBpZDogJ3dhbGxldElkJyxcbiAgICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgICBzdWJUeXBlOiAnbGlnaHRuaW5nQ3VzdG9keScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7IGtleXM6IFsnZGVmJywgJ2doaSddLCB3YXRjaE9ubHlBY2NvdW50cyB9LFxuICAgICAgICB9KVxuICAgICAgKSBhcyBMaWdodG5pbmdXYWxsZXQ7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCB3aXRoZHJhdyBvbiBjaGFpbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtczogTGlnaHRuaW5nT25jaGFpbldpdGhkcmF3UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYW1vdW50U2F0OiAxMDAwMDBuLFxuICAgICAgICAgICAgYWRkcmVzczogJ3RiMXB4N2R1M3J4cHQ1bXF0bXZhdXhtcGw3eGsycXNtdjV4bXo5Zzd3NWRycHp6dWVseDg2OWRxd2FwZTdrJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBzYXRzUGVyVmJ5dGU6IDE1bixcbiAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkMTIzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB1bnNpZ25lZFBzYnRIZXggPVxuICAgICAgICAnNzA3MzYyNzRmZjAxMDA3ZDAyMDAwMDAwMDE1ZTUwYjhkOTZjZWJkYzMyNzNkOWExMDBlYjY4MzkyZDk4MGQ1YjkzNGI4MTcwYzgwYTIzNDg4YjU5NTI2OGNhMDEwMDAwMDAwMGZmZmZmZmZmMDJhMDg2MDEwMDAwMDAwMDAwMjI1MTIwMzc5YmM4OGNjMTVkMzYwNWVkOWRlMWI2MWZmOGQ2NTAyMWI2NTBkYjExNTFlNzUxYTMwODg1Y2NmY2M3ZDE1YWZmYTgwYTAwMDAwMDAwMDAxNjAwMTQ4MGEwNmYyZTZiNzdlODE3ZmQ1ZGU2ZTQxZWE1MTJjNTYzYzI2Y2I4MDAwMDAwMDAwMDAxMDBlYTAyMDAwMDAwMDAwMTAxYTE1OGQ4MDY3MzViYjdjNTRlNGM3MDFkNGY1ODIxY2Q1MzQyZDQ4ZDVlMWZjYmVkMTE2OWU2ZTQ1YWE0NDRiZTAxMDAwMDAwMDBmZmZmZmZmZjAyYTA4NjAxMDAwMDAwMDAwMDIyNTEyMDM3OWJjODhjYzE1ZDM2MDVlZDlkZTFiNjFmZjhkNjUwMjFiNjUwZGIxMTUxZTc1MWEzMDg4NWNjZmNjN2QxNWE2YTMxMGMwMDAwMDAwMDAwMTYwMDE0NzhhNWQ5OGM3MTYwNDg0YjliMDBmMTc4MjgwM2M1OGVkZmM0OWI5YTAyNDczMDQ0MDIyMDQwN2Q5MTYyZjUyMzcxZGYyNDZkY2ZhMjk0M2Q0MGZiZGNiMGQ0YjY3NjhmNzY4MmM2NTE5MzM3OGIyODQ1YTYwMjIwMTAxYzdiYzQ2MGM5M2QyOTc2OTYxYWMyMzQwMGYwZjEwYzE0NWVmYjk4OWEzYWRkYjdmMDNlYmFhYTIyMDA5NTAxMjEwMzdlMTc0NDRjODVjOGI3ZGEwN2YxMmZkNTNjYjJjYTE0MmMyYjQ5MzJkMGY4OTg2NDljNGI1YmUwMDIxZGEwOTgwMDAwMDAwMDAxMDMwNDAxMDAwMDAwMjIwNjAyZTU3MTQ2ZTViNDc2MmE3ZmYzNzRhZGY0MDcyMDQ3YjY3ZWYxMTVhZDQ2YTM0MTg5YmRlYjZhNGY4OGRiOWIwODE4MDAwMDAwMDA1NDAwMDA4MDAwMDAwMDgwMDAwMDAwODAwMTAwMDAwMDA2MDAwMDAwMDAwMDIyMDIwMzc5YWJiZTQ0MDA0ZmY3ZTUyN2JkZWUzZGQ4ZDk1ZTVjZDI1MDA1M2YzNWVlOTIyNThiOTdhYTgzZGZhOTNjNjIxODAwMDAwMDAwNTQwMDAwODAwMDAwMDA4MDAwMDAwMDgwMDEwMDAwMDA1MDAwMDAwMDAwJztcblxuICAgICAgY29uc3QgdHhSZXF1ZXN0UmVzcG9uc2UgPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAndHhSZXExMjMnLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdEZWxpdmVyeScsXG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiB1bnNpZ25lZFBzYnRIZXgsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFJlcXVlc3RXaXRoU2lnbmF0dXJlUmVzcG9uc2UgPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAndHhSZXExMjMnLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdEZWxpdmVyeScsXG4gICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVuc2lnbmVkVHg6IHtcbiAgICAgICAgICAgICAgc2VyaWFsaXplZFR4SGV4OiB1bnNpZ25lZFBzYnRIZXgsXG4gICAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICAgIHNpZ25hdHVyZTogJ3NvbWVTaWduYXR1cmUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZmluYWxXaXRoZHJhd1Jlc3BvbnNlID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxMTIzJyxcbiAgICAgICAgc3RhdGU6ICdkZWxpdmVyZWQnLFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogdW5zaWduZWRQc2J0SGV4LFxuICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgICBzaWduYXR1cmU6ICdzb21lU2lnbmF0dXJlJyxcbiAgICAgICAgICAgICAgICBzdGF0dXM6ICdkZWxpdmVyZWQnLFxuICAgICAgICAgICAgICAgIHR4aWQ6ICd0eDEyMycsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0cmFuc2ZlclJlc3BvbnNlID0ge1xuICAgICAgICBlbnRyaWVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ3RiMXFyNTR6cWtmMHNqd2R5Y3lndWxrY3V3MGF1ZG04bjZyNzd4ajNxNicsXG4gICAgICAgICAgICB3YWxsZXQ6ICc2ODQ2OTE4MzgxZjExOGNjNDJjMzM1YjAzNzkyOTY2NScsXG4gICAgICAgICAgICB2YWx1ZTogLTEwMDAwMDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJy0xMDAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICd0YjFxbWRkbGU4bmhuamN2OTN0MHFucjJ0bWh2dnhmZW00cHB4cTRyemMnLFxuICAgICAgICAgICAgdmFsdWU6IDQ5ODU5MCxcbiAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnNDk4NTkwJyxcbiAgICAgICAgICAgIGlzQ2hhbmdlOiB0cnVlLFxuICAgICAgICAgICAgaXNQYXlHbzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAndGIxcWpxNDhjcWsydTgwaGV3ZGNuZGY1MzltOG5ubnZ0ODQ1M2tyMjNoJyxcbiAgICAgICAgICAgIHZhbHVlOiA1MDAwMDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzUwMDAwMCcsXG4gICAgICAgICAgICBpc0NoYW5nZTogZmFsc2UsXG4gICAgICAgICAgICBpc1BheUdvOiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpZDogJzY4NDY5MTg0ODFmMTE4Y2M0MmMzMzYxMTQxMDkwNmU1JyxcbiAgICAgICAgY29pbjogJ3RsbmJ0YycsXG4gICAgICAgIHdhbGxldDogJ3dhbGxldElkJyxcbiAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgIGVudGVycHJpc2U6ICc2ODQ2OTE4MzgxZjExOGNjNDJjMzM1NGZmMDVkNzJkOCcsXG4gICAgICAgIG9yZ2FuaXphdGlvbjogJzY4NDY5MTgzODFmMTE4Y2M0MmMzMzU1ZjY4MDdkMTFlJyxcbiAgICAgICAgdHhpZFR5cGU6ICd0cmFuc2FjdGlvbkhhc2gnLFxuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxMTIzJyxcbiAgICAgICAgaGVpZ2h0OiA5OTk5OTk5OTksXG4gICAgICAgIGhlaWdodElkOiAnOTk5OTk5OTk5LTY4NDY5MTg0ODFmMTE4Y2M0MmMzMzYxMTQxMDkwNmU1JyxcbiAgICAgICAgZGF0ZTogJzIwMjUtMDYtMDlUMDc6NDc6MTYuMDkwWicsXG4gICAgICAgIHR5cGU6ICdzZW5kJyxcbiAgICAgICAgdmFsdWU6IC0xMDAwMDAwLFxuICAgICAgICB2YWx1ZVN0cmluZzogJy0xMDAwMDAwJyxcbiAgICAgICAgaW50ZW5kZWRWYWx1ZVN0cmluZzogJy0xMDAwMDAwJyxcbiAgICAgICAgYmFzZVZhbHVlOiAtOTk4NTkwLFxuICAgICAgICBiYXNlVmFsdWVTdHJpbmc6ICctOTk4NTkwJyxcbiAgICAgICAgYmFzZVZhbHVlV2l0aG91dEZlZXM6IC05OTg1OTAsXG4gICAgICAgIGJhc2VWYWx1ZVdpdGhvdXRGZWVzU3RyaW5nOiAnLTk5ODU5MCcsXG4gICAgICAgIGZlZVN0cmluZzogJzE0MTAnLFxuICAgICAgICBwYXlHb0ZlZTogMCxcbiAgICAgICAgcGF5R29GZWVTdHJpbmc6ICcwJyxcbiAgICAgICAgdXNkOiAtMS4yMzQ1NixcbiAgICAgICAgdXNkUmF0ZTogMTIzNDU2LFxuICAgICAgICBzdGF0ZTogJ2luaXRpYWxpemVkJyxcbiAgICAgICAgaW5zdGFudDogZmFsc2UsXG4gICAgICAgIGlzUmV3YXJkOiBmYWxzZSxcbiAgICAgICAgaXNVbmxvY2s6IGZhbHNlLFxuICAgICAgICBpc0ZlZTogZmFsc2UsXG4gICAgICAgIHNlbmRlckluZm9ybWF0aW9uVmVyaWZpZWQ6IGZhbHNlLFxuICAgICAgICB0YWdzOiBbJzY4NDY5MTgzODFmMTE4Y2M0MmMzMzViMDM3OTI5NjY1JywgJzY4NDY5MTgzODFmMTE4Y2M0MmMzMzU0ZmYwNWQ3MmQ4J10sXG4gICAgICAgIGhpc3Rvcnk6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBkYXRlOiAnMjAyNS0wNi0wOVQwNzo0NzoxNi4xMDJaJyxcbiAgICAgICAgICAgIHVzZXI6ICc2ODQ2OTE4MjgxZjExOGNjNDJjMzMzNTI3NzlkZjg4ZicsXG4gICAgICAgICAgICBhY3Rpb246ICdjcmVhdGVkJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBpc09mZmNoYWluOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgbWV0YWRhdGE6IFtdLFxuICAgICAgICBjcmVhdGVkVGltZTogJzIwMjUtMDYtMDlUMDc6NDc6MTYuMTAyWicsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjcmVhdGVUeFJlcXVlc3ROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS90eHJlcXVlc3RzYClcbiAgICAgICAgLnJlcGx5KDIwMCwgdHhSZXF1ZXN0UmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCBzdG9yZVNpZ25hdHVyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucHV0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdFJlc3BvbnNlLnR4UmVxdWVzdElkfS9jb2luU3BlY2lmaWNgKVxuICAgICAgICAucmVwbHkoMjAwLCB0eFJlcXVlc3RXaXRoU2lnbmF0dXJlUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCBjcmVhdGVUcmFuc2Zlck5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi93YWxsZXQvJHt3YWxsZXQud2FsbGV0LmlkKCl9L3R4cmVxdWVzdHMvJHt0eFJlcXVlc3RSZXNwb25zZS50eFJlcXVlc3RJZH0vdHJhbnNmZXJzYClcbiAgICAgICAgLnJlcGx5KDIwMCwgdHJhbnNmZXJSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IHNlbmRUeFJlcXVlc3ROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS90eHJlcXVlc3RzLyR7dHhSZXF1ZXN0UmVzcG9uc2UudHhSZXF1ZXN0SWR9L3RyYW5zYWN0aW9ucy8wL3NlbmRgKVxuICAgICAgICAucmVwbHkoMjAwLCBmaW5hbFdpdGhkcmF3UmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCB1c2VyQXV0aEtleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2RlZicpXG4gICAgICAgIC5yZXBseSgyMDAsIHVzZXJBdXRoS2V5KTtcbiAgICAgIGNvbnN0IG5vZGVBdXRoS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXkvZ2hpJylcbiAgICAgICAgLnJlcGx5KDIwMCwgbm9kZUF1dGhLZXkpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldC53aXRoZHJhd09uY2hhaW4ocGFyYW1zKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXNwb25zZS50eFJlcXVlc3RJZCwgJ3R4UmVxMTIzJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzcG9uc2UudHhSZXF1ZXN0U3RhdGUsICdkZWxpdmVyZWQnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXNwb25zZS53aXRoZHJhd1N0YXR1cz8uc3RhdHVzLCAnZGVsaXZlcmVkJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzcG9uc2Uud2l0aGRyYXdTdGF0dXM/LnR4aWQsICd0eDEyMycpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKChyZXNwb25zZS53aXRoZHJhd1N0YXR1cyBhcyBhbnkpLnNpZ25hdHVyZSwgdW5kZWZpbmVkKTtcblxuICAgICAgdXNlckF1dGhLZXlOb2NrLmRvbmUoKTtcbiAgICAgIG5vZGVBdXRoS2V5Tm9jay5kb25lKCk7XG4gICAgICBjcmVhdGVUeFJlcXVlc3ROb2NrLmRvbmUoKTtcbiAgICAgIHN0b3JlU2lnbmF0dXJlTm9jay5kb25lKCk7XG4gICAgICBjcmVhdGVUcmFuc2Zlck5vY2suZG9uZSgpO1xuICAgICAgc2VuZFR4UmVxdWVzdE5vY2suZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgcGVuZGluZyBhcHByb3ZhbCB3aGVuIHdpdGhkcmF3aW5nIG9uY2hhaW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXM6IExpZ2h0bmluZ09uY2hhaW5XaXRoZHJhd1BhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFtb3VudFNhdDogMTAwMDAwbixcbiAgICAgICAgICAgIGFkZHJlc3M6ICd0YjFweDdkdTNyeHB0NW1xdG12YXV4bXBsN3hrMnFzbXY1eG16OWc3dzVkcnB6enVlbHg4NjlkcXdhcGU3aycsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgc2F0c1BlclZieXRlOiAxNW4sXG4gICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZDEyMycsXG4gICAgICB9O1xuICAgICAgY29uc3QgdW5zaWduZWRQc2J0SGV4ID1cbiAgICAgICAgJzcwNzM2Mjc0ZmYwMTAwN2QwMjAwMDAwMDAxNWU1MGI4ZDk2Y2ViZGMzMjczZDlhMTAwZWI2ODM5MmQ5ODBkNWI5MzRiODE3MGM4MGEyMzQ4OGI1OTUyNjhjYTAxMDAwMDAwMDBmZmZmZmZmZjAyYTA4NjAxMDAwMDAwMDAwMDIyNTEyMDM3OWJjODhjYzE1ZDM2MDVlZDlkZTFiNjFmZjhkNjUwMjFiNjUwZGIxMTUxZTc1MWEzMDg4NWNjZmNjN2QxNWFmZmE4MGEwMDAwMDAwMDAwMTYwMDE0ODBhMDZmMmU2Yjc3ZTgxN2ZkNWRlNmU0MWVhNTEyYzU2M2MyNmNiODAwMDAwMDAwMDAwMTAwZWEwMjAwMDAwMDAwMDEwMWExNThkODA2NzM1YmI3YzU0ZTRjNzAxZDRmNTgyMWNkNTM0MmQ0OGQ1ZTFmY2JlZDExNjllNmU0NWFhNDQ0YmUwMTAwMDAwMDAwZmZmZmZmZmYwMmEwODYwMTAwMDAwMDAwMDAyMjUxMjAzNzliYzg4Y2MxNWQzNjA1ZWQ5ZGUxYjYxZmY4ZDY1MDIxYjY1MGRiMTE1MWU3NTFhMzA4ODVjY2ZjYzdkMTVhNmEzMTBjMDAwMDAwMDAwMDE2MDAxNDc4YTVkOThjNzE2MDQ4NGI5YjAwZjE3ODI4MDNjNThlZGZjNDliOWEwMjQ3MzA0NDAyMjA0MDdkOTE2MmY1MjM3MWRmMjQ2ZGNmYTI5NDNkNDBmYmRjYjBkNGI2NzY4Zjc2ODJjNjUxOTMzNzhiMjg0NWE2MDIyMDEwMWM3YmM0NjBjOTNkMjk3Njk2MWFjMjM0MDBmMGYxMGMxNDVlZmI5ODlhM2FkZGI3ZjAzZWJhYWEyMjAwOTUwMTIxMDM3ZTE3NDQ0Yzg1YzhiN2RhMDdmMTJmZDUzY2IyY2ExNDJjMmI0OTMyZDBmODk4NjQ5YzRiNWJlMDAyMWRhMDk4MDAwMDAwMDAwMTAzMDQwMTAwMDAwMDIyMDYwMmU1NzE0NmU1YjQ3NjJhN2ZmMzc0YWRmNDA3MjA0N2I2N2VmMTE1YWQ0NmEzNDE4OWJkZWI2YTRmODhkYjliMDgxODAwMDAwMDAwNTQwMDAwODAwMDAwMDA4MDAwMDAwMDgwMDEwMDAwMDAwNjAwMDAwMDAwMDAyMjAyMDM3OWFiYmU0NDAwNGZmN2U1MjdiZGVlM2RkOGQ5NWU1Y2QyNTAwNTNmMzVlZTkyMjU4Yjk3YWE4M2RmYTkzYzYyMTgwMDAwMDAwMDU0MDAwMDgwMDAwMDAwODAwMDAwMDA4MDAxMDAwMDAwNTAwMDAwMDAwMCc7XG5cbiAgICAgIGNvbnN0IHR4UmVxdWVzdFJlc3BvbnNlID0ge1xuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4UmVxMTIzJyxcbiAgICAgICAgc3RhdGU6ICdwZW5kaW5nQXBwcm92YWwnLFxuICAgICAgICBwZW5kaW5nQXBwcm92YWxJZDogJ2FwcHJvdmFsMTIzJyxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdW5zaWduZWRUeDoge1xuICAgICAgICAgICAgICBzZXJpYWxpemVkVHhIZXg6IHVuc2lnbmVkUHNidEhleCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFJlcXVlc3RXaXRoU2lnbmF0dXJlUmVzcG9uc2UgPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAndHhSZXExMjMnLFxuICAgICAgICBzdGF0ZTogJ3BlbmRpbmdBcHByb3ZhbCcsXG4gICAgICAgIHBlbmRpbmdBcHByb3ZhbElkOiAnYXBwcm92YWwxMjMnLFxuICAgICAgICB0cmFuc2FjdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1bnNpZ25lZFR4OiB7XG4gICAgICAgICAgICAgIHNlcmlhbGl6ZWRUeEhleDogdW5zaWduZWRQc2J0SGV4LFxuICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgICBzaWduYXR1cmU6ICdzb21lU2lnbmF0dXJlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBlbmRpbmdBcHByb3ZhbERhdGE6IFBlbmRpbmdBcHByb3ZhbERhdGEgPSB7XG4gICAgICAgIGlkOiAnYXBwcm92YWwxMjMnLFxuICAgICAgICBzdGF0ZTogU3RhdGUuUEVORElORyxcbiAgICAgICAgY3JlYXRvcjogJ3VzZXIxMjMnLFxuICAgICAgICBpbmZvOiB7XG4gICAgICAgICAgdHlwZTogVHlwZS5UUkFOU0FDVElPTl9SRVFVRVNULFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY3JlYXRlVHhSZXF1ZXN0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vdHhyZXF1ZXN0c2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHR4UmVxdWVzdFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgZ2V0UGVuZGluZ0FwcHJvdmFsTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvJHtjb2luTmFtZX0vcGVuZGluZ2FwcHJvdmFscy8ke3R4UmVxdWVzdFJlc3BvbnNlLnBlbmRpbmdBcHByb3ZhbElkfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHBlbmRpbmdBcHByb3ZhbERhdGEpO1xuXG4gICAgICBjb25zdCB1c2VyQXV0aEtleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyLycgKyBjb2luTmFtZSArICcva2V5L2RlZicpXG4gICAgICAgIC5yZXBseSgyMDAsIHVzZXJBdXRoS2V5KTtcbiAgICAgIGNvbnN0IG5vZGVBdXRoS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvJyArIGNvaW5OYW1lICsgJy9rZXkvZ2hpJylcbiAgICAgICAgLnJlcGx5KDIwMCwgbm9kZUF1dGhLZXkpO1xuXG4gICAgICBjb25zdCBzdG9yZVNpZ25hdHVyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucHV0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vdHhyZXF1ZXN0cy8ke3R4UmVxdWVzdFJlc3BvbnNlLnR4UmVxdWVzdElkfS9jb2luU3BlY2lmaWNgKVxuICAgICAgICAucmVwbHkoMjAwLCB0eFJlcXVlc3RXaXRoU2lnbmF0dXJlUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldC53aXRoZHJhd09uY2hhaW4ocGFyYW1zKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXNwb25zZS50eFJlcXVlc3RJZCwgJ3R4UmVxMTIzJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzcG9uc2UudHhSZXF1ZXN0U3RhdGUsICdwZW5kaW5nQXBwcm92YWwnKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5wZW5kaW5nQXBwcm92YWwpO1xuXG4gICAgICB1c2VyQXV0aEtleU5vY2suZG9uZSgpO1xuICAgICAgbm9kZUF1dGhLZXlOb2NrLmRvbmUoKTtcbiAgICAgIHN0b3JlU2lnbmF0dXJlTm9jay5kb25lKCk7XG4gICAgICBjcmVhdGVUeFJlcXVlc3ROb2NrLmRvbmUoKTtcbiAgICAgIGdldFBlbmRpbmdBcHByb3ZhbE5vY2suZG9uZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndHJhbnNhY3Rpb25zJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCB3YWxsZXQ6IExpZ2h0bmluZ1dhbGxldDtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgd2FsbGV0ID0gZ2V0TGlnaHRuaW5nV2FsbGV0KFxuICAgICAgICBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwge1xuICAgICAgICAgIGlkOiAnd2FsbGV0SWQnLFxuICAgICAgICAgIGNvaW46ICd0bG5idGMnLFxuICAgICAgICAgIHN1YlR5cGU6ICdsaWdodG5pbmdDdXN0b2R5JyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHsga2V5czogWydkZWYnLCAnZ2hpJ10gfSxcbiAgICAgICAgfSlcbiAgICAgICkgYXMgTGlnaHRuaW5nV2FsbGV0O1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsaXN0IHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0ge1xuICAgICAgICBpZDogJ3R4MTIzJyxcbiAgICAgICAgbm9ybWFsaXplZFR4SGFzaDogJ25vcm1hbGl6ZWRIYXNoMTIzJyxcbiAgICAgICAgYmxvY2tIZWlnaHQ6IDEwMDAwMCxcbiAgICAgICAgaW5wdXRJZHM6IFsnaW5wdXQxJywgJ2lucHV0MiddLFxuICAgICAgICBlbnRyaWVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaW5wdXRzOiAxLFxuICAgICAgICAgICAgb3V0cHV0czogMixcbiAgICAgICAgICAgIHZhbHVlOiA1MDAwMCxcbiAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnNTAwMDAnLFxuICAgICAgICAgICAgYWRkcmVzczogJ3Rlc3RBZGRyZXNzJyxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0LndhbGxldC5pZCgpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnaW5wdXQxJyxcbiAgICAgICAgICAgIHZhbHVlOiA1MDAwMCxcbiAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnNTAwMDAnLFxuICAgICAgICAgICAgYWRkcmVzczogJ2lucHV0QWRkcmVzcycsXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldC53YWxsZXQuaWQoKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICdvdXRwdXQxJyxcbiAgICAgICAgICAgIHZhbHVlOiA0OTUwMCxcbiAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnNDk1MDAnLFxuICAgICAgICAgICAgYWRkcmVzczogJ291dHB1dEFkZHJlc3MnLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXQud2FsbGV0LmlkKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgc2l6ZTogMjUwLFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgnMjAyMy0wMS0wMVQwMDowMDowMFonKSxcbiAgICAgICAgZmVlOiA1MDAsXG4gICAgICAgIGZlZVN0cmluZzogJzUwMCcsXG4gICAgICAgIGhleDogJ2RlYWRiZWVmJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogNixcbiAgICAgIH07XG4gICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgbGltaXQ6IDEwMG4sXG4gICAgICAgIHN0YXJ0RGF0ZTogbmV3IERhdGUoKSxcbiAgICAgIH07XG4gICAgICBjb25zdCBsaXN0VHJhbnNhY3Rpb25zTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS9saWdodG5pbmcvdHJhbnNhY3Rpb25gKVxuICAgICAgICAucXVlcnkoVHJhbnNhY3Rpb25RdWVyeS5lbmNvZGUocXVlcnkpKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHRyYW5zYWN0aW9uczogW3RyYW5zYWN0aW9uXSB9KTtcbiAgICAgIGNvbnN0IGxpc3RUcmFuc2FjdGlvbnNSZXNwb25zZSA9IGF3YWl0IHdhbGxldC5saXN0VHJhbnNhY3Rpb25zKHF1ZXJ5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChsaXN0VHJhbnNhY3Rpb25zUmVzcG9uc2UudHJhbnNhY3Rpb25zLmxlbmd0aCwgMSk7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGxpc3RUcmFuc2FjdGlvbnNSZXNwb25zZS50cmFuc2FjdGlvbnNbMF0sIHRyYW5zYWN0aW9uKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChsaXN0VHJhbnNhY3Rpb25zUmVzcG9uc2UubmV4dEJhdGNoUHJldklkLCB1bmRlZmluZWQpO1xuICAgICAgbGlzdFRyYW5zYWN0aW9uc05vY2suZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB3b3JrIHByb3Blcmx5IHdpdGggcGFnaW5hdGlvbiB3aGlsZSBsaXN0aW5nIHRyYW5zYWN0aW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uMSA9IHtcbiAgICAgICAgaWQ6ICd0eDEyMycsXG4gICAgICAgIG5vcm1hbGl6ZWRUeEhhc2g6ICdub3JtYWxpemVkSGFzaDEyMycsXG4gICAgICAgIGJsb2NrSGVpZ2h0OiAxMDAwMDAsXG4gICAgICAgIGlucHV0SWRzOiBbJ2lucHV0MScsICdpbnB1dDInXSxcbiAgICAgICAgZW50cmllczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlucHV0czogMSxcbiAgICAgICAgICAgIG91dHB1dHM6IDIsXG4gICAgICAgICAgICB2YWx1ZTogNTAwMDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzUwMDAwJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICd0ZXN0QWRkcmVzcycsXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldC53YWxsZXQuaWQoKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJ2lucHV0MScsXG4gICAgICAgICAgICB2YWx1ZTogNTAwMDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzUwMDAwJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICdpbnB1dEFkZHJlc3MnLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXQud2FsbGV0LmlkKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnb3V0cHV0MScsXG4gICAgICAgICAgICB2YWx1ZTogNDk1MDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzQ5NTAwJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICdvdXRwdXRBZGRyZXNzJyxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0LndhbGxldC5pZCgpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHNpemU6IDI1MCxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoJzIwMjMtMDEtMDFUMDA6MDA6MDBaJyksXG4gICAgICAgIGZlZTogNTAwLFxuICAgICAgICBmZWVTdHJpbmc6ICc1MDAnLFxuICAgICAgICBoZXg6ICdkZWFkYmVlZicsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDYsXG4gICAgICB9O1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24yID0ge1xuICAgICAgICAuLi50cmFuc2FjdGlvbjEsXG4gICAgICAgIGlkOiAndHg0NTYnLFxuICAgICAgICBub3JtYWxpemVkVHhIYXNoOiAnbm9ybWFsaXplZEhhc2g0NTYnLFxuICAgICAgICBibG9ja0hlaWdodDogMTAwMDAxLFxuICAgICAgICBkYXRlOiBuZXcgRGF0ZSgnMjAyMy0wMS0wMlQwMDowMDowMFonKSxcbiAgICAgIH07XG4gICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgbGltaXQ6IDJuLFxuICAgICAgICBzdGFydERhdGU6IG5ldyBEYXRlKCcyMDIzLTAxLTAxJyksXG4gICAgICB9O1xuICAgICAgY29uc3QgbGlzdFRyYW5zYWN0aW9uc05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldC53YWxsZXQuaWQoKX0vbGlnaHRuaW5nL3RyYW5zYWN0aW9uYClcbiAgICAgICAgLnF1ZXJ5KFRyYW5zYWN0aW9uUXVlcnkuZW5jb2RlKHF1ZXJ5KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyB0cmFuc2FjdGlvbnM6IFt0cmFuc2FjdGlvbjEsIHRyYW5zYWN0aW9uMl0sIG5leHRCYXRjaFByZXZJZDogdHJhbnNhY3Rpb24yLmlkIH0pO1xuICAgICAgY29uc3QgbGlzdFRyYW5zYWN0aW9uc1Jlc3BvbnNlID0gYXdhaXQgd2FsbGV0Lmxpc3RUcmFuc2FjdGlvbnMocXVlcnkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGxpc3RUcmFuc2FjdGlvbnNSZXNwb25zZS50cmFuc2FjdGlvbnMubGVuZ3RoLCAyKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwobGlzdFRyYW5zYWN0aW9uc1Jlc3BvbnNlLnRyYW5zYWN0aW9uc1swXSwgdHJhbnNhY3Rpb24xKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwobGlzdFRyYW5zYWN0aW9uc1Jlc3BvbnNlLnRyYW5zYWN0aW9uc1sxXSwgdHJhbnNhY3Rpb24yKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChsaXN0VHJhbnNhY3Rpb25zUmVzcG9uc2UubmV4dEJhdGNoUHJldklkLCB0cmFuc2FjdGlvbjIuaWQpO1xuICAgICAgbGlzdFRyYW5zYWN0aW9uc05vY2suZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgcHJldklkIHBhcmFtZXRlciBmb3IgcGFnaW5hdGlvbiBjdXJzb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbjMgPSB7XG4gICAgICAgIGlkOiAndHg3ODknLFxuICAgICAgICBub3JtYWxpemVkVHhIYXNoOiAnbm9ybWFsaXplZEhhc2g3ODknLFxuICAgICAgICBibG9ja0hlaWdodDogMTAwMDAyLFxuICAgICAgICBpbnB1dElkczogWydpbnB1dDEnXSxcbiAgICAgICAgZW50cmllczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlucHV0czogMSxcbiAgICAgICAgICAgIG91dHB1dHM6IDEsXG4gICAgICAgICAgICB2YWx1ZTogNDAwMDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzQwMDAwJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICd0ZXN0QWRkcmVzcycsXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldC53YWxsZXQuaWQoKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJ2lucHV0MScsXG4gICAgICAgICAgICB2YWx1ZTogNDAwMDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzQwMDAwJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICdpbnB1dEFkZHJlc3MnLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXQud2FsbGV0LmlkKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnb3V0cHV0MScsXG4gICAgICAgICAgICB2YWx1ZTogMzk1MDAsXG4gICAgICAgICAgICB2YWx1ZVN0cmluZzogJzM5NTAwJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICdvdXRwdXRBZGRyZXNzJyxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0LndhbGxldC5pZCgpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHNpemU6IDIwMCxcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoJzIwMjMtMDEtMDNUMDA6MDA6MDBaJyksXG4gICAgICAgIGZlZTogNTAwLFxuICAgICAgICBmZWVTdHJpbmc6ICc1MDAnLFxuICAgICAgICBoZXg6ICdjYWZlYmFiZScsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDQsXG4gICAgICB9O1xuICAgICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICAgIGxpbWl0OiAxbixcbiAgICAgICAgcHJldklkOiAndHg0NTYnLCAvLyBDb250aW51ZSBmcm9tIHRoaXMgdHJhbnNhY3Rpb24gSURcbiAgICAgIH07XG4gICAgICBjb25zdCBsaXN0VHJhbnNhY3Rpb25zTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0LndhbGxldC5pZCgpfS9saWdodG5pbmcvdHJhbnNhY3Rpb25gKVxuICAgICAgICAucXVlcnkoVHJhbnNhY3Rpb25RdWVyeS5lbmNvZGUocXVlcnkpKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHRyYW5zYWN0aW9uczogW3RyYW5zYWN0aW9uM10gfSk7XG4gICAgICBjb25zdCBsaXN0VHJhbnNhY3Rpb25zUmVzcG9uc2UgPSBhd2FpdCB3YWxsZXQubGlzdFRyYW5zYWN0aW9ucyhxdWVyeSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwobGlzdFRyYW5zYWN0aW9uc1Jlc3BvbnNlLnRyYW5zYWN0aW9ucy5sZW5ndGgsIDEpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChsaXN0VHJhbnNhY3Rpb25zUmVzcG9uc2UudHJhbnNhY3Rpb25zWzBdLCB0cmFuc2FjdGlvbjMpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGxpc3RUcmFuc2FjdGlvbnNSZXNwb25zZS5uZXh0QmF0Y2hQcmV2SWQsIHVuZGVmaW5lZCk7XG4gICAgICBsaXN0VHJhbnNhY3Rpb25zTm9jay5kb25lKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=