PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-stx/dist/test/unit/transactionBuilder
Просмотр файла: contractBuilder.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const should_1 = __importDefault(require("should"));
const bn_js_1 = __importDefault(require("bn.js"));
const network_1 = require("@stacks/network");
const sdk_core_1 = require("@bitgo/sdk-core");
const transactions_1 = require("@stacks/transactions");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_api_1 = require("@bitgo/sdk-api");
const statics_1 = require("@bitgo/statics");
const src_1 = require("../../../src");
const testData = __importStar(require("../resources"));
const { stringifyCv } = src_1.StxLib.Utils;
describe('Stacks: Contract Builder', function () {
const coinName = 'stx';
const coinNameTest = 'tstx';
let bitgo;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, {
env: 'mock',
});
bitgo.initializeTestVars();
bitgo.safeRegister('stx', src_1.Stx.createInstance);
bitgo.safeRegister('tstx', src_1.Tstx.createInstance);
});
describe('Stx Contract call Builder', () => {
const factory = new src_1.StxLib.TransactionBuilderFactory(statics_1.coins.get(coinNameTest));
const factoryProd = new src_1.StxLib.TransactionBuilderFactory(statics_1.coins.get(coinName));
const initTxBuilder = () => {
const txBuilder = factory.getContractBuilder();
txBuilder.fee({ fee: '180' });
txBuilder.nonce(0);
txBuilder.contractAddress(testData.CONTRACT_ADDRESS);
txBuilder.contractName(testData.CONTRACT_NAME);
txBuilder.functionName(testData.CONTRACT_FUNCTION_NAME);
return txBuilder;
};
describe('contract builder environment', function () {
it('should select the right network', function () {
should_1.default.equal(factory.getTransferBuilder().coinName(), 'tstx');
should_1.default.equal(factoryProd.getTransferBuilder().coinName(), 'stx');
// used type any to access protected properties
const txBuilder = factory.getTransferBuilder();
const txBuilderProd = factoryProd.getTransferBuilder();
txBuilder._network.should.deepEqual(new network_1.StacksTestnet());
txBuilderProd._network.should.deepEqual(new network_1.StacksMainnet());
});
});
describe('should build ', () => {
it('an unsigned contract call transaction', async () => {
const builder = initTxBuilder();
builder.functionArgs([
{ type: 'uint128', val: '400000000' },
{ type: 'principal', val: testData.ACCOUNT_2.address },
{ type: 'optional', val: { type: 'uint128', val: '200' } },
{
type: 'optional',
val: {
type: 'tuple',
val: [
{ key: 'hashbytes', type: 'buffer', val: Buffer.from('some-hash') },
{ key: 'version', type: 'buffer', val: new bn_js_1.default(1).toBuffer() },
],
},
},
]);
builder.fromPubKey(testData.TX_SENDER.pub);
builder.numberSignatures(1);
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.UNSIGNED_CONTRACT_CALL);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.CONTRACT_ADDRESS);
tx.outputs[0].value.should.equal('0');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('0');
});
it('an unsigned self stacking contract call transaction', async () => {
const builder = initTxBuilder();
/* Contract call in clarity POX-4
(define-public (stack-stx (amount-ustx uint)
(pox-addr (tuple (version (buff 1)) (hashbytes (buff 32))))
(start-burn-ht uint)
(lock-period uint)
(signer-sig (optional (buff 65)))
(signer-key (buff 33))
(max-amount uint)
(auth-id uint))
*/
builder.functionArgs([
{ type: 'uint128', val: '400000000' },
{
type: 'tuple',
val: [
{ key: 'hashbytes', type: 'buffer', val: Buffer.from('some-hash') },
{ key: 'version', type: 'buffer', val: new bn_js_1.default(1).toBuffer() },
],
},
{ type: 'uint128', val: '52800' },
{ type: 'uint128', val: '2' },
// Nakamoto upgrade new 4 parameters
// https://docs.stacks.co/nakamoto-upgrade/signing-and-stacking/stacking-flow#solo-stacker-flow
{ type: 'optional', val: { type: 'buffer', val: Buffer.from('some-hash') } },
{ type: 'buffer', val: Buffer.from('some-hash') },
{ type: 'uint128', val: '340282366920938463463374607431768211455' },
{ type: 'uint128', val: '123456' },
]);
builder.fromPubKey(testData.TX_SENDER.pub);
builder.numberSignatures(1);
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.UNSIGNED_SELF_STACK_CONTRACT_CALL);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.CONTRACT_ADDRESS);
tx.outputs[0].value.should.equal('0');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('0');
});
it('a signed contract call with args', async () => {
const builder = initTxBuilder();
builder.functionArgs([
{ type: 'uint128', val: '400000000' },
{ type: 'principal', val: testData.ACCOUNT_2.address },
{ type: 'optional' },
{
type: 'optional',
val: {
type: 'tuple',
val: [
{ key: 'hashbytes', type: 'buffer', val: Buffer.from('some-hash') },
{ key: 'version', type: 'buffer', val: new bn_js_1.default(1).toBuffer() },
],
},
},
]);
builder.sign({ key: testData.TX_SENDER.prv });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_CONTRACT_WITH_ARGS);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.CONTRACT_ADDRESS);
tx.outputs[0].value.should.equal('0');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('0');
});
it('a signed self stacking contract call', async () => {
const builder = initTxBuilder();
/* Contract call in clarity POX-4
(define-public (stack-stx (amount-ustx uint)
(pox-addr (tuple (version (buff 1)) (hashbytes (buff 32))))
(start-burn-ht uint)
(lock-period uint)
(signer-sig (optional (buff 65)))
(signer-key (buff 33))
(max-amount uint)
(auth-id uint))
*/
builder.functionArgs([
{ type: 'uint128', val: '400000000' },
{
type: 'tuple',
val: [
{ key: 'hashbytes', type: 'buffer', val: Buffer.from('some-hash') },
{ key: 'version', type: 'buffer', val: new bn_js_1.default(1).toBuffer() },
],
},
{ type: 'uint128', val: '52800' },
{ type: 'uint128', val: '2' },
// Nakamoto upgrade new 4 parameters
// https://docs.stacks.co/nakamoto-upgrade/signing-and-stacking/stacking-flow#solo-stacker-flow
{ type: 'optional', val: { type: 'buffer', val: Buffer.from('some-hash') } },
{ type: 'buffer', val: Buffer.from('some-hash') },
{ type: 'uint128', val: '340282366920938463463374607431768211455' },
{ type: 'uint128', val: '123456' },
]);
builder.sign({ key: testData.TX_SENDER.prv });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_SELF_STACK_CONTRACT_CALL);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.CONTRACT_ADDRESS);
tx.outputs[0].value.should.equal('0');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('0');
});
it('a signed contract call transaction', async () => {
const amount = 123;
const builder = initTxBuilder();
builder.functionArgs([{ type: 'optional', val: { type: 'int128', val: amount } }]);
builder.sign({ key: testData.TX_SENDER.prv });
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(txJson.payload.functionArgs, [stringifyCv((0, transactions_1.someCV)((0, transactions_1.intCV)(amount)))]);
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_CONTRACT_CALL);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
});
it('a signed serialized contract call transaction', async () => {
const builder = factory.from(testData.SIGNED_CONTRACT_CALL);
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
should_1.default.deepEqual(txJson.payload.functionArgs, [stringifyCv((0, transactions_1.someCV)((0, transactions_1.intCV)(123)))]);
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_CONTRACT_CALL);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.CONTRACT_ADDRESS);
tx.outputs[0].value.should.equal('0');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('0');
});
it('a signed serialized self stacking contract call transaction', async () => {
const builder = factory.from(testData.SIGNED_SELF_STACK_CONTRACT_CALL);
const tx = await builder.build();
const txJson = tx.toJson();
should_1.default.deepEqual(txJson.payload.contractAddress, testData.CONTRACT_ADDRESS);
should_1.default.deepEqual(txJson.payload.contractName, testData.CONTRACT_NAME);
should_1.default.deepEqual(txJson.payload.functionName, testData.CONTRACT_FUNCTION_NAME);
should_1.default.deepEqual(txJson.nonce, 0);
should_1.default.deepEqual(txJson.fee.toString(), '180');
// Now stacks-stx self-stacking supports 8 parameters
// https://docs.stacks.co/nakamoto-upgrade/signing-and-stacking/stacking-flow#solo-stacker-flow
should_1.default.deepEqual(txJson.payload.functionArgs.length, 8);
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_SELF_STACK_CONTRACT_CALL);
tx.type.should.equal(sdk_core_1.TransactionType.ContractCall);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.CONTRACT_ADDRESS);
tx.outputs[0].value.should.equal('0');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('0');
});
it('a multisig transfer transaction', async () => {
const builder = initTxBuilder();
builder.functionArgs([{ type: 'optional', val: { type: 'int128', val: '123' } }]);
builder.sign({ key: testData.prv1 });
builder.sign({ key: testData.prv2 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
builder.numberSignatures(2);
const tx = await builder.build();
JSON.stringify(tx.toJson());
should_1.default.deepEqual(tx.toBroadcastFormat(), testData.MULTI_SIG_CONTRACT_CALL);
});
describe('ParseCV test', () => {
it('Optional with out value', () => {
const amount = '400000000';
const builder = initTxBuilder();
builder.functionArgs([
{ type: 'uint128', val: amount },
{ type: 'principal', val: testData.ACCOUNT_2.address },
{ type: 'optional' },
{
type: 'optional',
val: {
type: 'tuple',
val: [
{ key: 'hashbytes', type: 'buffer', val: Buffer.from('some-hash') },
{ key: 'version', type: 'buffer', val: new bn_js_1.default(1).toBuffer() },
],
},
},
]);
should_1.default.deepEqual(builder._functionArgs, [
(0, transactions_1.uintCV)(amount),
(0, transactions_1.standardPrincipalCV)(testData.ACCOUNT_2.address),
(0, transactions_1.noneCV)(),
(0, transactions_1.someCV)((0, transactions_1.tupleCV)({
hashbytes: (0, transactions_1.bufferCV)(Buffer.from('some-hash')),
version: (0, transactions_1.bufferCV)(new bn_js_1.default(1).toBuffer()),
})),
]);
});
it('use ClarityValue', () => {
const amount = '400000000';
const builder = initTxBuilder();
builder.functionArgs([
(0, transactions_1.uintCV)(amount),
(0, transactions_1.standardPrincipalCV)(testData.ACCOUNT_2.address),
(0, transactions_1.noneCV)(),
(0, transactions_1.someCV)((0, transactions_1.tupleCV)({
hashbytes: (0, transactions_1.bufferCV)(Buffer.from('some-hash')),
version: (0, transactions_1.bufferCV)(new bn_js_1.default(1).toBuffer()),
})),
]);
should_1.default.deepEqual(builder._functionArgs, [
(0, transactions_1.uintCV)(amount),
(0, transactions_1.standardPrincipalCV)(testData.ACCOUNT_2.address),
(0, transactions_1.noneCV)(),
(0, transactions_1.someCV)((0, transactions_1.tupleCV)({
hashbytes: (0, transactions_1.bufferCV)(Buffer.from('some-hash')),
version: (0, transactions_1.bufferCV)(new bn_js_1.default(1).toBuffer()),
})),
]);
});
it('Buffer as string', () => {
const builder = initTxBuilder();
builder.functionArgs([
{ type: 'buffer', val: 'some-hash' },
{ type: 'buffer', val: '1' },
]);
should_1.default.deepEqual(builder._functionArgs, [
(0, transactions_1.bufferCV)(Buffer.from('some-hash')),
(0, transactions_1.bufferCV)(new bn_js_1.default(1).toBuffer()),
]);
});
it('Buffer as number', () => {
const builder = initTxBuilder();
builder.functionArgs([
{ type: 'buffer', val: '1' },
{ type: 'buffer', val: 1 },
]);
should_1.default.deepEqual(builder._functionArgs, [
(0, transactions_1.bufferCV)(new bn_js_1.default(1).toBuffer()),
(0, transactions_1.bufferCV)(new bn_js_1.default(1).toBuffer()),
]);
});
it('invalid type', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.functionArgs([{ type: 'unknow', val: 'any-val' }]), new RegExp('Unexpected Clarity ABI type primitive: "unknow"'));
});
});
describe('should fail', () => {
it('a contract call with an invalid key', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.sign({ key: 'invalidKey' }), /Unsupported private key/);
});
it('a contract call with an invalid contract address', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.contractAddress(testData.ACCOUNT_1.address), /Invalid contract address/);
});
it('a contract call with an invalid contract name pox-2', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.contractName('pox-2'), /Only pox-4 and send-many-memo contracts supported/);
});
it('a contract call with an invalid contract name pox-3', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.contractName('pox-3'), /Only pox-4 and send-many-memo contracts supported/);
});
it('a contract call with an invalid contract function name', () => {
const builder = initTxBuilder();
assert_1.default.throws(() => builder.functionName('test-function'), new RegExp('test-function is not supported contract function name'));
});
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udHJhY3RCdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci9jb250cmFjdEJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsb0RBQTRCO0FBQzVCLGtEQUEyQjtBQUMzQiw2Q0FBK0Q7QUFDL0QsOENBQWtEO0FBQ2xELHVEQUE2RztBQUM3Ryw4Q0FBMEQ7QUFDMUQsNENBQTBDO0FBQzFDLDRDQUF1QztBQUV2QyxzQ0FBaUQ7QUFDakQsdURBQXlDO0FBRXpDLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxZQUFNLENBQUMsS0FBSyxDQUFDO0FBRXJDLFFBQVEsQ0FBQywwQkFBMEIsRUFBRTtJQUNuQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDdkIsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDO0lBQzVCLElBQUksS0FBbUIsQ0FBQztJQUV4QixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRTtZQUNuQyxHQUFHLEVBQUUsTUFBTTtTQUNaLENBQUMsQ0FBQztRQUNILEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzNCLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFNBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM5QyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxVQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO1FBQ3pDLE1BQU0sT0FBTyxHQUFHLElBQUksWUFBTSxDQUFDLHlCQUF5QixDQUFDLGVBQUssQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUM5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QyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IEJpZ051bSBmcm9tICdibi5qcyc7XG5pbXBvcnQgeyBTdGFja3NUZXN0bmV0LCBTdGFja3NNYWlubmV0IH0gZnJvbSAnQHN0YWNrcy9uZXR3b3JrJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBidWZmZXJDViwgbm9uZUNWLCBzb21lQ1YsIHN0YW5kYXJkUHJpbmNpcGFsQ1YsIHR1cGxlQ1YsIHVpbnRDViwgaW50Q1YgfSBmcm9tICdAc3RhY2tzL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstYXBpJztcbmltcG9ydCB7IGNvaW5zIH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuXG5pbXBvcnQgeyBTdHgsIFRzdHgsIFN0eExpYiB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi9yZXNvdXJjZXMnO1xuXG5jb25zdCB7IHN0cmluZ2lmeUN2IH0gPSBTdHhMaWIuVXRpbHM7XG5cbmRlc2NyaWJlKCdTdGFja3M6IENvbnRyYWN0IEJ1aWxkZXInLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGNvaW5OYW1lID0gJ3N0eCc7XG4gIGNvbnN0IGNvaW5OYW1lVGVzdCA9ICd0c3R4JztcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwge1xuICAgICAgZW52OiAnbW9jaycsXG4gICAgfSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdzdHgnLCBTdHguY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndHN0eCcsIFRzdHguY3JlYXRlSW5zdGFuY2UpO1xuICB9KTtcblxuICBkZXNjcmliZSgnU3R4IENvbnRyYWN0IGNhbGwgQnVpbGRlcicsICgpID0+IHtcbiAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFN0eExpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldChjb2luTmFtZVRlc3QpKTtcbiAgICBjb25zdCBmYWN0b3J5UHJvZCA9IG5ldyBTdHhMaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoY29pbk5hbWUpKTtcblxuICAgIGNvbnN0IGluaXRUeEJ1aWxkZXIgPSAoKSA9PiB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldENvbnRyYWN0QnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZTogJzE4MCcgfSk7XG4gICAgICB0eEJ1aWxkZXIubm9uY2UoMCk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3RBZGRyZXNzKHRlc3REYXRhLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0TmFtZSh0ZXN0RGF0YS5DT05UUkFDVF9OQU1FKTtcbiAgICAgIHR4QnVpbGRlci5mdW5jdGlvbk5hbWUodGVzdERhdGEuQ09OVFJBQ1RfRlVOQ1RJT05fTkFNRSk7XG4gICAgICByZXR1cm4gdHhCdWlsZGVyO1xuICAgIH07XG5cbiAgICBkZXNjcmliZSgnY29udHJhY3QgYnVpbGRlciBlbnZpcm9ubWVudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc2VsZWN0IHRoZSByaWdodCBuZXR3b3JrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzaG91bGQuZXF1YWwoZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKS5jb2luTmFtZSgpLCAndHN0eCcpO1xuICAgICAgICBzaG91bGQuZXF1YWwoZmFjdG9yeVByb2QuZ2V0VHJhbnNmZXJCdWlsZGVyKCkuY29pbk5hbWUoKSwgJ3N0eCcpO1xuICAgICAgICAvLyB1c2VkIHR5cGUgYW55IHRvIGFjY2VzcyBwcm90ZWN0ZWQgcHJvcGVydGllc1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXI6IGFueSA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlclByb2Q6IGFueSA9IGZhY3RvcnlQcm9kLmdldFRyYW5zZmVyQnVpbGRlcigpO1xuXG4gICAgICAgIHR4QnVpbGRlci5fbmV0d29yay5zaG91bGQuZGVlcEVxdWFsKG5ldyBTdGFja3NUZXN0bmV0KCkpO1xuICAgICAgICB0eEJ1aWxkZXJQcm9kLl9uZXR3b3JrLnNob3VsZC5kZWVwRXF1YWwobmV3IFN0YWNrc01haW5uZXQoKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzaG91bGQgYnVpbGQgJywgKCkgPT4ge1xuICAgICAgaXQoJ2FuIHVuc2lnbmVkIGNvbnRyYWN0IGNhbGwgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgIGJ1aWxkZXIuZnVuY3Rpb25BcmdzKFtcbiAgICAgICAgICB7IHR5cGU6ICd1aW50MTI4JywgdmFsOiAnNDAwMDAwMDAwJyB9LFxuICAgICAgICAgIHsgdHlwZTogJ3ByaW5jaXBhbCcsIHZhbDogdGVzdERhdGEuQUNDT1VOVF8yLmFkZHJlc3MgfSxcbiAgICAgICAgICB7IHR5cGU6ICdvcHRpb25hbCcsIHZhbDogeyB0eXBlOiAndWludDEyOCcsIHZhbDogJzIwMCcgfSB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6ICdvcHRpb25hbCcsXG4gICAgICAgICAgICB2YWw6IHtcbiAgICAgICAgICAgICAgdHlwZTogJ3R1cGxlJyxcbiAgICAgICAgICAgICAgdmFsOiBbXG4gICAgICAgICAgICAgICAgeyBrZXk6ICdoYXNoYnl0ZXMnLCB0eXBlOiAnYnVmZmVyJywgdmFsOiBCdWZmZXIuZnJvbSgnc29tZS1oYXNoJykgfSxcbiAgICAgICAgICAgICAgICB7IGtleTogJ3ZlcnNpb24nLCB0eXBlOiAnYnVmZmVyJywgdmFsOiBuZXcgQmlnTnVtKDEpLnRvQnVmZmVyKCkgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGJ1aWxkZXIuZnJvbVB1YktleSh0ZXN0RGF0YS5UWF9TRU5ERVIucHViKTtcbiAgICAgICAgYnVpbGRlci5udW1iZXJTaWduYXR1cmVzKDEpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdEFkZHJlc3MsIHRlc3REYXRhLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0TmFtZSwgdGVzdERhdGEuQ09OVFJBQ1RfTkFNRSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuZnVuY3Rpb25OYW1lLCB0ZXN0RGF0YS5DT05UUkFDVF9GVU5DVElPTl9OQU1FKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIDApO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5mZWUudG9TdHJpbmcoKSwgJzE4MCcpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlVOU0lHTkVEX0NPTlRSQUNUX0NBTEwpO1xuXG4gICAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuQ09OVFJBQ1RfQUREUkVTUyk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICAgIHR4LmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuVFhfU0VOREVSLmFkZHJlc3MpO1xuICAgICAgICB0eC5pbnB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FuIHVuc2lnbmVkIHNlbGYgc3RhY2tpbmcgY29udHJhY3QgY2FsbCB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgLyogQ29udHJhY3QgY2FsbCBpbiBjbGFyaXR5IFBPWC00XG4gICAgICAgIChkZWZpbmUtcHVibGljIChzdGFjay1zdHggKGFtb3VudC11c3R4IHVpbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChwb3gtYWRkciAodHVwbGUgKHZlcnNpb24gKGJ1ZmYgMSkpIChoYXNoYnl0ZXMgKGJ1ZmYgMzIpKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChzdGFydC1idXJuLWh0IHVpbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChsb2NrLXBlcmlvZCB1aW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoc2lnbmVyLXNpZyAob3B0aW9uYWwgKGJ1ZmYgNjUpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHNpZ25lci1rZXkgKGJ1ZmYgMzMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAobWF4LWFtb3VudCB1aW50KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoYXV0aC1pZCB1aW50KSlcbiAgICAgICAgICovXG4gICAgICAgIGJ1aWxkZXIuZnVuY3Rpb25BcmdzKFtcbiAgICAgICAgICB7IHR5cGU6ICd1aW50MTI4JywgdmFsOiAnNDAwMDAwMDAwJyB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6ICd0dXBsZScsXG4gICAgICAgICAgICB2YWw6IFtcbiAgICAgICAgICAgICAgeyBrZXk6ICdoYXNoYnl0ZXMnLCB0eXBlOiAnYnVmZmVyJywgdmFsOiBCdWZmZXIuZnJvbSgnc29tZS1oYXNoJykgfSxcbiAgICAgICAgICAgICAgeyBrZXk6ICd2ZXJzaW9uJywgdHlwZTogJ2J1ZmZlcicsIHZhbDogbmV3IEJpZ051bSgxKS50b0J1ZmZlcigpIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyB0eXBlOiAndWludDEyOCcsIHZhbDogJzUyODAwJyB9LFxuICAgICAgICAgIHsgdHlwZTogJ3VpbnQxMjgnLCB2YWw6ICcyJyB9LFxuICAgICAgICAgIC8vIE5ha2Ftb3RvIHVwZ3JhZGUgbmV3IDQgcGFyYW1ldGVyc1xuICAgICAgICAgIC8vIGh0dHBzOi8vZG9jcy5zdGFja3MuY28vbmFrYW1vdG8tdXBncmFkZS9zaWduaW5nLWFuZC1zdGFja2luZy9zdGFja2luZy1mbG93I3NvbG8tc3RhY2tlci1mbG93XG4gICAgICAgICAgeyB0eXBlOiAnb3B0aW9uYWwnLCB2YWw6IHsgdHlwZTogJ2J1ZmZlcicsIHZhbDogQnVmZmVyLmZyb20oJ3NvbWUtaGFzaCcpIH0gfSxcbiAgICAgICAgICB7IHR5cGU6ICdidWZmZXInLCB2YWw6IEJ1ZmZlci5mcm9tKCdzb21lLWhhc2gnKSB9LFxuICAgICAgICAgIHsgdHlwZTogJ3VpbnQxMjgnLCB2YWw6ICczNDAyODIzNjY5MjA5Mzg0NjM0NjMzNzQ2MDc0MzE3NjgyMTE0NTUnIH0sXG4gICAgICAgICAgeyB0eXBlOiAndWludDEyOCcsIHZhbDogJzEyMzQ1NicgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGJ1aWxkZXIuZnJvbVB1YktleSh0ZXN0RGF0YS5UWF9TRU5ERVIucHViKTtcbiAgICAgICAgYnVpbGRlci5udW1iZXJTaWduYXR1cmVzKDEpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdEFkZHJlc3MsIHRlc3REYXRhLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0TmFtZSwgdGVzdERhdGEuQ09OVFJBQ1RfTkFNRSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuZnVuY3Rpb25OYW1lLCB0ZXN0RGF0YS5DT05UUkFDVF9GVU5DVElPTl9OQU1FKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIDApO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5mZWUudG9TdHJpbmcoKSwgJzE4MCcpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlVOU0lHTkVEX1NFTEZfU1RBQ0tfQ09OVFJBQ1RfQ0FMTCk7XG5cbiAgICAgICAgdHgudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0Q2FsbCk7XG4gICAgICAgIHR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5DT05UUkFDVF9BRERSRVNTKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgICAgdHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4LmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5UWF9TRU5ERVIuYWRkcmVzcyk7XG4gICAgICAgIHR4LmlucHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYSBzaWduZWQgY29udHJhY3QgY2FsbCB3aXRoIGFyZ3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgIGJ1aWxkZXIuZnVuY3Rpb25BcmdzKFtcbiAgICAgICAgICB7IHR5cGU6ICd1aW50MTI4JywgdmFsOiAnNDAwMDAwMDAwJyB9LFxuICAgICAgICAgIHsgdHlwZTogJ3ByaW5jaXBhbCcsIHZhbDogdGVzdERhdGEuQUNDT1VOVF8yLmFkZHJlc3MgfSxcbiAgICAgICAgICB7IHR5cGU6ICdvcHRpb25hbCcgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiAnb3B0aW9uYWwnLFxuICAgICAgICAgICAgdmFsOiB7XG4gICAgICAgICAgICAgIHR5cGU6ICd0dXBsZScsXG4gICAgICAgICAgICAgIHZhbDogW1xuICAgICAgICAgICAgICAgIHsga2V5OiAnaGFzaGJ5dGVzJywgdHlwZTogJ2J1ZmZlcicsIHZhbDogQnVmZmVyLmZyb20oJ3NvbWUtaGFzaCcpIH0sXG4gICAgICAgICAgICAgICAgeyBrZXk6ICd2ZXJzaW9uJywgdHlwZTogJ2J1ZmZlcicsIHZhbDogbmV3IEJpZ051bSgxKS50b0J1ZmZlcigpIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlRYX1NFTkRFUi5wcnYgfSk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgYnVpbGRlci5idWlsZCgpO1xuXG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0QWRkcmVzcywgdGVzdERhdGEuQ09OVFJBQ1RfQUREUkVTUyk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuY29udHJhY3ROYW1lLCB0ZXN0RGF0YS5DT05UUkFDVF9OQU1FKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5mdW5jdGlvbk5hbWUsIHRlc3REYXRhLkNPTlRSQUNUX0ZVTkNUSU9OX05BTUUpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5ub25jZSwgMCk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmZlZS50b1N0cmluZygpLCAnMTgwJyk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuU0lHTkVEX0NPTlRSQUNUX1dJVEhfQVJHUyk7XG5cbiAgICAgICAgdHgudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0Q2FsbCk7XG4gICAgICAgIHR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5DT05UUkFDVF9BRERSRVNTKTtcbiAgICAgICAgdHgub3V0cHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgICAgdHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4LmlucHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5UWF9TRU5ERVIuYWRkcmVzcyk7XG4gICAgICAgIHR4LmlucHV0c1swXS52YWx1ZS5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYSBzaWduZWQgc2VsZiBzdGFja2luZyBjb250cmFjdCBjYWxsJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBidWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAvKiBDb250cmFjdCBjYWxsIGluIGNsYXJpdHkgUE9YLTRcbiAgICAgICAgKGRlZmluZS1wdWJsaWMgKHN0YWNrLXN0eCAoYW1vdW50LXVzdHggdWludClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHBveC1hZGRyICh0dXBsZSAodmVyc2lvbiAoYnVmZiAxKSkgKGhhc2hieXRlcyAoYnVmZiAzMikpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHN0YXJ0LWJ1cm4taHQgdWludClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvY2stcGVyaW9kIHVpbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChzaWduZXItc2lnIChvcHRpb25hbCAoYnVmZiA2NSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAoc2lnbmVyLWtleSAoYnVmZiAzMykpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChtYXgtYW1vdW50IHVpbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChhdXRoLWlkIHVpbnQpKVxuICAgICAgICAgKi9cbiAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW1xuICAgICAgICAgIHsgdHlwZTogJ3VpbnQxMjgnLCB2YWw6ICc0MDAwMDAwMDAnIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogJ3R1cGxlJyxcbiAgICAgICAgICAgIHZhbDogW1xuICAgICAgICAgICAgICB7IGtleTogJ2hhc2hieXRlcycsIHR5cGU6ICdidWZmZXInLCB2YWw6IEJ1ZmZlci5mcm9tKCdzb21lLWhhc2gnKSB9LFxuICAgICAgICAgICAgICB7IGtleTogJ3ZlcnNpb24nLCB0eXBlOiAnYnVmZmVyJywgdmFsOiBuZXcgQmlnTnVtKDEpLnRvQnVmZmVyKCkgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHR5cGU6ICd1aW50MTI4JywgdmFsOiAnNTI4MDAnIH0sXG4gICAgICAgICAgeyB0eXBlOiAndWludDEyOCcsIHZhbDogJzInIH0sXG4gICAgICAgICAgLy8gTmFrYW1vdG8gdXBncmFkZSBuZXcgNCBwYXJhbWV0ZXJzXG4gICAgICAgICAgLy8gaHR0cHM6Ly9kb2NzLnN0YWNrcy5jby9uYWthbW90by11cGdyYWRlL3NpZ25pbmctYW5kLXN0YWNraW5nL3N0YWNraW5nLWZsb3cjc29sby1zdGFja2VyLWZsb3dcbiAgICAgICAgICB7IHR5cGU6ICdvcHRpb25hbCcsIHZhbDogeyB0eXBlOiAnYnVmZmVyJywgdmFsOiBCdWZmZXIuZnJvbSgnc29tZS1oYXNoJykgfSB9LFxuICAgICAgICAgIHsgdHlwZTogJ2J1ZmZlcicsIHZhbDogQnVmZmVyLmZyb20oJ3NvbWUtaGFzaCcpIH0sXG4gICAgICAgICAgeyB0eXBlOiAndWludDEyOCcsIHZhbDogJzM0MDI4MjM2NjkyMDkzODQ2MzQ2MzM3NDYwNzQzMTc2ODIxMTQ1NScgfSxcbiAgICAgICAgICB7IHR5cGU6ICd1aW50MTI4JywgdmFsOiAnMTIzNDU2JyB9LFxuICAgICAgICBdKTtcbiAgICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5UWF9TRU5ERVIucHJ2IH0pO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdEFkZHJlc3MsIHRlc3REYXRhLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0TmFtZSwgdGVzdERhdGEuQ09OVFJBQ1RfTkFNRSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuZnVuY3Rpb25OYW1lLCB0ZXN0RGF0YS5DT05UUkFDVF9GVU5DVElPTl9OQU1FKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIDApO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5mZWUudG9TdHJpbmcoKSwgJzE4MCcpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLlNJR05FRF9TRUxGX1NUQUNLX0NPTlRSQUNUX0NBTEwpO1xuXG4gICAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuQ09OVFJBQ1RfQUREUkVTUyk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICAgIHR4LmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuVFhfU0VOREVSLmFkZHJlc3MpO1xuICAgICAgICB0eC5pbnB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2Egc2lnbmVkIGNvbnRyYWN0IGNhbGwgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IDEyMztcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW3sgdHlwZTogJ29wdGlvbmFsJywgdmFsOiB7IHR5cGU6ICdpbnQxMjgnLCB2YWw6IGFtb3VudCB9IH1dKTtcbiAgICAgICAgYnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5UWF9TRU5ERVIucHJ2IH0pO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdEFkZHJlc3MsIHRlc3REYXRhLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0TmFtZSwgdGVzdERhdGEuQ09OVFJBQ1RfTkFNRSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuZnVuY3Rpb25OYW1lLCB0ZXN0RGF0YS5DT05UUkFDVF9GVU5DVElPTl9OQU1FKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ubm9uY2UsIDApO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5mZWUudG9TdHJpbmcoKSwgJzE4MCcpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmZ1bmN0aW9uQXJncywgW3N0cmluZ2lmeUN2KHNvbWVDVihpbnRDVihhbW91bnQpKSldKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5TSUdORURfQ09OVFJBQ1RfQ0FMTCk7XG4gICAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdhIHNpZ25lZCBzZXJpYWxpemVkIGNvbnRyYWN0IGNhbGwgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odGVzdERhdGEuU0lHTkVEX0NPTlRSQUNUX0NBTEwpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuY29udHJhY3RBZGRyZXNzLCB0ZXN0RGF0YS5DT05UUkFDVF9BRERSRVNTKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5jb250cmFjdE5hbWUsIHRlc3REYXRhLkNPTlRSQUNUX05BTUUpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmZ1bmN0aW9uTmFtZSwgdGVzdERhdGEuQ09OVFJBQ1RfRlVOQ1RJT05fTkFNRSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLm5vbmNlLCAwKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uZmVlLnRvU3RyaW5nKCksICcxODAnKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5mdW5jdGlvbkFyZ3MsIFtzdHJpbmdpZnlDdihzb21lQ1YoaW50Q1YoMTIzKSkpXSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuU0lHTkVEX0NPTlRSQUNUX0NBTEwpO1xuICAgICAgICB0eC50eXBlLnNob3VsZC5lcXVhbChUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgICAgdHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICB0eC5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLkNPTlRSQUNUX0FERFJFU1MpO1xuICAgICAgICB0eC5vdXRwdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgICB0eC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgdHguaW5wdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHRlc3REYXRhLlRYX1NFTkRFUi5hZGRyZXNzKTtcbiAgICAgICAgdHguaW5wdXRzWzBdLnZhbHVlLnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdhIHNpZ25lZCBzZXJpYWxpemVkIHNlbGYgc3RhY2tpbmcgY29udHJhY3QgY2FsbCB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZnJvbSh0ZXN0RGF0YS5TSUdORURfU0VMRl9TVEFDS19DT05UUkFDVF9DQUxMKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5wYXlsb2FkLmNvbnRyYWN0QWRkcmVzcywgdGVzdERhdGEuQ09OVFJBQ1RfQUREUkVTUyk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuY29udHJhY3ROYW1lLCB0ZXN0RGF0YS5DT05UUkFDVF9OQU1FKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ucGF5bG9hZC5mdW5jdGlvbk5hbWUsIHRlc3REYXRhLkNPTlRSQUNUX0ZVTkNUSU9OX05BTUUpO1xuICAgICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5ub25jZSwgMCk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmZlZS50b1N0cmluZygpLCAnMTgwJyk7XG4gICAgICAgIC8vIE5vdyBzdGFja3Mtc3R4IHNlbGYtc3RhY2tpbmcgc3VwcG9ydHMgOCBwYXJhbWV0ZXJzXG4gICAgICAgIC8vIGh0dHBzOi8vZG9jcy5zdGFja3MuY28vbmFrYW1vdG8tdXBncmFkZS9zaWduaW5nLWFuZC1zdGFja2luZy9zdGFja2luZy1mbG93I3NvbG8tc3RhY2tlci1mbG93XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLnBheWxvYWQuZnVuY3Rpb25BcmdzLmxlbmd0aCwgOCk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuU0lHTkVEX1NFTEZfU1RBQ0tfQ09OVFJBQ1RfQ0FMTCk7XG4gICAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuQ09OVFJBQ1RfQUREUkVTUyk7XG4gICAgICAgIHR4Lm91dHB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICAgIHR4LmlucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICB0eC5pbnB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwodGVzdERhdGEuVFhfU0VOREVSLmFkZHJlc3MpO1xuICAgICAgICB0eC5pbnB1dHNbMF0udmFsdWUuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2EgbXVsdGlzaWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgIGJ1aWxkZXIuZnVuY3Rpb25BcmdzKFt7IHR5cGU6ICdvcHRpb25hbCcsIHZhbDogeyB0eXBlOiAnaW50MTI4JywgdmFsOiAnMTIzJyB9IH1dKTtcblxuICAgICAgICBidWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLnBydjEgfSk7XG4gICAgICAgIGJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEucHJ2MiB9KTtcbiAgICAgICAgYnVpbGRlci5mcm9tUHViS2V5KFt0ZXN0RGF0YS5wdWIxLCB0ZXN0RGF0YS5wdWIyLCB0ZXN0RGF0YS5wdWIzXSk7XG4gICAgICAgIGJ1aWxkZXIubnVtYmVyU2lnbmF0dXJlcygyKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCBidWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHR4LnRvSnNvbigpKTtcbiAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5NVUxUSV9TSUdfQ09OVFJBQ1RfQ0FMTCk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ1BhcnNlQ1YgdGVzdCcsICgpID0+IHtcbiAgICAgICAgaXQoJ09wdGlvbmFsIHdpdGggb3V0IHZhbHVlJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGFtb3VudCA9ICc0MDAwMDAwMDAnO1xuICAgICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW1xuICAgICAgICAgICAgeyB0eXBlOiAndWludDEyOCcsIHZhbDogYW1vdW50IH0sXG4gICAgICAgICAgICB7IHR5cGU6ICdwcmluY2lwYWwnLCB2YWw6IHRlc3REYXRhLkFDQ09VTlRfMi5hZGRyZXNzIH0sXG4gICAgICAgICAgICB7IHR5cGU6ICdvcHRpb25hbCcgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogJ29wdGlvbmFsJyxcbiAgICAgICAgICAgICAgdmFsOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3R1cGxlJyxcbiAgICAgICAgICAgICAgICB2YWw6IFtcbiAgICAgICAgICAgICAgICAgIHsga2V5OiAnaGFzaGJ5dGVzJywgdHlwZTogJ2J1ZmZlcicsIHZhbDogQnVmZmVyLmZyb20oJ3NvbWUtaGFzaCcpIH0sXG4gICAgICAgICAgICAgICAgICB7IGtleTogJ3ZlcnNpb24nLCB0eXBlOiAnYnVmZmVyJywgdmFsOiBuZXcgQmlnTnVtKDEpLnRvQnVmZmVyKCkgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgICBzaG91bGQuZGVlcEVxdWFsKChidWlsZGVyIGFzIGFueSkuX2Z1bmN0aW9uQXJncywgW1xuICAgICAgICAgICAgdWludENWKGFtb3VudCksXG4gICAgICAgICAgICBzdGFuZGFyZFByaW5jaXBhbENWKHRlc3REYXRhLkFDQ09VTlRfMi5hZGRyZXNzKSxcbiAgICAgICAgICAgIG5vbmVDVigpLFxuICAgICAgICAgICAgc29tZUNWKFxuICAgICAgICAgICAgICB0dXBsZUNWKHtcbiAgICAgICAgICAgICAgICBoYXNoYnl0ZXM6IGJ1ZmZlckNWKEJ1ZmZlci5mcm9tKCdzb21lLWhhc2gnKSksXG4gICAgICAgICAgICAgICAgdmVyc2lvbjogYnVmZmVyQ1YobmV3IEJpZ051bSgxKS50b0J1ZmZlcigpKSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgXSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCd1c2UgQ2xhcml0eVZhbHVlJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGFtb3VudCA9ICc0MDAwMDAwMDAnO1xuICAgICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgICAgYnVpbGRlci5mdW5jdGlvbkFyZ3MoW1xuICAgICAgICAgICAgdWludENWKGFtb3VudCksXG4gICAgICAgICAgICBzdGFuZGFyZFByaW5jaXBhbENWKHRlc3REYXRhLkFDQ09VTlRfMi5hZGRyZXNzKSxcbiAgICAgICAgICAgIG5vbmVDVigpLFxuICAgICAgICAgICAgc29tZUNWKFxuICAgICAgICAgICAgICB0dXBsZUNWKHtcbiAgICAgICAgICAgICAgICBoYXNoYnl0ZXM6IGJ1ZmZlckNWKEJ1ZmZlci5mcm9tKCdzb21lLWhhc2gnKSksXG4gICAgICAgICAgICAgICAgdmVyc2lvbjogYnVmZmVyQ1YobmV3IEJpZ051bSgxKS50b0J1ZmZlcigpKSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCgoYnVpbGRlciBhcyBhbnkpLl9mdW5jdGlvbkFyZ3MsIFtcbiAgICAgICAgICAgIHVpbnRDVihhbW91bnQpLFxuICAgICAgICAgICAgc3RhbmRhcmRQcmluY2lwYWxDVih0ZXN0RGF0YS5BQ0NPVU5UXzIuYWRkcmVzcyksXG4gICAgICAgICAgICBub25lQ1YoKSxcbiAgICAgICAgICAgIHNvbWVDVihcbiAgICAgICAgICAgICAgdHVwbGVDVih7XG4gICAgICAgICAgICAgICAgaGFzaGJ5dGVzOiBidWZmZXJDVihCdWZmZXIuZnJvbSgnc29tZS1oYXNoJykpLFxuICAgICAgICAgICAgICAgIHZlcnNpb246IGJ1ZmZlckNWKG5ldyBCaWdOdW0oMSkudG9CdWZmZXIoKSksXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApLFxuICAgICAgICAgIF0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnQnVmZmVyIGFzIHN0cmluZycsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBidWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIGJ1aWxkZXIuZnVuY3Rpb25BcmdzKFtcbiAgICAgICAgICAgIHsgdHlwZTogJ2J1ZmZlcicsIHZhbDogJ3NvbWUtaGFzaCcgfSxcbiAgICAgICAgICAgIHsgdHlwZTogJ2J1ZmZlcicsIHZhbDogJzEnIH0sXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgc2hvdWxkLmRlZXBFcXVhbCgoYnVpbGRlciBhcyBhbnkpLl9mdW5jdGlvbkFyZ3MsIFtcbiAgICAgICAgICAgIGJ1ZmZlckNWKEJ1ZmZlci5mcm9tKCdzb21lLWhhc2gnKSksXG4gICAgICAgICAgICBidWZmZXJDVihuZXcgQmlnTnVtKDEpLnRvQnVmZmVyKCkpLFxuICAgICAgICAgIF0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnQnVmZmVyIGFzIG51bWJlcicsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBidWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIGJ1aWxkZXIuZnVuY3Rpb25BcmdzKFtcbiAgICAgICAgICAgIHsgdHlwZTogJ2J1ZmZlcicsIHZhbDogJzEnIH0sXG4gICAgICAgICAgICB7IHR5cGU6ICdidWZmZXInLCB2YWw6IDEgfSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgICBzaG91bGQuZGVlcEVxdWFsKChidWlsZGVyIGFzIGFueSkuX2Z1bmN0aW9uQXJncywgW1xuICAgICAgICAgICAgYnVmZmVyQ1YobmV3IEJpZ051bSgxKS50b0J1ZmZlcigpKSxcbiAgICAgICAgICAgIGJ1ZmZlckNWKG5ldyBCaWdOdW0oMSkudG9CdWZmZXIoKSksXG4gICAgICAgICAgXSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdpbnZhbGlkIHR5cGUnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcblxuICAgICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgICAoKSA9PiBidWlsZGVyLmZ1bmN0aW9uQXJncyhbeyB0eXBlOiAndW5rbm93JywgdmFsOiAnYW55LXZhbCcgfV0pLFxuICAgICAgICAgICAgbmV3IFJlZ0V4cCgnVW5leHBlY3RlZCBDbGFyaXR5IEFCSSB0eXBlIHByaW1pdGl2ZTogXCJ1bmtub3dcIicpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ3Nob3VsZCBmYWlsJywgKCkgPT4ge1xuICAgICAgICBpdCgnYSBjb250cmFjdCBjYWxsIHdpdGggYW4gaW52YWxpZCBrZXknLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgICBhc3NlcnQudGhyb3dzKCgpID0+IGJ1aWxkZXIuc2lnbih7IGtleTogJ2ludmFsaWRLZXknIH0pLCAvVW5zdXBwb3J0ZWQgcHJpdmF0ZSBrZXkvKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdhIGNvbnRyYWN0IGNhbGwgd2l0aCBhbiBpbnZhbGlkIGNvbnRyYWN0IGFkZHJlc3MnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgICBhc3NlcnQudGhyb3dzKCgpID0+IGJ1aWxkZXIuY29udHJhY3RBZGRyZXNzKHRlc3REYXRhLkFDQ09VTlRfMS5hZGRyZXNzKSwgL0ludmFsaWQgY29udHJhY3QgYWRkcmVzcy8pO1xuICAgICAgICB9KTtcbiAgICAgICAgaXQoJ2EgY29udHJhY3QgY2FsbCB3aXRoIGFuIGludmFsaWQgY29udHJhY3QgbmFtZSBwb3gtMicsICgpID0+IHtcbiAgICAgICAgICBjb25zdCBidWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gYnVpbGRlci5jb250cmFjdE5hbWUoJ3BveC0yJyksIC9Pbmx5IHBveC00IGFuZCBzZW5kLW1hbnktbWVtbyBjb250cmFjdHMgc3VwcG9ydGVkLyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpdCgnYSBjb250cmFjdCBjYWxsIHdpdGggYW4gaW52YWxpZCBjb250cmFjdCBuYW1lIHBveC0zJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBidWlsZGVyLmNvbnRyYWN0TmFtZSgncG94LTMnKSwgL09ubHkgcG94LTQgYW5kIHNlbmQtbWFueS1tZW1vIGNvbnRyYWN0cyBzdXBwb3J0ZWQvKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGl0KCdhIGNvbnRyYWN0IGNhbGwgd2l0aCBhbiBpbnZhbGlkIGNvbnRyYWN0IGZ1bmN0aW9uIG5hbWUnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVpbGRlciA9IGluaXRUeEJ1aWxkZXIoKTtcbiAgICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICAgKCkgPT4gYnVpbGRlci5mdW5jdGlvbk5hbWUoJ3Rlc3QtZnVuY3Rpb24nKSxcbiAgICAgICAgICAgIG5ldyBSZWdFeHAoJ3Rlc3QtZnVuY3Rpb24gaXMgbm90IHN1cHBvcnRlZCBjb250cmFjdCBmdW5jdGlvbiBuYW1lJylcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!