PHP WebShell

Текущая директория: /opt/BitGoJS/modules/sdk-coin-xlm/dist/test/unit

Просмотр файла: xlm.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 should = __importStar(require("should"));
const crypto_1 = require("crypto");
const stellar = __importStar(require("stellar-sdk"));
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_api_1 = require("@bitgo/sdk-api");
const src_1 = require("../../src");
const keyPair_1 = require("../../src/lib/keyPair");
const nock_1 = __importDefault(require("nock"));
const assert = __importStar(require("assert"));
nock_1.default.enableNetConnect();
describe('XLM:', function () {
    let bitgo;
    let basecoin;
    let uri;
    before(function () {
        bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
        bitgo.safeRegister('txlm', src_1.Txlm.createInstance);
        bitgo.initializeTestVars();
        basecoin = bitgo.coin('txlm');
        uri = sdk_core_1.Environments[bitgo.getEnv()].uri;
    });
    after(function () {
        nock_1.default.cleanAll();
    });
    describe('Addresses:', () => {
        const noMemoIdAddress = 'GBIEJQUARJ33DIZU4AIRDOKYPSVK66Z3O5XU7OOI7LUOAJWTPI4OA4JI';
        const validMemoIdAddress = 'GBIEJQUARJ33DIZU4AIRDOKYPSVK66Z3O5XU7OOI7LUOAJWTPI4OA4JI?memoId=5';
        const invalidMemoIdAddress = 'GBIEJQUARJ33DIZU4AIRDOKYPSVK66Z3O5XU7OOI7LUOAJWTPI4OA4JI?memoId=x';
        const multipleMemoIdAddress = 'GBIEJQUARJ33DIZU4AIRDOKYPSVK66Z3O5XU7OOI7LUOAJWTPI4OA4JI?memoId=5&memoId=3';
        // Muxed address of GAFHNUKOZT6QA4WJS6YSDCN6XETEOP7Q6AOHFFLUGLNVM6FY724ULORC
        const validMuxedAddress = 'MAFHNUKOZT6QA4WJS6YSDCN6XETEOP7Q6AOHFFLUGLNVM6FY724UKAAAAAAAAAAAAEJCO';
        const validMuxedBaseAddress = 'GAFHNUKOZT6QA4WJS6YSDCN6XETEOP7Q6AOHFFLUGLNVM6FY724ULORC';
        it('should get address details without memoId', function () {
            const addressDetails = basecoin.getAddressDetails(noMemoIdAddress);
            addressDetails.address.should.equal(noMemoIdAddress);
            should.not.exist(addressDetails.memoId);
        });
        it('should get address details with memoId', function () {
            const addressDetails = basecoin.getAddressDetails(validMemoIdAddress);
            addressDetails.address.should.equal(validMemoIdAddress.split('?')[0]);
            addressDetails.memoId.should.equal('5');
        });
        it('should throw on invalid memo id address', () => {
            (() => {
                basecoin.getAddressDetails(invalidMemoIdAddress);
            }).should.throw();
        });
        it('should throw on multiple memo id address', () => {
            (() => {
                basecoin.getAddressDetails(multipleMemoIdAddress);
            }).should.throw();
        });
        it('should validate address', function () {
            basecoin.isValidAddress('GBRIS6W5OZNWWFJA6GYRF3JBK5WZNX5WWD2KC6NCOOIEMF7H6JMQLUI4').should.equal(true);
            basecoin.isValidAddress('GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2').should.equal(true);
            basecoin.isValidAddress('GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2?memoId=1').should.equal(true);
            basecoin.isValidAddress('GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2?memoId=x').should.equal(false);
            basecoin.isValidAddress('SBKGCMBY56MHTT4EGE3YJIYL4CPWKSGJ7VDEQF4J3B3YO576KNL7DOYJ').should.equal(false); // private key
            basecoin.isValidAddress('r2udSsspYjWSoUZxzxLzV6RxGcbygngJ8').should.equal(false); // xrp account
        });
        it('should validate muxed address', function () {
            basecoin.isValidAddress(validMuxedAddress).should.equal(true);
            const muxedAddressDetails = basecoin.getAddressDetails(validMuxedAddress);
            muxedAddressDetails.should.deepEqual({
                baseAddress: validMuxedBaseAddress,
                address: validMuxedAddress,
                id: '1',
                memoId: undefined,
            });
        });
        it('verifyAddress should work', async function () {
            await basecoin.verifyAddress({
                address: 'GBRIS6W5OZNWWFJA6GYRF3JBK5WZNX5WWD2KC6NCOOIEMF7H6JMQLUI4',
                rootAddress: 'GBRIS6W5OZNWWFJA6GYRF3JBK5WZNX5WWD2KC6NCOOIEMF7H6JMQLUI4',
            });
            await basecoin.verifyAddress({
                address: 'GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2?memoId=1',
                rootAddress: 'GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2',
            });
            await basecoin.verifyAddress({
                address: validMuxedAddress,
                rootAddress: validMuxedBaseAddress,
            });
            assert.rejects(basecoin.verifyAddress({
                address: 'GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2?memoId=243432',
                rootAddress: 'GBRIS6W5OZNWWFJA6GYRF3JBK5WZNX5WWD2KC6NCOOIEMF7H6JMQLUI4',
            }));
            assert.rejects(basecoin.verifyAddress({
                address: 'GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2=x',
                rootAddress: 'GDU2FEL6THGGOFDHHP4I5FHNWY4S2SXYUBCEDB5ZREMD6UFRT4SYWSW2',
            }));
            assert.rejects(basecoin.verifyAddress({
                address: 'SBKGCMBY56MHTT4EGE3YJIYL4CPWKSGJ7VDEQF4J3B3YO576KNL7DOYJ',
            }));
            assert.rejects(basecoin.verifyAddress({
                address: 'r2udSsspYjWSoUZxzxLzV6RxGcbygngJ8',
            }));
        });
    });
    it('should validate pub key', () => {
        const { pub } = basecoin.keychains().create();
        basecoin.isValidPub(pub).should.equal(true);
    });
    it('should validate root keypair', () => {
        const { pub, prv } = basecoin.keychains().create({ isRootKey: true });
        basecoin.isValidPub(pub).should.equal(true);
        basecoin.isValidPrv(prv).should.equal(true);
    });
    it('should validate stellar username', function () {
        basecoin.isValidStellarUsername('foo@bar.baz').should.equal(true);
        basecoin.isValidStellarUsername('foo_bar9.baz').should.equal(true);
        basecoin.isValidStellarUsername('foo+bar_9.baz').should.equal(true);
        basecoin.isValidStellarUsername('').should.equal(false);
        basecoin.isValidStellarUsername('foo bar.baz').should.equal(false); // whitespace is not allowed
        basecoin.isValidStellarUsername('Foo@bar.baz').should.equal(false); // only lowercase letters are allowed
    });
    it('Should explain an XLM transaction', async function () {
        const signedExplanation = await basecoin.explainTransaction({
            txBase64: 'AAAAAMDHAbd3O7B2auR1e+EH/LRKe8IcQBOF+XP2lOxWi1PfAAAB9AAEvJEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAB1RFU1RJTkcAAAAAAQAAAAAAAAABAAAAALgEl4p84728zfXtl/JdOsx3QbI97mcybqcXdfgdv54zAAAAAAAAAAEqBfIAAAAAAAAAAAFWi1PfAAAAQDoqo7juOBZawMlk8znIbYqSKemjgmINosp/P4+0SFGo/xJy1YgD6YEc65aWuyBxucFFBXCSlAxP2Z7nPMyjewM=',
        });
        signedExplanation.outputAmount.should.equal('5000000000');
        signedExplanation.outputAmounts.should.have.property('txlm', '5000000000');
        signedExplanation.outputs.length.should.equal(1);
        signedExplanation.outputs[0].address.should.equal('GC4AJF4KPTR33PGN6XWZP4S5HLGHOQNSHXXGOMTOU4LXL6A5X6PDH445');
        signedExplanation.outputs[0].amount.should.equal('5000000000');
        signedExplanation.outputs[0].coin.should.equal('txlm');
        signedExplanation.fee.fee.should.equal('500');
        signedExplanation.memo.value.should.equal('TESTING');
        signedExplanation.memo.type.should.equal('text');
        signedExplanation.changeOutputs.length.should.equal(0);
        signedExplanation.changeAmount.should.equal('0');
        const unsignedExplanation = await basecoin.explainTransaction({
            txBase64: 'AAAAAMDHAbd3O7B2auR1e+EH/LRKe8IcQBOF+XP2lOxWi1PfAAAAZAAEvJEAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAABAAAAAAAAAAEAAAAAuASXinzjvbzN9e2X8l06zHdBsj3uZzJupxd1+B2/njMAAAAAAAAAAlQL5AAAAAAAAAAAAA==',
        });
        unsignedExplanation.outputAmount.should.equal('10000000000');
        unsignedExplanation.outputAmounts.should.have.property('txlm', '10000000000');
        unsignedExplanation.outputs.length.should.equal(1);
        unsignedExplanation.outputs[0].address.should.equal('GC4AJF4KPTR33PGN6XWZP4S5HLGHOQNSHXXGOMTOU4LXL6A5X6PDH445');
        unsignedExplanation.outputs[0].amount.should.equal('10000000000');
        unsignedExplanation.outputs[0].coin.should.equal('txlm');
        unsignedExplanation.fee.fee.should.equal('100');
        unsignedExplanation.memo.value.should.equal('1');
        unsignedExplanation.memo.type.should.equal('id');
        unsignedExplanation.changeOutputs.length.should.equal(0);
        unsignedExplanation.changeAmount.should.equal('0');
    });
    it('Should explain an XLM transaction', async function () {
        const signedExplanation = await basecoin.explainTransaction({
            txBase64: 'AAAAAMDHAbd3O7B2auR1e+EH/LRKe8IcQBOF+XP2lOxWi1PfAAAB9AAEvJEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAB1RFU1RJTkcAAAAAAQAAAAAAAAABAAAAALgEl4p84728zfXtl/JdOsx3QbI97mcybqcXdfgdv54zAAAAAAAAAAEqBfIAAAAAAAAAAAFWi1PfAAAAQDoqo7juOBZawMlk8znIbYqSKemjgmINosp/P4+0SFGo/xJy1YgD6YEc65aWuyBxucFFBXCSlAxP2Z7nPMyjewM=',
        });
        signedExplanation.outputAmount.should.equal('5000000000');
        signedExplanation.outputAmounts.should.have.property('txlm', '5000000000');
        signedExplanation.outputs.length.should.equal(1);
        signedExplanation.outputs[0].address.should.equal('GC4AJF4KPTR33PGN6XWZP4S5HLGHOQNSHXXGOMTOU4LXL6A5X6PDH445');
        signedExplanation.outputs[0].amount.should.equal('5000000000');
        signedExplanation.outputs[0].coin.should.equal('txlm');
        signedExplanation.fee.fee.should.equal('500');
        signedExplanation.memo.value.should.equal('TESTING');
        signedExplanation.memo.type.should.equal('text');
        signedExplanation.changeOutputs.length.should.equal(0);
        signedExplanation.changeAmount.should.equal('0');
        const unsignedExplanation = await basecoin.explainTransaction({
            txBase64: 'AAAAAMDHAbd3O7B2auR1e+EH/LRKe8IcQBOF+XP2lOxWi1PfAAAAZAAEvJEAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAABAAAAAAAAAAEAAAAAuASXinzjvbzN9e2X8l06zHdBsj3uZzJupxd1+B2/njMAAAAAAAAAAlQL5AAAAAAAAAAAAA==',
        });
        unsignedExplanation.outputAmount.should.equal('10000000000');
        unsignedExplanation.outputAmounts.should.have.property('txlm', '10000000000');
        unsignedExplanation.outputs.length.should.equal(1);
        unsignedExplanation.outputs[0].address.should.equal('GC4AJF4KPTR33PGN6XWZP4S5HLGHOQNSHXXGOMTOU4LXL6A5X6PDH445');
        unsignedExplanation.outputs[0].amount.should.equal('10000000000');
        unsignedExplanation.outputs[0].coin.should.equal('txlm');
        unsignedExplanation.fee.fee.should.equal('100');
        unsignedExplanation.memo.value.should.equal('1');
        unsignedExplanation.memo.type.should.equal('id');
        unsignedExplanation.changeOutputs.length.should.equal(0);
        unsignedExplanation.changeAmount.should.equal('0');
    });
    it('Should explain an XLM transaction by passing in a hex format', async function () {
        const signedExplanation = await basecoin.explainTransaction({
            txHex: '0000000200000000aa0c5c593ed36af12269dc4605dd34da32fdab5c676fa0644f28e598dd57512a0000afc800000000009896810000000100000000000000000000000000000000000000000000000100000000000000010000010000000000000000010a76d14eccfd0072c997b12189beb926473ff0f01c72957432db5678b8feb945000000000000000005f5e1000000000000000000',
        });
        signedExplanation.outputAmount.should.equal('100000000');
        signedExplanation.outputAmounts.should.have.property('txlm', '100000000');
        signedExplanation.outputs.length.should.equal(1);
        signedExplanation.outputs[0].address.should.equal('MAFHNUKOZT6QA4WJS6YSDCN6XETEOP7Q6AOHFFLUGLNVM6FY724UKAAAAAAAAAAAAEJCO');
        signedExplanation.outputs[0].amount.should.equal('100000000');
        signedExplanation.outputs[0].coin.should.equal('txlm');
        signedExplanation.fee.fee.should.equal('45000');
        signedExplanation.changeOutputs.length.should.equal(0);
        signedExplanation.changeAmount.should.equal('0');
    });
    it('Should explain a trustline transaction', async function () {
        const explanation = await basecoin.explainTransaction({
            txBase64: 'AAAAAIKWO6R0/V4oJDk2LZsdiEInIzgJ6L0GxmSU2Ffs8Y7ZAAABLAAIj4EAAAACAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAA=',
        });
        explanation.outputAmount.should.equal('0');
        explanation.fee.fee.should.equal('300');
        explanation.memo.should.be.empty();
        explanation.changeOutputs.length.should.equal(0);
        explanation.changeAmount.should.equal('0');
        explanation.operations.length.should.equal(1);
        explanation.operations[0].limit.should.equal('1000000000000');
        explanation.operations[0].coin.should.equal('txlm:BST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L');
        explanation.operations[0].type.should.equal('changeTrust');
        explanation.operations[0].should.have.property('asset');
        explanation.operations[0].asset.code.should.equal('BST');
        explanation.operations[0].asset.issuer.should.equal('GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L');
    });
    it('Should explain a token transaction', async function () {
        const explanation = await basecoin.explainTransaction({
            txBase64: 'AAAAAIXpiGPR/Yc+gSN614hAf1N1hecXFL7Lac99olpq38K/AAAAZAAC9TAAAAAEAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAgpY7pHT9XigkOTYtmx2IQicjOAnovQbGZJTYV+zxjtkAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAAAdzWUAAAAAAAAAAAFq38K/AAAAQPJTLIGGY06BuVDw0ISasYwHZpR6V38CaOfGhSooclY+4IBE9JKdKuMyGNXXCcFxM/NxrX64jhBXk+lWvjjo4wY=',
        });
        explanation.outputAmount.should.equal('0');
        explanation.fee.fee.should.equal('100');
        explanation.memo.should.be.empty();
        explanation.changeOutputs.length.should.equal(0);
        explanation.changeAmount.should.equal('0');
        explanation.outputAmounts.should.have.property('txlm:BST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L', '500000000');
    });
    it('isValidMemoId should work', function () {
        basecoin.isValidMemo({ value: '1', type: 'id' }).should.equal(true);
        basecoin.isValidMemo({ value: 'uno', type: 'text' }).should.equal(true);
        const buffer = Buffer.alloc(32).fill(10);
        basecoin.isValidMemo({ value: buffer, type: 'hash' }).should.equal(true);
        basecoin.isValidMemo({ value: buffer.toString('hex'), type: 'hash' }).should.equal(true);
        basecoin.isValidMemo({ value: 1, type: 'id' }).should.equal(false);
        basecoin.isValidMemo({ value: 1, type: 'text' }).should.equal(false);
        basecoin.isValidMemo({ value: '1', type: 'hash' }).should.equal(false);
        basecoin.isValidMemo({ value: '1', type: 'return' }).should.equal(false);
    });
    it('should supplement wallet generation', async function () {
        const walletParams = await basecoin.supplementGenerateWallet({});
        walletParams.should.have.property('rootPrivateKey');
        basecoin.isValidPrv(walletParams.rootPrivateKey).should.equal(true);
    });
    it('should supplement wallet generation with provided private key', async function () {
        const rootPrivateKey = basecoin.generateKeyPair().prv;
        const walletParams = await basecoin.supplementGenerateWallet({ rootPrivateKey });
        walletParams.should.have.property('rootPrivateKey');
        walletParams.rootPrivateKey.should.equal(rootPrivateKey);
    });
    describe('deriveKeyWithSeed', function () {
        it('should derive key with seed', function () {
            (() => {
                basecoin.deriveKeyWithSeed('test');
            }).should.throw('method deriveKeyWithSeed not supported for eddsa curve');
        });
    });
    describe('Transaction Verification', function () {
        let basecoin;
        let wallet;
        let halfSignedTransaction;
        let rootKeyHalfSignedTransaction;
        const userKeychain = {
            pub: 'GA34NPQ4M54HHZBKSDZ5B3J3BZHTXKCZD4UFO2OYZERPOASK4DAATSIB',
            prv: 'SDADJSTZNIKF46NM7LE3ZHMX4TJ2VJBL7PTERNDLWHZ5U6KNO5S7XFJD',
        };
        const backupKeychain = {
            pub: 'GC3D3ZNNK7GHLMSWJA54DQO6QJUJJF7K6J5JGCEW45ZT6QMKZ6PMUHUM',
            prv: 'SA22TDBINLZMGYUDVXGUP2JMYIQ3DTJE53PNQUVCDK73XRS6TDVYU7WW',
        };
        // This key pair is the decoded version of the userKeychain above
        const rootKeychain = {
            pub: '37c6be1c677873e42a90f3d0ed3b0e4f3ba8591f285769d8c922f7024ae0c009',
            prv: 'c034ca796a145e79acfac9bc9d97e4d3aaa42bfbe648b46bb1f3da794d7765fb37c6be1c677873e42a90f3d0ed3b0e4f3ba8591f285769d8c922f7024ae0c009',
        };
        // This key pair is the decoded version of the backupKeychain above
        const backupRootKeychain = {
            pub: 'b63de5ad57cc75b256483bc1c1de82689497eaf27a930896e7733f418acf9eca',
            prv: '35a98c286af2c36283adcd47e92cc221b1cd24eeded852a21abfbbc65e98eb8ab63de5ad57cc75b256483bc1c1de82689497eaf27a930896e7733f418acf9eca',
        };
        const prebuild = {
            txBase64: 'AAAAAGRnXg19FteG/7zPd+jDC7LDvRlzgfFC+JrPhRep0kYiAAAAZAB/4cUAAAACAAAAAAAAAAAAAAABAAAAAQAAAABkZ14NfRbXhv+8z3fowwuyw70Zc4HxQviaz4UXqdJGIgAAAAEAAAAAmljT/+FedddnAHwo95dOC4RNy6eVLSehaJY34b9GxuYAAAAAAAAAAAehIAAAAAAAAAAAAA==',
            txInfo: {
                fee: 100,
                sequence: '35995558267060226',
                source: 'GBSGOXQNPULNPBX7XTHXP2GDBOZMHPIZOOA7CQXYTLHYKF5J2JDCF7LT',
                operations: [
                    {
                        amount: '12.8', // 12.8 XLM
                        asset: { code: 'XLM' },
                        destination: 'GCNFRU774FPHLV3HAB6CR54XJYFYITOLU6KS2J5BNCLDPYN7I3DOMIPY',
                        type: 'payment',
                    },
                ],
                signatures: [],
            },
            feeInfo: {
                height: 123456,
                xlmBaseFee: '100',
                xlmBaseReserve: '5000000',
            },
            walletId: '5a78dd561c6258a907f1eeaee132f796',
        };
        const signedTxBase64 = 'AAAAAGRnXg19FteG/7zPd+jDC7LDvRlzgfFC+JrPhRep0kYiAAAAZAB/4cUAAAACAAAAAAAAAAAAAAABAAAAAQAAAABkZ14NfRbXhv+8z3fowwuyw70Zc4HxQviaz4UXqdJGIgAAAAEAAAAAmljT/+FedddnAHwo95dOC4RNy6eVLSehaJY34b9GxuYAAAAAAAAAAAehIAAAAAAAAAAAAUrgwAkAAABAOExcvVJIUJv9HuVfbV0y7lRPRARv4wDtcdhHG7QN40h5wQ2uwPF52OGQ8KY+66a1A/8lNKB75sgj2xj44s8lDQ==';
        before(function () {
            basecoin = bitgo.coin('txlm');
            const walletData = {
                id: '5a78dd561c6258a907f1eeaee132f796',
                users: [
                    {
                        user: '543c11ed356d00cb7600000b98794503',
                        permissions: ['admin', 'view', 'spend'],
                    },
                ],
                coin: 'txlm',
                label: 'Verification Wallet',
                m: 2,
                n: 3,
                keys: [
                    '5a78dd56bfe424aa07aa068651b194fd',
                    '5a78dd5674a70eb4079f58797dfe2f5e',
                    '5a78dd561c6258a907f1eea9f1d079e2',
                ],
                tags: ['5a78dd561c6258a907f1eeaee132f796'],
                disableTransactionNotifications: false,
                freeze: {},
                deleted: false,
                approvalsRequired: 1,
                isCold: true,
                coinSpecific: {},
                clientFlags: [],
                balance: 650000000,
                confirmedBalance: 650000000,
                spendableBalance: 650000000,
                balanceString: '650000000',
                confirmedBalanceString: '650000000',
                spendableBalanceString: '650000000',
                receiveAddress: {
                    id: '5a78de2bbfe424aa07aa131ec03c8dc1',
                    address: 'GBSGOXQNPULNPBX7XTHXP2GDBOZMHPIZOOA7CQXYTLHYKF5J2JDCF7LT',
                    chain: 0,
                    index: 0,
                    coin: 'txlm',
                    wallet: '5a78dd561c6258a907f1eeaee132f796',
                    coinSpecific: {},
                },
                pendingApprovals: [],
            };
            wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
        });
        it('should sign a prebuild', async function () {
            // sign transaction
            halfSignedTransaction = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: userKeychain.prv,
            });
            halfSignedTransaction.halfSigned.txBase64.should.equal(signedTxBase64);
        });
        it('should sign a prebuild with root key', async function () {
            rootKeyHalfSignedTransaction = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: rootKeychain.prv,
            });
            rootKeyHalfSignedTransaction.halfSigned.txBase64.should.equal(signedTxBase64);
        });
        it('should sign a transaction with generated root key pair', async function () {
            const seed = Buffer.from(rootKeychain.prv.slice(0, 64), 'hex');
            const kp = basecoin.generateRootKeyPair(seed);
            kp.prv.length.should.equal(128);
            const halfSignedTx = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: kp.prv,
            });
            halfSignedTx.halfSigned.txBase64.should.equal(signedTxBase64);
        });
        it('should verify the user signature on a tx', function () {
            const userPub = userKeychain.pub;
            const tx = new stellar.Transaction(halfSignedTransaction.halfSigned.txBase64, stellar.Networks.TESTNET);
            const validSignature = basecoin.verifySignature(userPub, tx.hash(), tx.signatures[0].signature());
            validSignature.should.equal(true);
        });
        it('should verify the user signature on a tx given root key', function () {
            const rootPub = rootKeychain.pub;
            const tx = new stellar.Transaction(rootKeyHalfSignedTransaction.halfSigned.txBase64, stellar.Networks.TESTNET);
            const validSignature = basecoin.verifySignature(rootPub, tx.hash(), tx.signatures[0].signature());
            validSignature.should.equal(true);
        });
        it('should fail to verify the wrong signature on a tx', function () {
            const keyPair = basecoin.generateKeyPair();
            const tx = new stellar.Transaction(halfSignedTransaction.halfSigned.txBase64, stellar.Networks.TESTNET);
            const validSignature = basecoin.verifySignature(keyPair.pub, tx.hash(), tx.signatures[0].signature());
            validSignature.should.equal(false);
        });
        it('should fail to verify the wrong signature on a tx given root key', function () {
            const keyPair = basecoin.generateRootKeyPair();
            const tx = new stellar.Transaction(rootKeyHalfSignedTransaction.halfSigned.txBase64, stellar.Networks.TESTNET);
            const validSignature = basecoin.verifySignature(keyPair.pub, tx.hash(), tx.signatures[0].signature());
            validSignature.should.equal(false);
        });
        it('should create a recovery transaction', async function () {
            const destinationAddress = 'GDDHCKMYYYCVXOSAVMSEIYGYNX74LIAV3ACXYQ6WPMDUF7W3KZNWTHTH';
            (0, nock_1.default)('https://horizon-testnet.stellar.org/accounts')
                .get('/' + wallet.receiveAddress())
                .reply(200, {
                sequence: '35995558267060226',
                balances: [
                    {
                        asset_type: 'native',
                        balance: '6500000000',
                    },
                ],
            });
            (0, nock_1.default)('https://horizon-testnet.stellar.org/accounts')
                .get('/' + destinationAddress)
                .reply(200, {
                sequence: '35995558267060213',
                balances: 13131313,
            });
            (0, nock_1.default)('https://horizon-testnet.stellar.org')
                .get('/ledgers')
                .query({
                order: 'desc',
                limit: 1,
            })
                .reply(200, {
                records: [
                    {
                        base_reserve_in_stroops: '5000000',
                        base_fee_in_stroops: 100,
                    },
                ],
            })
                .persist();
            const recovery = await basecoin.recover({
                userKey: 'GA34NPQ4M54HHZBKSDZ5B3J3BZHTXKCZD4UFO2OYZERPOASK4DAATSIB',
                backupKey: 'GC3D3ZNNK7GHLMSWJA54DQO6QJUJJF7K6J5JGCEW45ZT6QMKZ6PMUHUM',
                recoveryDestination: destinationAddress,
                rootAddress: wallet.receiveAddress(),
            });
            should.exist(recovery.txBase64);
            should.exist(recovery.feeInfo);
            recovery.coin.should.equal('txlm');
            recovery.txBase64.should.be.a.String();
            recovery.recoveryAmount.should.be.a.Number();
            recovery.feeInfo.fee.should.equal(100);
        });
        it('should fail to verify a transaction signed with the wrong key', async function () {
            // sign transaction
            const tx = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: backupKeychain.prv,
            });
            const txParams = {
                recipients: [
                    {
                        address: 'GCNFRU774FPHLV3HAB6CR54XJYFYITOLU6KS2J5BNCLDPYN7I3DOMIPY',
                        amount: '128000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: tx.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: userKeychain.pub },
                    backup: { pub: backupKeychain.pub },
                },
            };
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('transaction signed with wrong key');
        });
        it('should fail to verify a transaction signed with the wrong root key', async function () {
            // sign transaction
            const tx = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: backupRootKeychain.prv,
            });
            const txParams = {
                recipients: [
                    {
                        address: 'GCNFRU774FPHLV3HAB6CR54XJYFYITOLU6KS2J5BNCLDPYN7I3DOMIPY',
                        amount: '128000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: tx.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: rootKeychain.pub },
                    backup: { pub: backupRootKeychain.pub },
                },
            };
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('transaction signed with wrong key');
        });
        it('should fail to verify a transaction to the wrong recipient', async function () {
            // sign transaction
            const tx = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: backupKeychain.prv,
            });
            const txParams = {
                recipients: [
                    {
                        address: 'GAK3NSB43EVCZKDH4PYGJPCVPOYZ7X7KIR3ZTWSYRKRMJWGG5TABM6TH',
                        amount: '128000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: tx.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: userKeychain.pub },
                    backup: { pub: backupKeychain.pub },
                },
            };
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('transaction prebuild does not match expected recipient');
        });
        it('should fail to verify a transaction with the wrong amount', async function () {
            // sign transaction
            const tx = await wallet.signTransaction({
                txPrebuild: prebuild,
                prv: backupKeychain.prv,
            });
            const txParams = {
                recipients: [
                    {
                        address: 'GCNFRU774FPHLV3HAB6CR54XJYFYITOLU6KS2J5BNCLDPYN7I3DOMIPY',
                        amount: '130000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: tx.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: userKeychain.pub },
                    backup: { pub: backupKeychain.pub },
                },
            };
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('transaction prebuild does not match expected amount');
        });
        it('should fail to verify a transaction without recipients', async function () {
            const prebuilt = {
                txBase64: 'AAAAAP1qe44j+i4uIT+arbD4QDQBt8ryEeJd7a0jskQ3nwDeAAAAAAB/4cUAAAACAAAAAAAAAAIAAAAAAAAAAQAAAAAAAAAAAAAAAA==',
                txInfo: {
                    fee: 0,
                    sequence: '35995558267060226',
                    source: 'GD6WU64OEP5C4LRBH6NK3MHYIA2ADN6K6II6EXPNVUR3ERBXT4AN4ACD',
                    operations: [],
                    signatures: [],
                },
                feeInfo: {
                    height: 123456,
                    xlmBaseFee: '100',
                    xlmBaseReserve: '5000000',
                },
                walletId: '5a78dd561c6258a907f1eeaee132f796',
            };
            const keyPair = {
                pub: 'GAA4LVBE2HEKECNWDRT2NLTSBWFIZRGTEQFC7BLOREMMPNDHFRUGP3VZ',
                prv: 'SCIVSTUJX7SYJZHKMJI4YF7YWA27FU7XN5EH4OWBFL2Y2KTYI7IP2DFZ',
            };
            // sign transaction
            const tx = await wallet.signTransaction({
                txPrebuild: prebuilt,
                prv: keyPair.prv,
            });
            const txParams = {
                recipients: [
                    {
                        address: 'GAUKA3ZTH3DZ6THBCPL6AOQBCEEBIFYDU4FGXUCHOC7PILXGUPTUBJ6E',
                        amount: '130000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: tx.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: userKeychain.pub },
                    backup: { pub: backupKeychain.pub },
                },
            };
            await basecoin
                .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                .should.be.rejectedWith('transaction prebuild does not have any operations');
        });
        it('should verify a transaction', async function () {
            const txParams = {
                recipients: [
                    {
                        address: 'GCNFRU774FPHLV3HAB6CR54XJYFYITOLU6KS2J5BNCLDPYN7I3DOMIPY',
                        amount: '128000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: halfSignedTransaction.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: userKeychain.pub },
                    backup: { pub: backupKeychain.pub },
                },
            };
            const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
            validTransaction.should.equal(true);
        });
        it('should verify a transaction with root key', async function () {
            const txParams = {
                recipients: [
                    {
                        address: 'GCNFRU774FPHLV3HAB6CR54XJYFYITOLU6KS2J5BNCLDPYN7I3DOMIPY',
                        amount: '128000000',
                    },
                ],
            };
            const txPrebuild = {
                txBase64: rootKeyHalfSignedTransaction.halfSigned.txBase64,
            };
            const verification = {
                disableNetworking: true,
                keychains: {
                    user: { pub: rootKeychain.pub },
                    backup: { pub: backupRootKeychain.pub },
                },
            };
            const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
            validTransaction.should.equal(true);
        });
        describe('trustline transactions', function () {
            it('should fail to verify a trustline transaction with unmatching number of trustlines', async function () {
                const txParams = {
                    recipients: [],
                    type: 'trustline',
                    trustlines: [],
                };
                const buildResult = {
                    txBase64: 'AAAAANsKrHV2BVjACFt2xlyhxYzP2MNBmb4IQ5E9/WiJiV3TAAABLAAM4aEAAAAHAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAA=',
                };
                (0, nock_1.default)(uri).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`).reply(200, buildResult);
                const txPrebuild = await wallet.prebuildTransaction(txParams);
                const verification = {
                    disableNetworking: true,
                    keychains: {
                        user: { pub: userKeychain.pub },
                        backup: { pub: backupKeychain.pub },
                    },
                };
                await basecoin
                    .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                    .should.be.rejectedWith('transaction prebuild does not match expected trustline operations');
            });
            it('should fail to verify a trustline transaction with unmatching trustlines', async function () {
                const txParams = {
                    type: 'trustline',
                    recipients: [],
                    trustlines: [
                        {
                            token: 'txlm:BST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L',
                            action: 'remove',
                        },
                    ],
                };
                const buildResult = {
                    txBase64: 'AAAAANsKrHV2BVjACFt2xlyhxYzP2MNBmb4IQ5E9/WiJiV3TAAABLAAM4aEAAAAHAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAA=',
                };
                (0, nock_1.default)(uri).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`).reply(200, buildResult);
                const txPrebuild = await wallet.prebuildTransaction(txParams);
                const verification = {
                    disableNetworking: true,
                    keychains: {
                        user: { pub: userKeychain.pub },
                        backup: { pub: backupKeychain.pub },
                    },
                };
                await basecoin
                    .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                    .should.be.rejectedWith('transaction prebuild does not match expected trustline tokens');
            });
            it('should fail to verify a trustline transaction with unmatching limit', async function () {
                const txParams = {
                    type: 'trustline',
                    recipients: [],
                    trustlines: [
                        {
                            token: 'txlm:BST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L',
                            action: 'add',
                            limit: '999',
                        },
                    ],
                };
                const buildResult = {
                    txBase64: 'AAAAANsKrHV2BVjACFt2xlyhxYzP2MNBmb4IQ5E9/WiJiV3TAAABLAAM4aEAAAAHAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAA=',
                };
                (0, nock_1.default)(uri).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`).reply(200, buildResult);
                const txPrebuild = await wallet.prebuildTransaction(txParams);
                const verification = {
                    disableNetworking: true,
                    keychains: {
                        user: { pub: userKeychain.pub },
                        backup: { pub: backupKeychain.pub },
                    },
                };
                await basecoin
                    .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                    .should.be.rejectedWith('transaction prebuild does not match expected trustline tokens');
            });
            it('should verify a trustline transaction', async function () {
                const txParams = {
                    type: 'trustline',
                    recipients: [],
                    trustlines: [
                        {
                            token: 'txlm:BST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L',
                            action: 'add',
                            limit: '1000000000000',
                        },
                        {
                            token: 'txlm:TST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L',
                            action: 'remove',
                        },
                    ],
                };
                const buildResult = {
                    txBase64: 'AAAAANsKrHV2BVjACFt2xlyhxYzP2MNBmb4IQ5E9/WiJiV3TAAAAyAAM4aEAAAAJAAAAAAAAAAAAAAACAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAYAAAABVFNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAAAAAAAAAAAAAAAAAAA=',
                };
                (0, nock_1.default)(uri).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`).reply(200, buildResult);
                const txPrebuild = await wallet.prebuildTransaction(txParams);
                const verification = {
                    disableNetworking: true,
                    keychains: {
                        user: { pub: userKeychain.pub },
                        backup: { pub: backupKeychain.pub },
                    },
                };
                const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild, wallet, verification });
                validTransaction.should.equal(true);
            });
        });
        describe('enabletoken transactions', function () {
            it('should fail to verify a enbletoken transaction with unmatching number of token', async function () {
                const txParams = {
                    recipients: [],
                    type: 'enabletoken',
                };
                const buildResult = {
                    txBase64: 'AAAAANsKrHV2BVjACFt2xlyhxYzP2MNBmb4IQ5E9/WiJiV3TAAABLAAM4aEAAAAHAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAA=',
                };
                (0, nock_1.default)(uri).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`).reply(200, buildResult);
                const txPrebuild = await wallet.prebuildTransaction(txParams);
                const verification = {
                    disableNetworking: true,
                    keychains: {
                        user: { pub: userKeychain.pub },
                        backup: { pub: backupKeychain.pub },
                    },
                };
                await basecoin
                    .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                    .should.be.rejectedWith('transaction prebuild does not match expected trustline operations');
            });
            it('should fail to verify a enbletoken transaction with unmatching token', async function () {
                const txParams = {
                    type: 'enabletoken',
                    recipients: [
                        {
                            token: 'txlm:BST-GBQTIOS3XGHB7LVYGBKQVJGCZ3R4JL5E4CBSWJ5ALIJUHBKS6263644L',
                            amount: 0,
                            address: '',
                        },
                    ],
                };
                const buildResult = {
                    txBase64: 'AAAAANsKrHV2BVjACFt2xlyhxYzP2MNBmb4IQ5E9/WiJiV3TAAABLAAM4aEAAAAHAAAAAAAAAAAAAAABAAAAAAAAAAYAAAABQlNUAAAAAABhNDpbuY4frrgwVQqkws7jxK+k4IMrJ6BaE0OFUva9vwAAAOjUpRAAAAAAAAAAAAA=',
                };
                (0, nock_1.default)(uri).post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/build`).reply(200, buildResult);
                const txPrebuild = await wallet.prebuildTransaction(txParams);
                const verification = {
                    disableNetworking: true,
                    keychains: {
                        user: { pub: userKeychain.pub },
                        backup: { pub: backupKeychain.pub },
                    },
                };
                await basecoin
                    .verifyTransaction({ txParams, txPrebuild, wallet, verification })
                    .should.be.rejectedWith('transaction prebuild does not match expected trustline tokens');
            });
        });
    });
    describe('Federation lookups:', function () {
        describe('Look up by stellar address:', function () {
            it('should fail to loop up an invalid stellar address with a bitgo.com domain', async function () {
                const stellarAddress = 'invalid*bitgo.com';
                (0, nock_1.default)(uri)
                    .get('/.well-known/stellar.toml')
                    .reply(200, 'FEDERATION_SERVER="https://test.bitgo.com/api/v2/txlm/federation"')
                    .get('/api/v2/txlm/federation')
                    .query({
                    q: stellarAddress,
                    type: 'name',
                })
                    .reply(404, {
                    detail: `user not found: ${stellarAddress}`,
                    name: 'UserNotFound',
                });
                await basecoin
                    .federationLookupByName(stellarAddress)
                    .should.be.rejectedWith(`user not found: ${stellarAddress}`);
            });
            it('should resolve a stellar address into an account', async function () {
                const stellarAddress = 'tester*bitgo.com';
                const accountId = 'GCBYY3S62QY43PMEKGJHRCBHEFJOHCLGSMWXREUZYDQHJHQ2LK4I42JA';
                (0, nock_1.default)(uri)
                    .get('/.well-known/stellar.toml')
                    .reply(200, 'FEDERATION_SERVER="https://test.bitgo.com/api/v2/txlm/federation"')
                    .get('/api/v2/txlm/federation')
                    .query({
                    q: stellarAddress,
                    type: 'name',
                })
                    .reply(200, {
                    stellar_address: stellarAddress,
                    account_id: accountId,
                });
                const res = await basecoin.federationLookupByName(stellarAddress);
                res.should.have.property('stellar_address');
                res.should.have.property('account_id');
                res.stellar_address.should.equal(stellarAddress);
                res.account_id.should.equal(accountId);
            });
        });
        describe('Look up by account id:', function () {
            it('should fail to look up an account if the account id is invalid', async function () {
                const accountId = '123';
                (0, nock_1.default)(uri)
                    .get('/api/v2/txlm/federation')
                    .query({
                    q: accountId,
                    type: 'id',
                })
                    .reply(400, {
                    detail: 'invalid id: ' + accountId,
                });
                await basecoin.federationLookupByAccountId(accountId).should.be.rejectedWith(`invalid id: ${accountId}`);
            });
            it('should return only account_id for non-bitgo accounts', async function () {
                const accountId = 'GCROXHYJSTCS3CQQIU7GFC7YQIRIVGPYZQRZEM6PN7P7TAZ3PU4CHJRG';
                (0, nock_1.default)(uri)
                    .get('/api/v2/txlm/federation')
                    .query({
                    q: accountId,
                    type: 'id',
                })
                    .reply(200, {
                    account_id: accountId,
                });
                const res = await basecoin.federationLookupByAccountId(accountId);
                res.should.not.have.property('stellar_address');
                res.should.not.have.property('memo_type');
                res.should.not.have.property('memo');
                res.should.have.property('account_id');
                res.account_id.should.equal(accountId);
            });
            it('should resolve a valid account id into an account', async function () {
                const accountId = 'GDDHCKMYYYCVXOSAVMSEIYGYNX74LIAV3ACXYQ6WPMDUF7W3KZNWTHTH';
                (0, nock_1.default)(uri)
                    .get('/api/v2/txlm/federation')
                    .query({
                    q: accountId,
                    type: 'id',
                })
                    .reply(200, {
                    stellar_address: 'tester*bitgo.com',
                    account_id: accountId,
                    memo_type: 'id',
                    memo: '0',
                });
                const res = await basecoin.federationLookupByAccountId(accountId);
                res.should.have.property('stellar_address');
                res.should.have.property('account_id');
                res.should.have.property('memo_type');
                res.should.have.property('memo');
                res.account_id.should.equal(accountId);
                res.stellar_address.should.equal('tester*bitgo.com');
            });
        });
    });
    describe('Keypairs:', () => {
        it('should generate a keypair from random seed', function () {
            const keyPair = basecoin.generateKeyPair();
            keyPair.should.have.property('pub');
            keyPair.should.have.property('prv');
            const address = keyPair.pub;
            basecoin.isValidAddress(address).should.equal(true);
            basecoin.isValidPub(keyPair.pub).should.equal(true);
            basecoin.isValidPrv(keyPair.prv).should.equal(true);
        });
        it('should generate a keypair from seed', function () {
            const seed = (0, crypto_1.randomBytes)(32);
            const keyPair = basecoin.generateKeyPair(seed);
            keyPair.should.have.property('pub');
            keyPair.should.have.property('prv');
            const address = keyPair.pub;
            basecoin.isValidAddress(address).should.equal(true);
            basecoin.isValidPub(keyPair.pub).should.equal(true);
            basecoin.isValidPrv(keyPair.prv).should.equal(true);
            const secret = keyPair.prv;
            stellar.StrKey.encodeEd25519SecretSeed(seed).should.equal(secret);
        });
        it('should validate pub key', () => {
            const { pub } = basecoin.keychains().create();
            basecoin.isValidPub(pub).should.equal(true);
        });
    });
    describe('Generate wallet Root key pair: ', () => {
        it('should generate a root keypair from random seed', function () {
            const kp = basecoin.generateRootKeyPair();
            basecoin.isValidPub(kp.pub).should.equal(true);
            const keyPair = new keyPair_1.KeyPair({ prv: kp.prv }).getKeys(true);
            keyPair.should.have.property('pub');
            keyPair.should.have.property('prv');
            keyPair.prv?.should.equal(kp.prv.slice(0, 64));
            keyPair.pub.should.equal(kp.pub);
        });
        it('should generate a root keypair from seed', function () {
            const seed = Buffer.from('761de570c460792f10378a8b3c7cc2283241db37d8dac13dbdd8095a05ea00b2', 'hex');
            const kp = basecoin.generateRootKeyPair(seed);
            basecoin.isValidPub(kp.pub).should.equal(true);
            kp.pub.should.equal('7fe4254baaeebfefd5a632fdb71aa9ec63aa611bcd392b07a759a4b21307b7fc');
            kp.prv.should.equal('761de570c460792f10378a8b3c7cc2283241db37d8dac13dbdd8095a05ea00b27fe4254baaeebfefd5a632fdb71aa9ec63aa611bcd392b07a759a4b21307b7fc');
            const keyPair = new keyPair_1.KeyPair({ prv: kp.prv }).getKeys(true);
            keyPair.should.have.property('prv');
            keyPair.prv?.should.equal(kp.prv.slice(0, 64));
            keyPair.pub.should.equal(kp.pub);
        });
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieGxtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3hsbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtDQUFpQztBQUNqQyxtQ0FBcUM7QUFDckMscURBQXVDO0FBRXZDLDhDQUF1RDtBQUN2RCw4Q0FBMEQ7QUFDMUQsNENBQTBDO0FBQzFDLG1DQUFpQztBQUNqQyxtREFBZ0Q7QUFFaEQsZ0RBQXdCO0FBQ3hCLCtDQUFpQztBQUNqQyxjQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUV4QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksUUFBUSxDQUFDO0lBQ2IsSUFBSSxHQUFHLENBQUM7SUFFUixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixHQUFHLEdBQUcsdUJBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDekMsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLENBQUM7UUFDSixjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDbEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRTtRQUMxQixNQUFNLGVBQWUsR0FBRywwREFBMEQsQ0FBQztRQUNuRixNQUFNLGtCQUFrQixHQUFHLG1FQUFtRSxDQUFDO1FBQy9G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QUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQy9DLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBzdGVsbGFyIGZyb20gJ3N0ZWxsYXItc2RrJztcblxuaW1wb3J0IHsgRW52aXJvbm1lbnRzLCBXYWxsZXQgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLWFwaSc7XG5pbXBvcnQgeyBUeGxtIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IEtleVBhaXIgfSBmcm9tICcuLi8uLi9zcmMvbGliL2tleVBhaXInO1xuXG5pbXBvcnQgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xubm9jay5lbmFibGVOZXRDb25uZWN0KCk7XG5cbmRlc2NyaWJlKCdYTE06JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQgdXJpO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0eGxtJywgVHhsbS5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgdXJpID0gRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGRyZXNzZXM6JywgKCkgPT4ge1xuICAgIGNvbnN0IG5vTWVtb0lkQWRkcmVzcyA9ICdHQklFSlFVQVJKMzNESVpVNEFJUkRPS1lQU1ZLNjZaM081WFU3T09JN0xVT0FKV1RQSTRPQTRKSSc7XG4gICAgY29uc3QgdmFsaWRNZW1vSWRBZGRyZXNzID0gJ0dCSUVKUVVBUkozM0RJWlU0QUlSRE9LWVBTVks2NlozTzVYVTdPT0k3TFVPQUpXVFBJNE9BNEpJP21lbW9JZD01JztcbiAgICBjb25zdCBpbnZhbGlkTWVtb0lkQWRkcmVzcyA9ICdHQklFSlFVQVJKMzNESVpVNEFJUkRPS1lQU1ZLNjZaM081WFU3T09JN0xVT0FKV1RQSTRPQTRKST9tZW1vSWQ9eCc7XG4gICAgY29uc3QgbXVsdGlwbGVNZW1vSWRBZGRyZXNzID0gJ0dCSUVKUVVBUkozM0RJWlU0QUlSRE9LWVBTVks2NlozTzVYVTdPT0k3TFVPQUpXVFBJNE9BNEpJP21lbW9JZD01Jm1lbW9JZD0zJztcbiAgICAvLyBNdXhlZCBhZGRyZXNzIG9mIEdBRkhOVUtPWlQ2UUE0V0pTNllTRENONlhFVEVPUDdRNkFPSEZGTFVHTE5WTTZGWTcyNFVMT1JDXG4gICAgY29uc3QgdmFsaWRNdXhlZEFkZHJlc3MgPSAnTUFGSE5VS09aVDZRQTRXSlM2WVNEQ042WEVURU9QN1E2QU9IRkZMVUdMTlZNNkZZNzI0VUtBQUFBQUFBQUFBQUFFSkNPJztcbiAgICBjb25zdCB2YWxpZE11eGVkQmFzZUFkZHJlc3MgPSAnR0FGSE5VS09aVDZRQTRXSlM2WVNEQ042WEVURU9QN1E2QU9IRkZMVUdMTlZNNkZZNzI0VUxPUkMnO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgYWRkcmVzcyBkZXRhaWxzIHdpdGhvdXQgbWVtb0lkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc0RldGFpbHMgPSBiYXNlY29pbi5nZXRBZGRyZXNzRGV0YWlscyhub01lbW9JZEFkZHJlc3MpO1xuICAgICAgYWRkcmVzc0RldGFpbHMuYWRkcmVzcy5zaG91bGQuZXF1YWwobm9NZW1vSWRBZGRyZXNzKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QoYWRkcmVzc0RldGFpbHMubWVtb0lkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IGFkZHJlc3MgZGV0YWlscyB3aXRoIG1lbW9JZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3NEZXRhaWxzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHModmFsaWRNZW1vSWRBZGRyZXNzKTtcbiAgICAgIGFkZHJlc3NEZXRhaWxzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHZhbGlkTWVtb0lkQWRkcmVzcy5zcGxpdCgnPycpWzBdKTtcbiAgICAgIGFkZHJlc3NEZXRhaWxzLm1lbW9JZC5zaG91bGQuZXF1YWwoJzUnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gaW52YWxpZCBtZW1vIGlkIGFkZHJlc3MnLCAoKSA9PiB7XG4gICAgICAoKCkgPT4ge1xuICAgICAgICBiYXNlY29pbi5nZXRBZGRyZXNzRGV0YWlscyhpbnZhbGlkTWVtb0lkQWRkcmVzcyk7XG4gICAgICB9KS5zaG91bGQudGhyb3coKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gbXVsdGlwbGUgbWVtbyBpZCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgKCgpID0+IHtcbiAgICAgICAgYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHMobXVsdGlwbGVNZW1vSWRBZGRyZXNzKTtcbiAgICAgIH0pLnNob3VsZC50aHJvdygpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoJ0dCUklTNlc1T1pOV1dGSkE2R1lSRjNKQks1V1pOWDVXV0QyS0M2TkNPT0lFTUY3SDZKTVFMVUk0Jykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoJ0dEVTJGRUw2VEhHR09GREhIUDRJNUZITldZNFMyU1hZVUJDRURCNVpSRU1ENlVGUlQ0U1lXU1cyJykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoJ0dEVTJGRUw2VEhHR09GREhIUDRJNUZITldZNFMyU1hZVUJDRURCNVpSRU1ENlVGUlQ0U1lXU1cyP21lbW9JZD0xJykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZEFkZHJlc3MoJ0dEVTJGRUw2VEhHR09GREhIUDRJNUZITldZNFMyU1hZVUJDRURCNVpSRU1ENlVGUlQ0U1lXU1cyP21lbW9JZD14Jykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKCdTQktHQ01CWTU2TUhUVDRFR0UzWUpJWUw0Q1BXS1NHSjdWREVRRjRKM0IzWU81NzZLTkw3RE9ZSicpLnNob3VsZC5lcXVhbChmYWxzZSk7IC8vIHByaXZhdGUga2V5XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcygncjJ1ZFNzc3BZaldTb1VaeHp4THpWNlJ4R2NieWduZ0o4Jykuc2hvdWxkLmVxdWFsKGZhbHNlKTsgLy8geHJwIGFjY291bnRcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgbXV4ZWQgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKHZhbGlkTXV4ZWRBZGRyZXNzKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBjb25zdCBtdXhlZEFkZHJlc3NEZXRhaWxzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHModmFsaWRNdXhlZEFkZHJlc3MpO1xuICAgICAgbXV4ZWRBZGRyZXNzRGV0YWlscy5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgYmFzZUFkZHJlc3M6IHZhbGlkTXV4ZWRCYXNlQWRkcmVzcyxcbiAgICAgICAgYWRkcmVzczogdmFsaWRNdXhlZEFkZHJlc3MsXG4gICAgICAgIGlkOiAnMScsXG4gICAgICAgIG1lbW9JZDogdW5kZWZpbmVkLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgndmVyaWZ5QWRkcmVzcyBzaG91bGQgd29yaycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luLnZlcmlmeUFkZHJlc3Moe1xuICAgICAgICBhZGRyZXNzOiAnR0JSSVM2VzVPWk5XV0ZKQTZHWVJGM0pCSzVXWk5YNVdXRDJLQzZOQ09PSUVNRjdINkpNUUxVSTQnLFxuICAgICAgICByb290QWRkcmVzczogJ0dCUklTNlc1T1pOV1dGSkE2R1lSRjNKQks1V1pOWDVXV0QyS0M2TkNPT0lFTUY3SDZKTVFMVUk0JyxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgYmFzZWNvaW4udmVyaWZ5QWRkcmVzcyh7XG4gICAgICAgIGFkZHJlc3M6ICdHRFUyRkVMNlRIR0dPRkRISFA0STVGSE5XWTRTMlNYWVVCQ0VEQjVaUkVNRDZVRlJUNFNZV1NXMj9tZW1vSWQ9MScsXG4gICAgICAgIHJvb3RBZGRyZXNzOiAnR0RVMkZFTDZUSEdHT0ZESEhQNEk1RkhOV1k0UzJTWFlVQkNFREI1WlJFTUQ2VUZSVDRTWVdTVzInLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luLnZlcmlmeUFkZHJlc3Moe1xuICAgICAgICBhZGRyZXNzOiB2YWxpZE11eGVkQWRkcmVzcyxcbiAgICAgICAgcm9vdEFkZHJlc3M6IHZhbGlkTXV4ZWRCYXNlQWRkcmVzcyxcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYmFzZWNvaW4udmVyaWZ5QWRkcmVzcyh7XG4gICAgICAgICAgYWRkcmVzczogJ0dEVTJGRUw2VEhHR09GREhIUDRJNUZITldZNFMyU1hZVUJDRURCNVpSRU1ENlVGUlQ0U1lXU1cyP21lbW9JZD0yNDM0MzInLFxuICAgICAgICAgIHJvb3RBZGRyZXNzOiAnR0JSSVM2VzVPWk5XV0ZKQTZHWVJGM0pCSzVXWk5YNVdXRDJLQzZOQ09PSUVNRjdINkpNUUxVSTQnLFxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGJhc2Vjb2luLnZlcmlmeUFkZHJlc3Moe1xuICAgICAgICAgIGFkZHJlc3M6ICdHRFUyRkVMNlRIR0dPRkRISFA0STVGSE5XWTRTMlNYWVVCQ0VEQjVaUkVNRDZVRlJUNFNZV1NXMj14JyxcbiAgICAgICAgICByb290QWRkcmVzczogJ0dEVTJGRUw2VEhHR09GREhIUDRJNUZITldZNFMyU1hZVUJDRURCNVpSRU1ENlVGUlQ0U1lXU1cyJyxcbiAgICAgICAgfSlcbiAgICAgICk7XG5cbiAgICAgIGFzc2VydC5yZWplY3RzKFxuICAgICAgICBiYXNlY29pbi52ZXJpZnlBZGRyZXNzKHtcbiAgICAgICAgICBhZGRyZXNzOiAnU0JLR0NNQlk1Nk1IVFQ0RUdFM1lKSVlMNENQV0tTR0o3VkRFUUY0SjNCM1lPNTc2S05MN0RPWUonLFxuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgICAgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGJhc2Vjb2luLnZlcmlmeUFkZHJlc3Moe1xuICAgICAgICAgIGFkZHJlc3M6ICdyMnVkU3NzcFlqV1NvVVp4enhMelY2UnhHY2J5Z25nSjgnLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwdWIga2V5JywgKCkgPT4ge1xuICAgIGNvbnN0IHsgcHViIH0gPSBiYXNlY29pbi5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICBiYXNlY29pbi5pc1ZhbGlkUHViKHB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHZhbGlkYXRlIHJvb3Qga2V5cGFpcicsICgpID0+IHtcbiAgICBjb25zdCB7IHB1YiwgcHJ2IH0gPSBiYXNlY29pbi5rZXljaGFpbnMoKS5jcmVhdGUoeyBpc1Jvb3RLZXk6IHRydWUgfSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFB1YihwdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KHBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHZhbGlkYXRlIHN0ZWxsYXIgdXNlcm5hbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFN0ZWxsYXJVc2VybmFtZSgnZm9vQGJhci5iYXonKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFN0ZWxsYXJVc2VybmFtZSgnZm9vX2JhcjkuYmF6Jykuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRTdGVsbGFyVXNlcm5hbWUoJ2ZvbytiYXJfOS5iYXonKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFN0ZWxsYXJVc2VybmFtZSgnJykuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICBiYXNlY29pbi5pc1ZhbGlkU3RlbGxhclVzZXJuYW1lKCdmb28gYmFyLmJheicpLnNob3VsZC5lcXVhbChmYWxzZSk7IC8vIHdoaXRlc3BhY2UgaXMgbm90IGFsbG93ZWRcbiAgICBiYXNlY29pbi5pc1ZhbGlkU3RlbGxhclVzZXJuYW1lKCdGb29AYmFyLmJheicpLnNob3VsZC5lcXVhbChmYWxzZSk7IC8vIG9ubHkgbG93ZXJjYXNlIGxldHRlcnMgYXJlIGFsbG93ZWRcbiAgfSk7XG5cbiAgaXQoJ1Nob3VsZCBleHBsYWluIGFuIFhMTSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzaWduZWRFeHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eEJhc2U2NDpcbiAgICAgICAgJ0FBQUFBTURIQWJkM083QjJhdVIxZStFSC9MUktlOEljUUJPRitYUDJsT3hXaTFQZkFBQUI5QUFFdkpFQUFBQUJBQUFBQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQkFBQUFCMVJGVTFSSlRrY0FBQUFBQVFBQUFBQUFBQUFCQUFBQUFMZ0VsNHA4NDcyOHpmWHRsL0pkT3N4M1FiSTk3bWN5YnFjWGRmZ2R2NTR6QUFBQUFBQUFBQUVxQmZJQUFBQUFBQUFBQUFGV2kxUGZBQUFBUURvcW83anVPQlphd01sazh6bkliWXFTS2VtamdtSU5vc3AvUDQrMFNGR28veEp5MVlnRDZZRWM2NWFXdXlCeHVjRkZCWENTbEF4UDJaN25QTXlqZXdNPScsXG4gICAgfSk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnNTAwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dEFtb3VudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4bG0nLCAnNTAwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCdHQzRBSkY0S1BUUjMzUEdONlhXWlA0UzVITEdIT1FOU0hYWEdPTVRPVTRMWEw2QTVYNlBESDQ0NScpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnNTAwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uY29pbi5zaG91bGQuZXF1YWwoJ3R4bG0nKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5mZWUuZmVlLnNob3VsZC5lcXVhbCgnNTAwJyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24ubWVtby52YWx1ZS5zaG91bGQuZXF1YWwoJ1RFU1RJTkcnKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5tZW1vLnR5cGUuc2hvdWxkLmVxdWFsKCd0ZXh0Jyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24uY2hhbmdlT3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICBjb25zdCB1bnNpZ25lZEV4cGxhbmF0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4QmFzZTY0OlxuICAgICAgICAnQUFBQUFNREhBYmQzTzdCMmF1UjFlK0VIL0xSS2U4SWNRQk9GK1hQMmxPeFdpMVBmQUFBQVpBQUV2SkVBQUFBQ0FBQUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUFBQUFBQUFBQUVBQUFBQkFBQUFBQUFBQUFFQUFBQUF1QVNYaW56anZiek45ZTJYOGwwNnpIZEJzajN1WnpKdXB4ZDErQjIvbmpNQUFBQUFBQUFBQWxRTDVBQUFBQUFBQUFBQUFBPT0nLFxuICAgIH0pO1xuICAgIHVuc2lnbmVkRXhwbGFuYXRpb24ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAnKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dEFtb3VudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4bG0nLCAnMTAwMDAwMDAwMDAnKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoJ0dDNEFKRjRLUFRSMzNQR042WFdaUDRTNUhMR0hPUU5TSFhYR09NVE9VNExYTDZBNVg2UERINDQ1Jyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwMDAwMDAwJyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmNvaW4uc2hvdWxkLmVxdWFsKCd0eGxtJyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5mZWUuZmVlLnNob3VsZC5lcXVhbCgnMTAwJyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5tZW1vLnZhbHVlLnNob3VsZC5lcXVhbCgnMScpO1xuICAgIHVuc2lnbmVkRXhwbGFuYXRpb24ubWVtby50eXBlLnNob3VsZC5lcXVhbCgnaWQnKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZU91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgfSk7XG5cbiAgaXQoJ1Nob3VsZCBleHBsYWluIGFuIFhMTSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzaWduZWRFeHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eEJhc2U2NDpcbiAgICAgICAgJ0FBQUFBTURIQWJkM083QjJhdVIxZStFSC9MUktlOEljUUJPRitYUDJsT3hXaTFQZkFBQUI5QUFFdkpFQUFBQUJBQUFBQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQkFBQUFCMVJGVTFSSlRrY0FBQUFBQVFBQUFBQUFBQUFCQUFBQUFMZ0VsNHA4NDcyOHpmWHRsL0pkT3N4M1FiSTk3bWN5YnFjWGRmZ2R2NTR6QUFBQUFBQUFBQUVxQmZJQUFBQUFBQUFBQUFGV2kxUGZBQUFBUURvcW83anVPQlphd01sazh6bkliWXFTS2VtamdtSU5vc3AvUDQrMFNGR28veEp5MVlnRDZZRWM2NWFXdXlCeHVjRkZCWENTbEF4UDJaN25QTXlqZXdNPScsXG4gICAgfSk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnNTAwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dEFtb3VudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4bG0nLCAnNTAwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCdHQzRBSkY0S1BUUjMzUEdONlhXWlA0UzVITEdIT1FOU0hYWEdPTVRPVTRMWEw2QTVYNlBESDQ0NScpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnNTAwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uY29pbi5zaG91bGQuZXF1YWwoJ3R4bG0nKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5mZWUuZmVlLnNob3VsZC5lcXVhbCgnNTAwJyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24ubWVtby52YWx1ZS5zaG91bGQuZXF1YWwoJ1RFU1RJTkcnKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5tZW1vLnR5cGUuc2hvdWxkLmVxdWFsKCd0ZXh0Jyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24uY2hhbmdlT3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICBjb25zdCB1bnNpZ25lZEV4cGxhbmF0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4QmFzZTY0OlxuICAgICAgICAnQUFBQUFNREhBYmQzTzdCMmF1UjFlK0VIL0xSS2U4SWNRQk9GK1hQMmxPeFdpMVBmQUFBQVpBQUV2SkVBQUFBQ0FBQUFBUUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFDQUFBQUFBQUFBQUVBQUFBQkFBQUFBQUFBQUFFQUFBQUF1QVNYaW56anZiek45ZTJYOGwwNnpIZEJzajN1WnpKdXB4ZDErQjIvbmpNQUFBQUFBQUFBQWxRTDVBQUFBQUFBQUFBQUFBPT0nLFxuICAgIH0pO1xuICAgIHVuc2lnbmVkRXhwbGFuYXRpb24ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAnKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dEFtb3VudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4bG0nLCAnMTAwMDAwMDAwMDAnKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoJ0dDNEFKRjRLUFRSMzNQR042WFdaUDRTNUhMR0hPUU5TSFhYR09NVE9VNExYTDZBNVg2UERINDQ1Jyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwMDAwMDAwJyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmNvaW4uc2hvdWxkLmVxdWFsKCd0eGxtJyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5mZWUuZmVlLnNob3VsZC5lcXVhbCgnMTAwJyk7XG4gICAgdW5zaWduZWRFeHBsYW5hdGlvbi5tZW1vLnZhbHVlLnNob3VsZC5lcXVhbCgnMScpO1xuICAgIHVuc2lnbmVkRXhwbGFuYXRpb24ubWVtby50eXBlLnNob3VsZC5lcXVhbCgnaWQnKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZU91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB1bnNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgfSk7XG5cbiAgaXQoJ1Nob3VsZCBleHBsYWluIGFuIFhMTSB0cmFuc2FjdGlvbiBieSBwYXNzaW5nIGluIGEgaGV4IGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzaWduZWRFeHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eEhleDpcbiAgICAgICAgJzAwMDAwMDAyMDAwMDAwMDBhYTBjNWM1OTNlZDM2YWYxMjI2OWRjNDYwNWRkMzRkYTMyZmRhYjVjNjc2ZmEwNjQ0ZjI4ZTU5OGRkNTc1MTJhMDAwMGFmYzgwMDAwMDAwMDAwOTg5NjgxMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAxMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAxMGE3NmQxNGVjY2ZkMDA3MmM5OTdiMTIxODliZWI5MjY0NzNmZjBmMDFjNzI5NTc0MzJkYjU2NzhiOGZlYjk0NTAwMDAwMDAwMDAwMDAwMDAwNWY1ZTEwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgIH0pO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwMDAwMCcpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dEFtb3VudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4bG0nLCAnMTAwMDAwMDAwJyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24ub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwoXG4gICAgICAnTUFGSE5VS09aVDZRQTRXSlM2WVNEQ042WEVURU9QN1E2QU9IRkZMVUdMTlZNNkZZNzI0VUtBQUFBQUFBQUFBQUFFSkNPJ1xuICAgICk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMDAwMDAnKTtcbiAgICBzaWduZWRFeHBsYW5hdGlvbi5vdXRwdXRzWzBdLmNvaW4uc2hvdWxkLmVxdWFsKCd0eGxtJyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24uZmVlLmZlZS5zaG91bGQuZXF1YWwoJzQ1MDAwJyk7XG4gICAgc2lnbmVkRXhwbGFuYXRpb24uY2hhbmdlT3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIHNpZ25lZEV4cGxhbmF0aW9uLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgfSk7XG5cbiAgaXQoJ1Nob3VsZCBleHBsYWluIGEgdHJ1c3RsaW5lIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4QmFzZTY0OlxuICAgICAgICAnQUFBQUFJS1dPNlIwL1Y0b0pEazJMWnNkaUVJbkl6Z0o2TDBHeG1TVTJGZnM4WTdaQUFBQkxBQUlqNEVBQUFBQ0FBQUFBQUFBQUFBQUFBQUJBQUFBQUFBQUFBWUFBQUFCUWxOVUFBQUFBQUJoTkRwYnVZNGZycmd3VlFxa3dzN2p4SytrNElNcko2QmFFME9GVXZhOXZ3QUFBT2pVcFJBQUFBQUFBQUFBQUFBPScsXG4gICAgfSk7XG4gICAgZXhwbGFuYXRpb24ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIGV4cGxhbmF0aW9uLmZlZS5mZWUuc2hvdWxkLmVxdWFsKCczMDAnKTtcbiAgICBleHBsYW5hdGlvbi5tZW1vLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgIGV4cGxhbmF0aW9uLmNoYW5nZU91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICBleHBsYW5hdGlvbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgZXhwbGFuYXRpb24ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIGV4cGxhbmF0aW9uLm9wZXJhdGlvbnNbMF0ubGltaXQuc2hvdWxkLmVxdWFsKCcxMDAwMDAwMDAwMDAwJyk7XG4gICAgZXhwbGFuYXRpb24ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbCgndHhsbTpCU1QtR0JRVElPUzNYR0hCN0xWWUdCS1FWSkdDWjNSNEpMNUU0Q0JTV0o1QUxJSlVIQktTNjI2MzY0NEwnKTtcbiAgICBleHBsYW5hdGlvbi5vcGVyYXRpb25zWzBdLnR5cGUuc2hvdWxkLmVxdWFsKCdjaGFuZ2VUcnVzdCcpO1xuICAgIGV4cGxhbmF0aW9uLm9wZXJhdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Fzc2V0Jyk7XG4gICAgZXhwbGFuYXRpb24ub3BlcmF0aW9uc1swXS5hc3NldC5jb2RlLnNob3VsZC5lcXVhbCgnQlNUJyk7XG4gICAgZXhwbGFuYXRpb24ub3BlcmF0aW9uc1swXS5hc3NldC5pc3N1ZXIuc2hvdWxkLmVxdWFsKCdHQlFUSU9TM1hHSEI3TFZZR0JLUVZKR0NaM1I0Skw1RTRDQlNXSjVBTElKVUhCS1M2MjYzNjQ0TCcpO1xuICB9KTtcblxuICBpdCgnU2hvdWxkIGV4cGxhaW4gYSB0b2tlbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBleHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICB0eEJhc2U2NDpcbiAgICAgICAgJ0FBQUFBSVhwaUdQUi9ZYytnU042MTRoQWYxTjFoZWNYRkw3TGFjOTlvbHBxMzhLL0FBQUFaQUFDOVRBQUFBQUVBQUFBQUFBQUFBQUFBQUFCQUFBQUFBQUFBQUVBQUFBQWdwWTdwSFQ5WGlna09UWXRteDJJUWljak9Bbm92UWJHWkpUWVYrenhqdGtBQUFBQlFsTlVBQUFBQUFCaE5EcGJ1WTRmcnJnd1ZRcWt3czdqeEsrazRJTXJKNkJhRTBPRlV2YTl2d0FBQUFBZHpXVUFBQUFBQUFBQUFBRnEzOEsvQUFBQVFQSlRMSUdHWTA2QnVWRHcwSVNhc1l3SFpwUjZWMzhDYU9mR2hTb29jbFkrNElCRTlKS2RLdU15R05YWENjRnhNL054clg2NGpoQlhrK2xXdmpqbzR3WT0nLFxuICAgIH0pO1xuICAgIGV4cGxhbmF0aW9uLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICBleHBsYW5hdGlvbi5mZWUuZmVlLnNob3VsZC5lcXVhbCgnMTAwJyk7XG4gICAgZXhwbGFuYXRpb24ubWVtby5zaG91bGQuYmUuZW1wdHkoKTtcbiAgICBleHBsYW5hdGlvbi5jaGFuZ2VPdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgZXhwbGFuYXRpb24uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIGV4cGxhbmF0aW9uLm91dHB1dEFtb3VudHMuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAndHhsbTpCU1QtR0JRVElPUzNYR0hCN0xWWUdCS1FWSkdDWjNSNEpMNUU0Q0JTV0o1QUxJSlVIQktTNjI2MzY0NEwnLFxuICAgICAgJzUwMDAwMDAwMCdcbiAgICApO1xuICB9KTtcblxuICBpdCgnaXNWYWxpZE1lbW9JZCBzaG91bGQgd29yaycsIGZ1bmN0aW9uICgpIHtcbiAgICBiYXNlY29pbi5pc1ZhbGlkTWVtbyh7IHZhbHVlOiAnMScsIHR5cGU6ICdpZCcgfSkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vKHsgdmFsdWU6ICd1bm8nLCB0eXBlOiAndGV4dCcgfSkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygzMikuZmlsbCgxMCk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZE1lbW8oeyB2YWx1ZTogYnVmZmVyLCB0eXBlOiAnaGFzaCcgfSkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vKHsgdmFsdWU6IGJ1ZmZlci50b1N0cmluZygnaGV4JyksIHR5cGU6ICdoYXNoJyB9KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZE1lbW8oeyB2YWx1ZTogMSwgdHlwZTogJ2lkJyB9KS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vKHsgdmFsdWU6IDEsIHR5cGU6ICd0ZXh0JyB9KS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIGJhc2Vjb2luLmlzVmFsaWRNZW1vKHsgdmFsdWU6ICcxJywgdHlwZTogJ2hhc2gnIH0pLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZE1lbW8oeyB2YWx1ZTogJzEnLCB0eXBlOiAncmV0dXJuJyB9KS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHN1cHBsZW1lbnQgd2FsbGV0IGdlbmVyYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgd2FsbGV0UGFyYW1zID0gYXdhaXQgYmFzZWNvaW4uc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KHt9KTtcbiAgICB3YWxsZXRQYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Jvb3RQcml2YXRlS2V5Jyk7XG4gICAgYmFzZWNvaW4uaXNWYWxpZFBydih3YWxsZXRQYXJhbXMucm9vdFByaXZhdGVLZXkpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBzdXBwbGVtZW50IHdhbGxldCBnZW5lcmF0aW9uIHdpdGggcHJvdmlkZWQgcHJpdmF0ZSBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgcm9vdFByaXZhdGVLZXkgPSBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoKS5wcnY7XG4gICAgY29uc3Qgd2FsbGV0UGFyYW1zID0gYXdhaXQgYmFzZWNvaW4uc3VwcGxlbWVudEdlbmVyYXRlV2FsbGV0KHsgcm9vdFByaXZhdGVLZXkgfSk7XG4gICAgd2FsbGV0UGFyYW1zLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyb290UHJpdmF0ZUtleScpO1xuICAgIHdhbGxldFBhcmFtcy5yb290UHJpdmF0ZUtleS5zaG91bGQuZXF1YWwocm9vdFByaXZhdGVLZXkpO1xuICB9KTtcblxuICBkZXNjcmliZSgnZGVyaXZlS2V5V2l0aFNlZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBkZXJpdmUga2V5IHdpdGggc2VlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIGJhc2Vjb2luLmRlcml2ZUtleVdpdGhTZWVkKCd0ZXN0Jyk7XG4gICAgICB9KS5zaG91bGQudGhyb3coJ21ldGhvZCBkZXJpdmVLZXlXaXRoU2VlZCBub3Qgc3VwcG9ydGVkIGZvciBlZGRzYSBjdXJ2ZScpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiYXNlY29pbjtcbiAgICBsZXQgd2FsbGV0O1xuICAgIGxldCBoYWxmU2lnbmVkVHJhbnNhY3Rpb247XG4gICAgbGV0IHJvb3RLZXlIYWxmU2lnbmVkVHJhbnNhY3Rpb247XG5cbiAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICBwdWI6ICdHQTM0TlBRNE01NEhIWkJLU0RaNUIzSjNCWkhUWEtDWkQ0VUZPMk9ZWkVSUE9BU0s0REFBVFNJQicsXG4gICAgICBwcnY6ICdTREFESlNUWk5JS0Y0Nk5NN0xFM1pITVg0VEoyVkpCTDdQVEVSTkRMV0haNVU2S05PNVM3WEZKRCcsXG4gICAgfTtcbiAgICBjb25zdCBiYWNrdXBLZXljaGFpbiA9IHtcbiAgICAgIHB1YjogJ0dDM0QzWk5OSzdHSExNU1dKQTU0RFFPNlFKVUpKRjdLNko1SkdDRVc0NVpUNlFNS1o2UE1VSFVNJyxcbiAgICAgIHBydjogJ1NBMjJUREJJTkxaTUdZVURWWEdVUDJKTVlJUTNEVEpFNTNQTlFVVkNESzczWFJTNlREVllVN1dXJyxcbiAgICB9O1xuICAgIC8vIFRoaXMga2V5IHBhaXIgaXMgdGhlIGRlY29kZWQgdmVyc2lvbiBvZiB0aGUgdXNlcktleWNoYWluIGFib3ZlXG4gICAgY29uc3Qgcm9vdEtleWNoYWluID0ge1xuICAgICAgcHViOiAnMzdjNmJlMWM2Nzc4NzNlNDJhOTBmM2QwZWQzYjBlNGYzYmE4NTkxZjI4NTc2OWQ4YzkyMmY3MDI0YWUwYzAwOScsXG4gICAgICBwcnY6ICdjMDM0Y2E3OTZhMTQ1ZTc5YWNmYWM5YmM5ZDk3ZTRkM2FhYTQyYmZiZTY0OGI0NmJiMWYzZGE3OTRkNzc2NWZiMzdjNmJlMWM2Nzc4NzNlNDJhOTBmM2QwZWQzYjBlNGYzYmE4NTkxZjI4NTc2OWQ4YzkyMmY3MDI0YWUwYzAwOScsXG4gICAgfTtcbiAgICAvLyBUaGlzIGtleSBwYWlyIGlzIHRoZSBkZWNvZGVkIHZlcnNpb24gb2YgdGhlIGJhY2t1cEtleWNoYWluIGFib3ZlXG4gICAgY29uc3QgYmFja3VwUm9vdEtleWNoYWluID0ge1xuICAgICAgcHViOiAnYjYzZGU1YWQ1N2NjNzViMjU2NDgzYmMxYzFkZTgyNjg5NDk3ZWFmMjdhOTMwODk2ZTc3MzNmNDE4YWNmOWVjYScsXG4gICAgICBwcnY6ICczNWE5OGMyODZhZjJjMzYyODNhZGNkNDdlOTJjYzIyMWIxY2QyNGVlZGVkODUyYTIxYWJmYmJjNjVlOThlYjhhYjYzZGU1YWQ1N2NjNzViMjU2NDgzYmMxYzFkZTgyNjg5NDk3ZWFmMjdhOTMwODk2ZTc3MzNmNDE4YWNmOWVjYScsXG4gICAgfTtcblxuICAgIGNvbnN0IHByZWJ1aWxkID0ge1xuICAgICAgdHhCYXNlNjQ6XG4gICAgICAgICdBQUFBQUdSblhnMTlGdGVHLzd6UGQrakRDN0xEdlJsemdmRkMrSnJQaFJlcDBrWWlBQUFBWkFCLzRjVUFBQUFDQUFBQUFBQUFBQUFBQUFBQkFBQUFBUUFBQUFCa1oxNE5mUmJYaHYrOHozZm93d3V5dzcwWmM0SHhRdmlhejRVWHFkSkdJZ0FBQUFFQUFBQUFtbGpULytGZWRkZG5BSHdvOTVkT0M0Uk55NmVWTFNlaGFKWTM0YjlHeHVZQUFBQUFBQUFBQUFlaElBQUFBQUFBQUFBQUFBPT0nLFxuICAgICAgdHhJbmZvOiB7XG4gICAgICAgIGZlZTogMTAwLFxuICAgICAgICBzZXF1ZW5jZTogJzM1OTk1NTU4MjY3MDYwMjI2JyxcbiAgICAgICAgc291cmNlOiAnR0JTR09YUU5QVUxOUEJYN1hUSFhQMkdEQk9aTUhQSVpPT0E3Q1FYWVRMSFlLRjVKMkpEQ0Y3TFQnLFxuICAgICAgICBvcGVyYXRpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYW1vdW50OiAnMTIuOCcsIC8vIDEyLjggWExNXG4gICAgICAgICAgICBhc3NldDogeyBjb2RlOiAnWExNJyB9LFxuICAgICAgICAgICAgZGVzdGluYXRpb246ICdHQ05GUlU3NzRGUEhMVjNIQUI2Q1I1NFhKWUZZSVRPTFU2S1MySjVCTkNMRFBZTjdJM0RPTUlQWScsXG4gICAgICAgICAgICB0eXBlOiAncGF5bWVudCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgc2lnbmF0dXJlczogW10sXG4gICAgICB9LFxuICAgICAgZmVlSW5mbzoge1xuICAgICAgICBoZWlnaHQ6IDEyMzQ1NixcbiAgICAgICAgeGxtQmFzZUZlZTogJzEwMCcsXG4gICAgICAgIHhsbUJhc2VSZXNlcnZlOiAnNTAwMDAwMCcsXG4gICAgICB9LFxuICAgICAgd2FsbGV0SWQ6ICc1YTc4ZGQ1NjFjNjI1OGE5MDdmMWVlYWVlMTMyZjc5NicsXG4gICAgfTtcbiAgICBjb25zdCBzaWduZWRUeEJhc2U2NCA9XG4gICAgICAnQUFBQUFHUm5YZzE5RnRlRy83elBkK2pEQzdMRHZSbHpnZkZDK0pyUGhSZXAwa1lpQUFBQVpBQi80Y1VBQUFBQ0FBQUFBQUFBQUFBQUFBQUJBQUFBQVFBQUFBQmtaMTROZlJiWGh2Kzh6M2Zvd3d1eXc3MFpjNEh4UXZpYXo0VVhxZEpHSWdBQUFBRUFBQUFBbWxqVC8rRmVkZGRuQUh3bzk1ZE9DNFJOeTZlVkxTZWhhSlkzNGI5R3h1WUFBQUFBQUFBQUFBZWhJQUFBQUFBQUFBQUFBVXJnd0FrQUFBQkFPRXhjdlZKSVVKdjlIdVZmYlYweTdsUlBSQVJ2NHdEdGNkaEhHN1FONDBoNXdRMnV3UEY1Mk9HUThLWSs2NmExQS84bE5LQjc1c2dqMnhqNDRzOGxEUT09JztcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICAgIGlkOiAnNWE3OGRkNTYxYzYyNThhOTA3ZjFlZWFlZTEzMmY3OTYnLFxuICAgICAgICB1c2VyczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXI6ICc1NDNjMTFlZDM1NmQwMGNiNzYwMDAwMGI5ODc5NDUwMycsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY29pbjogJ3R4bG0nLFxuICAgICAgICBsYWJlbDogJ1ZlcmlmaWNhdGlvbiBXYWxsZXQnLFxuICAgICAgICBtOiAyLFxuICAgICAgICBuOiAzLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzVhNzhkZDU2YmZlNDI0YWEwN2FhMDY4NjUxYjE5NGZkJyxcbiAgICAgICAgICAnNWE3OGRkNTY3NGE3MGViNDA3OWY1ODc5N2RmZTJmNWUnLFxuICAgICAgICAgICc1YTc4ZGQ1NjFjNjI1OGE5MDdmMWVlYTlmMWQwNzllMicsXG4gICAgICAgIF0sXG4gICAgICAgIHRhZ3M6IFsnNWE3OGRkNTYxYzYyNThhOTA3ZjFlZWFlZTEzMmY3OTYnXSxcbiAgICAgICAgZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9uczogZmFsc2UsXG4gICAgICAgIGZyZWV6ZToge30sXG4gICAgICAgIGRlbGV0ZWQ6IGZhbHNlLFxuICAgICAgICBhcHByb3ZhbHNSZXF1aXJlZDogMSxcbiAgICAgICAgaXNDb2xkOiB0cnVlLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICBjbGllbnRGbGFnczogW10sXG4gICAgICAgIGJhbGFuY2U6IDY1MDAwMDAwMCxcbiAgICAgICAgY29uZmlybWVkQmFsYW5jZTogNjUwMDAwMDAwLFxuICAgICAgICBzcGVuZGFibGVCYWxhbmNlOiA2NTAwMDAwMDAsXG4gICAgICAgIGJhbGFuY2VTdHJpbmc6ICc2NTAwMDAwMDAnLFxuICAgICAgICBjb25maXJtZWRCYWxhbmNlU3RyaW5nOiAnNjUwMDAwMDAwJyxcbiAgICAgICAgc3BlbmRhYmxlQmFsYW5jZVN0cmluZzogJzY1MDAwMDAwMCcsXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgaWQ6ICc1YTc4ZGUyYmJmZTQyNGFhMDdhYTEzMWVjMDNjOGRjMScsXG4gICAgICAgICAgYWRkcmVzczogJ0dCU0dPWFFOUFVMTlBCWDdYVEhYUDJHREJPWk1IUElaT09BN0NRWFlUTEhZS0Y1SjJKRENGN0xUJyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICBjb2luOiAndHhsbScsXG4gICAgICAgICAgd2FsbGV0OiAnNWE3OGRkNTYxYzYyNThhOTA3ZjFlZWFlZTEzMmY3OTYnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0sXG4gICAgICAgIHBlbmRpbmdBcHByb3ZhbHM6IFtdLFxuICAgICAgfTtcbiAgICAgIHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB3YWxsZXREYXRhKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhIHByZWJ1aWxkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gc2lnbiB0cmFuc2FjdGlvblxuICAgICAgaGFsZlNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgd2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHByZWJ1aWxkLFxuICAgICAgICBwcnY6IHVzZXJLZXljaGFpbi5wcnYsXG4gICAgICB9KTtcbiAgICAgIGhhbGZTaWduZWRUcmFuc2FjdGlvbi5oYWxmU2lnbmVkLnR4QmFzZTY0LnNob3VsZC5lcXVhbChzaWduZWRUeEJhc2U2NCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYSBwcmVidWlsZCB3aXRoIHJvb3Qga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcm9vdEtleUhhbGZTaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHdhbGxldC5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiBwcmVidWlsZCxcbiAgICAgICAgcHJ2OiByb290S2V5Y2hhaW4ucHJ2LFxuICAgICAgfSk7XG4gICAgICByb290S2V5SGFsZlNpZ25lZFRyYW5zYWN0aW9uLmhhbGZTaWduZWQudHhCYXNlNjQuc2hvdWxkLmVxdWFsKHNpZ25lZFR4QmFzZTY0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBhIHRyYW5zYWN0aW9uIHdpdGggZ2VuZXJhdGVkIHJvb3Qga2V5IHBhaXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20ocm9vdEtleWNoYWluLnBydi5zbGljZSgwLCA2NCksICdoZXgnKTtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcihzZWVkKTtcbiAgICAgIGtwLnBydi5sZW5ndGguc2hvdWxkLmVxdWFsKDEyOCk7XG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHggPSBhd2FpdCB3YWxsZXQuc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDogcHJlYnVpbGQsXG4gICAgICAgIHBydjoga3AucHJ2LFxuICAgICAgfSk7XG4gICAgICBoYWxmU2lnbmVkVHguaGFsZlNpZ25lZC50eEJhc2U2NC5zaG91bGQuZXF1YWwoc2lnbmVkVHhCYXNlNjQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdGhlIHVzZXIgc2lnbmF0dXJlIG9uIGEgdHgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyUHViID0gdXNlcktleWNoYWluLnB1YjtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IHN0ZWxsYXIuVHJhbnNhY3Rpb24oaGFsZlNpZ25lZFRyYW5zYWN0aW9uLmhhbGZTaWduZWQudHhCYXNlNjQsIHN0ZWxsYXIuTmV0d29ya3MuVEVTVE5FVCk7XG4gICAgICBjb25zdCB2YWxpZFNpZ25hdHVyZSA9IGJhc2Vjb2luLnZlcmlmeVNpZ25hdHVyZSh1c2VyUHViLCB0eC5oYXNoKCksIHR4LnNpZ25hdHVyZXNbMF0uc2lnbmF0dXJlKCkpO1xuICAgICAgdmFsaWRTaWduYXR1cmUuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdGhlIHVzZXIgc2lnbmF0dXJlIG9uIGEgdHggZ2l2ZW4gcm9vdCBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByb290UHViID0gcm9vdEtleWNoYWluLnB1YjtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IHN0ZWxsYXIuVHJhbnNhY3Rpb24ocm9vdEtleUhhbGZTaWduZWRUcmFuc2FjdGlvbi5oYWxmU2lnbmVkLnR4QmFzZTY0LCBzdGVsbGFyLk5ldHdvcmtzLlRFU1RORVQpO1xuICAgICAgY29uc3QgdmFsaWRTaWduYXR1cmUgPSBiYXNlY29pbi52ZXJpZnlTaWduYXR1cmUocm9vdFB1YiwgdHguaGFzaCgpLCB0eC5zaWduYXR1cmVzWzBdLnNpZ25hdHVyZSgpKTtcbiAgICAgIHZhbGlkU2lnbmF0dXJlLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgdGhlIHdyb25nIHNpZ25hdHVyZSBvbiBhIHR4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5UGFpciA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgY29uc3QgdHggPSBuZXcgc3RlbGxhci5UcmFuc2FjdGlvbihoYWxmU2lnbmVkVHJhbnNhY3Rpb24uaGFsZlNpZ25lZC50eEJhc2U2NCwgc3RlbGxhci5OZXR3b3Jrcy5URVNUTkVUKTtcbiAgICAgIGNvbnN0IHZhbGlkU2lnbmF0dXJlID0gYmFzZWNvaW4udmVyaWZ5U2lnbmF0dXJlKGtleVBhaXIucHViLCB0eC5oYXNoKCksIHR4LnNpZ25hdHVyZXNbMF0uc2lnbmF0dXJlKCkpO1xuICAgICAgdmFsaWRTaWduYXR1cmUuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgdGhlIHdyb25nIHNpZ25hdHVyZSBvbiBhIHR4IGdpdmVuIHJvb3Qga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5UGFpciA9IGJhc2Vjb2luLmdlbmVyYXRlUm9vdEtleVBhaXIoKTtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IHN0ZWxsYXIuVHJhbnNhY3Rpb24ocm9vdEtleUhhbGZTaWduZWRUcmFuc2FjdGlvbi5oYWxmU2lnbmVkLnR4QmFzZTY0LCBzdGVsbGFyLk5ldHdvcmtzLlRFU1RORVQpO1xuICAgICAgY29uc3QgdmFsaWRTaWduYXR1cmUgPSBiYXNlY29pbi52ZXJpZnlTaWduYXR1cmUoa2V5UGFpci5wdWIsIHR4Lmhhc2goKSwgdHguc2lnbmF0dXJlc1swXS5zaWduYXR1cmUoKSk7XG4gICAgICB2YWxpZFNpZ25hdHVyZS5zaG91bGQuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSByZWNvdmVyeSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICdHRERIQ0tNWVlZQ1ZYT1NBVk1TRUlZR1lOWDc0TElBVjNBQ1hZUTZXUE1EVUY3VzNLWk5XVEhUSCc7XG4gICAgICBub2NrKCdodHRwczovL2hvcml6b24tdGVzdG5ldC5zdGVsbGFyLm9yZy9hY2NvdW50cycpXG4gICAgICAgIC5nZXQoJy8nICsgd2FsbGV0LnJlY2VpdmVBZGRyZXNzKCkpXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzZXF1ZW5jZTogJzM1OTk1NTU4MjY3MDYwMjI2JyxcbiAgICAgICAgICBiYWxhbmNlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhc3NldF90eXBlOiAnbmF0aXZlJyxcbiAgICAgICAgICAgICAgYmFsYW5jZTogJzY1MDAwMDAwMDAnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgbm9jaygnaHR0cHM6Ly9ob3Jpem9uLXRlc3RuZXQuc3RlbGxhci5vcmcvYWNjb3VudHMnKVxuICAgICAgICAuZ2V0KCcvJyArIGRlc3RpbmF0aW9uQWRkcmVzcylcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHNlcXVlbmNlOiAnMzU5OTU1NTgyNjcwNjAyMTMnLFxuICAgICAgICAgIGJhbGFuY2VzOiAxMzEzMTMxMyxcbiAgICAgICAgfSk7XG5cbiAgICAgIG5vY2soJ2h0dHBzOi8vaG9yaXpvbi10ZXN0bmV0LnN0ZWxsYXIub3JnJylcbiAgICAgICAgLmdldCgnL2xlZGdlcnMnKVxuICAgICAgICAucXVlcnkoe1xuICAgICAgICAgIG9yZGVyOiAnZGVzYycsXG4gICAgICAgICAgbGltaXQ6IDEsXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICByZWNvcmRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGJhc2VfcmVzZXJ2ZV9pbl9zdHJvb3BzOiAnNTAwMDAwMCcsXG4gICAgICAgICAgICAgIGJhc2VfZmVlX2luX3N0cm9vcHM6IDEwMCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnBlcnNpc3QoKTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogJ0dBMzROUFE0TTU0SEhaQktTRFo1QjNKM0JaSFRYS0NaRDRVRk8yT1laRVJQT0FTSzREQUFUU0lCJyxcbiAgICAgICAgYmFja3VwS2V5OiAnR0MzRDNaTk5LN0dITE1TV0pBNTREUU82UUpVSkpGN0s2SjVKR0NFVzQ1WlQ2UU1LWjZQTVVIVU0nLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHJvb3RBZGRyZXNzOiB3YWxsZXQucmVjZWl2ZUFkZHJlc3MoKSxcbiAgICAgIH0pO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5LnR4QmFzZTY0KTtcbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeS5mZWVJbmZvKTtcbiAgICAgIHJlY292ZXJ5LmNvaW4uc2hvdWxkLmVxdWFsKCd0eGxtJyk7XG4gICAgICByZWNvdmVyeS50eEJhc2U2NC5zaG91bGQuYmUuYS5TdHJpbmcoKTtcbiAgICAgIHJlY292ZXJ5LnJlY292ZXJ5QW1vdW50LnNob3VsZC5iZS5hLk51bWJlcigpO1xuICAgICAgcmVjb3ZlcnkuZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgdHJhbnNhY3Rpb24gc2lnbmVkIHdpdGggdGhlIHdyb25nIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgd2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHByZWJ1aWxkLFxuICAgICAgICBwcnY6IGJhY2t1cEtleWNoYWluLnBydixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdHQ05GUlU3NzRGUEhMVjNIQUI2Q1I1NFhKWUZZSVRPTFU2S1MySjVCTkNMRFBZTjdJM0RPTUlQWScsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMjgwMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhCYXNlNjQ6IHR4LmhhbGZTaWduZWQudHhCYXNlNjQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICBkaXNhYmxlTmV0d29ya2luZzogdHJ1ZSxcbiAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICBiYWNrdXA6IHsgcHViOiBiYWNrdXBLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RyYW5zYWN0aW9uIHNpZ25lZCB3aXRoIHdyb25nIGtleScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZlcmlmeSBhIHRyYW5zYWN0aW9uIHNpZ25lZCB3aXRoIHRoZSB3cm9uZyByb290IGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgd2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHByZWJ1aWxkLFxuICAgICAgICBwcnY6IGJhY2t1cFJvb3RLZXljaGFpbi5wcnYsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnR0NORlJVNzc0RlBITFYzSEFCNkNSNTRYSllGWUlUT0xVNktTMko1Qk5DTERQWU43STNET01JUFknLFxuICAgICAgICAgICAgYW1vdW50OiAnMTI4MDAwMDAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4QmFzZTY0OiB0eC5oYWxmU2lnbmVkLnR4QmFzZTY0LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHtcbiAgICAgICAgZGlzYWJsZU5ldHdvcmtpbmc6IHRydWUsXG4gICAgICAgIGtleWNoYWluczoge1xuICAgICAgICAgIHVzZXI6IHsgcHViOiByb290S2V5Y2hhaW4ucHViIH0sXG4gICAgICAgICAgYmFja3VwOiB7IHB1YjogYmFja3VwUm9vdEtleWNoYWluLnB1YiB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHJhbnNhY3Rpb24gc2lnbmVkIHdpdGggd3Jvbmcga2V5Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgdHJhbnNhY3Rpb24gdG8gdGhlIHdyb25nIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgd2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHByZWJ1aWxkLFxuICAgICAgICBwcnY6IGJhY2t1cEtleWNoYWluLnBydixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdHQUszTlNCNDNFVkNaS0RINFBZR0pQQ1ZQT1laN1g3S0lSM1pUV1NZUktSTUpXR0c1VEFCTTZUSCcsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMjgwMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhCYXNlNjQ6IHR4LmhhbGZTaWduZWQudHhCYXNlNjQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICBkaXNhYmxlTmV0d29ya2luZzogdHJ1ZSxcbiAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICBiYWNrdXA6IHsgcHViOiBiYWNrdXBLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RyYW5zYWN0aW9uIHByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGV4cGVjdGVkIHJlY2lwaWVudCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZlcmlmeSBhIHRyYW5zYWN0aW9uIHdpdGggdGhlIHdyb25nIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgd2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHByZWJ1aWxkLFxuICAgICAgICBwcnY6IGJhY2t1cEtleWNoYWluLnBydixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICdHQ05GUlU3NzRGUEhMVjNIQUI2Q1I1NFhKWUZZSVRPTFU2S1MySjVCTkNMRFBZTjdJM0RPTUlQWScsXG4gICAgICAgICAgICBhbW91bnQ6ICcxMzAwMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhCYXNlNjQ6IHR4LmhhbGZTaWduZWQudHhCYXNlNjQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICBkaXNhYmxlTmV0d29ya2luZzogdHJ1ZSxcbiAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICBiYWNrdXA6IHsgcHViOiBiYWNrdXBLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RyYW5zYWN0aW9uIHByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGV4cGVjdGVkIGFtb3VudCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZlcmlmeSBhIHRyYW5zYWN0aW9uIHdpdGhvdXQgcmVjaXBpZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHByZWJ1aWx0ID0ge1xuICAgICAgICB0eEJhc2U2NDpcbiAgICAgICAgICAnQUFBQUFQMXFlNDRqK2k0dUlUK2FyYkQ0UURRQnQ4cnlFZUpkN2EwanNrUTNud0RlQUFBQUFBQi80Y1VBQUFBQ0FBQUFBQUFBQUFJQUFBQUFBQUFBQVFBQUFBQUFBQUFBQUFBQUFBPT0nLFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBmZWU6IDAsXG4gICAgICAgICAgc2VxdWVuY2U6ICczNTk5NTU1ODI2NzA2MDIyNicsXG4gICAgICAgICAgc291cmNlOiAnR0Q2V1U2NE9FUDVDNExSQkg2TkszTUhZSUEyQURONks2SUk2RVhQTlZVUjNFUkJYVDRBTjRBQ0QnLFxuICAgICAgICAgIG9wZXJhdGlvbnM6IFtdLFxuICAgICAgICAgIHNpZ25hdHVyZXM6IFtdLFxuICAgICAgICB9LFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgaGVpZ2h0OiAxMjM0NTYsXG4gICAgICAgICAgeGxtQmFzZUZlZTogJzEwMCcsXG4gICAgICAgICAgeGxtQmFzZVJlc2VydmU6ICc1MDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgICAgd2FsbGV0SWQ6ICc1YTc4ZGQ1NjFjNjI1OGE5MDdmMWVlYWVlMTMyZjc5NicsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBrZXlQYWlyID0ge1xuICAgICAgICBwdWI6ICdHQUE0TFZCRTJIRUtFQ05XRFJUMk5MVFNCV0ZJWlJHVEVRRkM3QkxPUkVNTVBOREhGUlVHUDNWWicsXG4gICAgICAgIHBydjogJ1NDSVZTVFVKWDdTWUpaSEtNSkk0WUY3WVdBMjdGVTdYTjVFSDRPV0JGTDJZMktUWUk3SVAyREZaJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIHNpZ24gdHJhbnNhY3Rpb25cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgd2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHByZWJ1aWx0LFxuICAgICAgICBwcnY6IGtleVBhaXIucHJ2LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0dBVUtBM1pUSDNEWjZUSEJDUEw2QU9RQkNFRUJJRllEVTRGR1hVQ0hPQzdQSUxYR1VQVFVCSjZFJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEzMDAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEJhc2U2NDogdHguaGFsZlNpZ25lZC50eEJhc2U2NCxcbiAgICAgIH07XG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgIGRpc2FibGVOZXR3b3JraW5nOiB0cnVlLFxuICAgICAgICBrZXljaGFpbnM6IHtcbiAgICAgICAgICB1c2VyOiB7IHB1YjogdXNlcktleWNoYWluLnB1YiB9LFxuICAgICAgICAgIGJhY2t1cDogeyBwdWI6IGJhY2t1cEtleWNoYWluLnB1YiB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHJhbnNhY3Rpb24gcHJlYnVpbGQgZG9lcyBub3QgaGF2ZSBhbnkgb3BlcmF0aW9ucycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0dDTkZSVTc3NEZQSExWM0hBQjZDUjU0WEpZRllJVE9MVTZLUzJKNUJOQ0xEUFlON0kzRE9NSVBZJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEyODAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEJhc2U2NDogaGFsZlNpZ25lZFRyYW5zYWN0aW9uLmhhbGZTaWduZWQudHhCYXNlNjQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICBkaXNhYmxlTmV0d29ya2luZzogdHJ1ZSxcbiAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICBiYWNrdXA6IHsgcHViOiBiYWNrdXBLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCB2YWxpZFRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdHJhbnNhY3Rpb24gd2l0aCByb290IGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ0dDTkZSVTc3NEZQSExWM0hBQjZDUjU0WEpZRllJVE9MVTZLUzJKNUJOQ0xEUFlON0kzRE9NSVBZJyxcbiAgICAgICAgICAgIGFtb3VudDogJzEyODAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEJhc2U2NDogcm9vdEtleUhhbGZTaWduZWRUcmFuc2FjdGlvbi5oYWxmU2lnbmVkLnR4QmFzZTY0LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHtcbiAgICAgICAgZGlzYWJsZU5ldHdvcmtpbmc6IHRydWUsXG4gICAgICAgIGtleWNoYWluczoge1xuICAgICAgICAgIHVzZXI6IHsgcHViOiByb290S2V5Y2hhaW4ucHViIH0sXG4gICAgICAgICAgYmFja3VwOiB7IHB1YjogYmFja3VwUm9vdEtleWNoYWluLnB1YiB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KTtcbiAgICAgIHZhbGlkVHJhbnNhY3Rpb24uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3RydXN0bGluZSB0cmFuc2FjdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgdHJ1c3RsaW5lIHRyYW5zYWN0aW9uIHdpdGggdW5tYXRjaGluZyBudW1iZXIgb2YgdHJ1c3RsaW5lcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgcmVjaXBpZW50czogW10sXG4gICAgICAgICAgdHlwZTogJ3RydXN0bGluZScsXG4gICAgICAgICAgdHJ1c3RsaW5lczogW10sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYnVpbGRSZXN1bHQgPSB7XG4gICAgICAgICAgdHhCYXNlNjQ6XG4gICAgICAgICAgICAnQUFBQUFOc0tySFYyQlZqQUNGdDJ4bHloeFl6UDJNTkJtYjRJUTVFOS9XaUppVjNUQUFBQkxBQU00YUVBQUFBSEFBQUFBQUFBQUFBQUFBQUJBQUFBQUFBQUFBWUFBQUFCUWxOVUFBQUFBQUJoTkRwYnVZNGZycmd3VlFxa3dzN2p4SytrNElNcko2QmFFME9GVXZhOXZ3QUFBT2pVcFJBQUFBQUFBQUFBQUFBPScsXG4gICAgICAgIH07XG5cbiAgICAgICAgbm9jayh1cmkpLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvYnVpbGRgKS5yZXBseSgyMDAsIGJ1aWxkUmVzdWx0KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24odHhQYXJhbXMpO1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgZGlzYWJsZU5ldHdvcmtpbmc6IHRydWUsXG4gICAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgICB1c2VyOiB7IHB1YjogdXNlcktleWNoYWluLnB1YiB9LFxuICAgICAgICAgICAgYmFja3VwOiB7IHB1YjogYmFja3VwS2V5Y2hhaW4ucHViIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHJhbnNhY3Rpb24gcHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQgdHJ1c3RsaW5lIG9wZXJhdGlvbnMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgdHJ1c3RsaW5lIHRyYW5zYWN0aW9uIHdpdGggdW5tYXRjaGluZyB0cnVzdGxpbmVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgICB0eXBlOiAndHJ1c3RsaW5lJyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXSxcbiAgICAgICAgICB0cnVzdGxpbmVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHRva2VuOiAndHhsbTpCU1QtR0JRVElPUzNYR0hCN0xWWUdCS1FWSkdDWjNSNEpMNUU0Q0JTV0o1QUxJSlVIQktTNjI2MzY0NEwnLFxuICAgICAgICAgICAgICBhY3Rpb246ICdyZW1vdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGJ1aWxkUmVzdWx0ID0ge1xuICAgICAgICAgIHR4QmFzZTY0OlxuICAgICAgICAgICAgJ0FBQUFBTnNLckhWMkJWakFDRnQyeGx5aHhZelAyTU5CbWI0SVE1RTkvV2lKaVYzVEFBQUJMQUFNNGFFQUFBQUhBQUFBQUFBQUFBQUFBQUFCQUFBQUFBQUFBQVlBQUFBQlFsTlVBQUFBQUFCaE5EcGJ1WTRmcnJnd1ZRcWt3czdqeEsrazRJTXJKNkJhRTBPRlV2YTl2d0FBQU9qVXBSQUFBQUFBQUFBQUFBQT0nLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2sodXJpKS5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYCkucmVwbHkoMjAwLCBidWlsZFJlc3VsdCk7XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IGF3YWl0IHdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHR4UGFyYW1zKTtcbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGRpc2FibGVOZXR3b3JraW5nOiB0cnVlLFxuICAgICAgICAgIGtleWNoYWluczoge1xuICAgICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICAgIGJhY2t1cDogeyBwdWI6IGJhY2t1cEtleWNoYWluLnB1YiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RyYW5zYWN0aW9uIHByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGV4cGVjdGVkIHRydXN0bGluZSB0b2tlbnMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgdHJ1c3RsaW5lIHRyYW5zYWN0aW9uIHdpdGggdW5tYXRjaGluZyBsaW1pdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgdHlwZTogJ3RydXN0bGluZScsXG4gICAgICAgICAgcmVjaXBpZW50czogW10sXG4gICAgICAgICAgdHJ1c3RsaW5lczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0b2tlbjogJ3R4bG06QlNULUdCUVRJT1MzWEdIQjdMVllHQktRVkpHQ1ozUjRKTDVFNENCU1dKNUFMSUpVSEJLUzYyNjM2NDRMJyxcbiAgICAgICAgICAgICAgYWN0aW9uOiAnYWRkJyxcbiAgICAgICAgICAgICAgbGltaXQ6ICc5OTknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGJ1aWxkUmVzdWx0ID0ge1xuICAgICAgICAgIHR4QmFzZTY0OlxuICAgICAgICAgICAgJ0FBQUFBTnNLckhWMkJWakFDRnQyeGx5aHhZelAyTU5CbWI0SVE1RTkvV2lKaVYzVEFBQUJMQUFNNGFFQUFBQUhBQUFBQUFBQUFBQUFBQUFCQUFBQUFBQUFBQVlBQUFBQlFsTlVBQUFBQUFCaE5EcGJ1WTRmcnJnd1ZRcWt3czdqeEsrazRJTXJKNkJhRTBPRlV2YTl2d0FBQU9qVXBSQUFBQUFBQUFBQUFBQT0nLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2sodXJpKS5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L2J1aWxkYCkucmVwbHkoMjAwLCBidWlsZFJlc3VsdCk7XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IGF3YWl0IHdhbGxldC5wcmVidWlsZFRyYW5zYWN0aW9uKHR4UGFyYW1zKTtcbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGRpc2FibGVOZXR3b3JraW5nOiB0cnVlLFxuICAgICAgICAgIGtleWNoYWluczoge1xuICAgICAgICAgICAgdXNlcjogeyBwdWI6IHVzZXJLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICAgIGJhY2t1cDogeyBwdWI6IGJhY2t1cEtleWNoYWluLnB1YiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3RyYW5zYWN0aW9uIHByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIGV4cGVjdGVkIHRydXN0bGluZSB0b2tlbnMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHRydXN0bGluZSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgdHlwZTogJ3RydXN0bGluZScsXG4gICAgICAgICAgcmVjaXBpZW50czogW10sXG4gICAgICAgICAgdHJ1c3RsaW5lczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0b2tlbjogJ3R4bG06QlNULUdCUVRJT1MzWEdIQjdMVllHQktRVkpHQ1ozUjRKTDVFNENCU1dKNUFMSUpVSEJLUzYyNjM2NDRMJyxcbiAgICAgICAgICAgICAgYWN0aW9uOiAnYWRkJyxcbiAgICAgICAgICAgICAgbGltaXQ6ICcxMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHRva2VuOiAndHhsbTpUU1QtR0JRVElPUzNYR0hCN0xWWUdCS1FWSkdDWjNSNEpMNUU0Q0JTV0o1QUxJSlVIQktTNjI2MzY0NEwnLFxuICAgICAgICAgICAgICBhY3Rpb246ICdyZW1vdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGJ1aWxkUmVzdWx0ID0ge1xuICAgICAgICAgIHR4QmFzZTY0OlxuICAgICAgICAgICAgJ0FBQUFBTnNLckhWMkJWakFDRnQyeGx5aHhZelAyTU5CbWI0SVE1RTkvV2lKaVYzVEFBQUF5QUFNNGFFQUFBQUpBQUFBQUFBQUFBQUFBQUFDQUFBQUFBQUFBQVlBQUFBQlFsTlVBQUFBQUFCaE5EcGJ1WTRmcnJnd1ZRcWt3czdqeEsrazRJTXJKNkJhRTBPRlV2YTl2d0FBQU9qVXBSQUFBQUFBQUFBQUFBWUFBQUFCVkZOVUFBQUFBQUJoTkRwYnVZNGZycmd3VlFxa3dzN2p4SytrNElNcko2QmFFME9GVXZhOXZ3QUFBQUFBQUFBQUFBQUFBQUFBQUFBPScsXG4gICAgICAgIH07XG5cbiAgICAgICAgbm9jayh1cmkpLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvYnVpbGRgKS5yZXBseSgyMDAsIGJ1aWxkUmVzdWx0KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24odHhQYXJhbXMpO1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgZGlzYWJsZU5ldHdvcmtpbmc6IHRydWUsXG4gICAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgICB1c2VyOiB7IHB1YjogdXNlcktleWNoYWluLnB1YiB9LFxuICAgICAgICAgICAgYmFja3VwOiB7IHB1YjogYmFja3VwS2V5Y2hhaW4ucHViIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdmFsaWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgICB2YWxpZFRyYW5zYWN0aW9uLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2VuYWJsZXRva2VuIHRyYW5zYWN0aW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgZmFpbCB0byB2ZXJpZnkgYSBlbmJsZXRva2VuIHRyYW5zYWN0aW9uIHdpdGggdW5tYXRjaGluZyBudW1iZXIgb2YgdG9rZW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHJlY2lwaWVudHM6IFtdLFxuICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYnVpbGRSZXN1bHQgPSB7XG4gICAgICAgICAgdHhCYXNlNjQ6XG4gICAgICAgICAgICAnQUFBQUFOc0tySFYyQlZqQUNGdDJ4bHloeFl6UDJNTkJtYjRJUTVFOS9XaUppVjNUQUFBQkxBQU00YUVBQUFBSEFBQUFBQUFBQUFBQUFBQUJBQUFBQUFBQUFBWUFBQUFCUWxOVUFBQUFBQUJoTkRwYnVZNGZycmd3VlFxa3dzN2p4SytrNElNcko2QmFFME9GVXZhOXZ3QUFBT2pVcFJBQUFBQUFBQUFBQUFBPScsXG4gICAgICAgIH07XG5cbiAgICAgICAgbm9jayh1cmkpLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvYnVpbGRgKS5yZXBseSgyMDAsIGJ1aWxkUmVzdWx0KTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0gYXdhaXQgd2FsbGV0LnByZWJ1aWxkVHJhbnNhY3Rpb24odHhQYXJhbXMpO1xuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgZGlzYWJsZU5ldHdvcmtpbmc6IHRydWUsXG4gICAgICAgICAga2V5Y2hhaW5zOiB7XG4gICAgICAgICAgICB1c2VyOiB7IHB1YjogdXNlcktleWNoYWluLnB1YiB9LFxuICAgICAgICAgICAgYmFja3VwOiB7IHB1YjogYmFja3VwS2V5Y2hhaW4ucHViIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHJhbnNhY3Rpb24gcHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQgdHJ1c3RsaW5lIG9wZXJhdGlvbnMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgZW5ibGV0b2tlbiB0cmFuc2FjdGlvbiB3aXRoIHVubWF0Y2hpbmcgdG9rZW4nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0b2tlbjogJ3R4bG06QlNULUdCUVRJT1MzWEdIQjdMVllHQktRVkpHQ1ozUjRKTDVFNENCU1dKNUFMSUpVSEJLUzYyNjM2NDRMJyxcbiAgICAgICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBidWlsZFJlc3VsdCA9IHtcbiAgICAgICAgICB0eEJhc2U2NDpcbiAgICAgICAgICAgICdBQUFBQU5zS3JIVjJCVmpBQ0Z0MnhseWh4WXpQMk1OQm1iNElRNUU5L1dpSmlWM1RBQUFCTEFBTTRhRUFBQUFIQUFBQUFBQUFBQUFBQUFBQkFBQUFBQUFBQUFZQUFBQUJRbE5VQUFBQUFBQmhORHBidVk0ZnJyZ3dWUXFrd3M3anhLK2s0SU1ySjZCYUUwT0ZVdmE5dndBQUFPalVwUkFBQUFBQUFBQUFBQUE9JyxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKHVyaSkucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9idWlsZGApLnJlcGx5KDIwMCwgYnVpbGRSZXN1bHQpO1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSBhd2FpdCB3YWxsZXQucHJlYnVpbGRUcmFuc2FjdGlvbih0eFBhcmFtcyk7XG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHtcbiAgICAgICAgICBkaXNhYmxlTmV0d29ya2luZzogdHJ1ZSxcbiAgICAgICAgICBrZXljaGFpbnM6IHtcbiAgICAgICAgICAgIHVzZXI6IHsgcHViOiB1c2VyS2V5Y2hhaW4ucHViIH0sXG4gICAgICAgICAgICBiYWNrdXA6IHsgcHViOiBiYWNrdXBLZXljaGFpbi5wdWIgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0cmFuc2FjdGlvbiBwcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBleHBlY3RlZCB0cnVzdGxpbmUgdG9rZW5zJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0ZlZGVyYXRpb24gbG9va3VwczonLCBmdW5jdGlvbiAoKSB7XG4gICAgZGVzY3JpYmUoJ0xvb2sgdXAgYnkgc3RlbGxhciBhZGRyZXNzOicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgZmFpbCB0byBsb29wIHVwIGFuIGludmFsaWQgc3RlbGxhciBhZGRyZXNzIHdpdGggYSBiaXRnby5jb20gZG9tYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzdGVsbGFyQWRkcmVzcyA9ICdpbnZhbGlkKmJpdGdvLmNvbSc7XG5cbiAgICAgICAgbm9jayh1cmkpXG4gICAgICAgICAgLmdldCgnLy53ZWxsLWtub3duL3N0ZWxsYXIudG9tbCcpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgJ0ZFREVSQVRJT05fU0VSVkVSPVwiaHR0cHM6Ly90ZXN0LmJpdGdvLmNvbS9hcGkvdjIvdHhsbS9mZWRlcmF0aW9uXCInKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdHhsbS9mZWRlcmF0aW9uJylcbiAgICAgICAgICAucXVlcnkoe1xuICAgICAgICAgICAgcTogc3RlbGxhckFkZHJlc3MsXG4gICAgICAgICAgICB0eXBlOiAnbmFtZScsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoNDA0LCB7XG4gICAgICAgICAgICBkZXRhaWw6IGB1c2VyIG5vdCBmb3VuZDogJHtzdGVsbGFyQWRkcmVzc31gLFxuICAgICAgICAgICAgbmFtZTogJ1VzZXJOb3RGb3VuZCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAuZmVkZXJhdGlvbkxvb2t1cEJ5TmFtZShzdGVsbGFyQWRkcmVzcylcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChgdXNlciBub3QgZm91bmQ6ICR7c3RlbGxhckFkZHJlc3N9YCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXNvbHZlIGEgc3RlbGxhciBhZGRyZXNzIGludG8gYW4gYWNjb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc3RlbGxhckFkZHJlc3MgPSAndGVzdGVyKmJpdGdvLmNvbSc7XG4gICAgICAgIGNvbnN0IGFjY291bnRJZCA9ICdHQ0JZWTNTNjJRWTQzUE1FS0dKSFJDQkhFRkpPSENMR1NNV1hSRVVaWURRSEpIUTJMSzRJNDJKQSc7XG5cbiAgICAgICAgbm9jayh1cmkpXG4gICAgICAgICAgLmdldCgnLy53ZWxsLWtub3duL3N0ZWxsYXIudG9tbCcpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgJ0ZFREVSQVRJT05fU0VSVkVSPVwiaHR0cHM6Ly90ZXN0LmJpdGdvLmNvbS9hcGkvdjIvdHhsbS9mZWRlcmF0aW9uXCInKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdHhsbS9mZWRlcmF0aW9uJylcbiAgICAgICAgICAucXVlcnkoe1xuICAgICAgICAgICAgcTogc3RlbGxhckFkZHJlc3MsXG4gICAgICAgICAgICB0eXBlOiAnbmFtZScsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBzdGVsbGFyX2FkZHJlc3M6IHN0ZWxsYXJBZGRyZXNzLFxuICAgICAgICAgICAgYWNjb3VudF9pZDogYWNjb3VudElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLmZlZGVyYXRpb25Mb29rdXBCeU5hbWUoc3RlbGxhckFkZHJlc3MpO1xuICAgICAgICByZXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0ZWxsYXJfYWRkcmVzcycpO1xuICAgICAgICByZXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FjY291bnRfaWQnKTtcbiAgICAgICAgcmVzLnN0ZWxsYXJfYWRkcmVzcy5zaG91bGQuZXF1YWwoc3RlbGxhckFkZHJlc3MpO1xuICAgICAgICByZXMuYWNjb3VudF9pZC5zaG91bGQuZXF1YWwoYWNjb3VudElkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0xvb2sgdXAgYnkgYWNjb3VudCBpZDonLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIGZhaWwgdG8gbG9vayB1cCBhbiBhY2NvdW50IGlmIHRoZSBhY2NvdW50IGlkIGlzIGludmFsaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGFjY291bnRJZCA9ICcxMjMnO1xuXG4gICAgICAgIG5vY2sodXJpKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdHhsbS9mZWRlcmF0aW9uJylcbiAgICAgICAgICAucXVlcnkoe1xuICAgICAgICAgICAgcTogYWNjb3VudElkLFxuICAgICAgICAgICAgdHlwZTogJ2lkJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSg0MDAsIHtcbiAgICAgICAgICAgIGRldGFpbDogJ2ludmFsaWQgaWQ6ICcgKyBhY2NvdW50SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uZmVkZXJhdGlvbkxvb2t1cEJ5QWNjb3VudElkKGFjY291bnRJZCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChgaW52YWxpZCBpZDogJHthY2NvdW50SWR9YCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gb25seSBhY2NvdW50X2lkIGZvciBub24tYml0Z28gYWNjb3VudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGFjY291bnRJZCA9ICdHQ1JPWEhZSlNUQ1MzQ1FRSVU3R0ZDN1lRSVJJVkdQWVpRUlpFTTZQTjdQN1RBWjNQVTRDSEpSRyc7XG5cbiAgICAgICAgbm9jayh1cmkpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi90eGxtL2ZlZGVyYXRpb24nKVxuICAgICAgICAgIC5xdWVyeSh7XG4gICAgICAgICAgICBxOiBhY2NvdW50SWQsXG4gICAgICAgICAgICB0eXBlOiAnaWQnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjb3VudF9pZDogYWNjb3VudElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLmZlZGVyYXRpb25Mb29rdXBCeUFjY291bnRJZChhY2NvdW50SWQpO1xuICAgICAgICByZXMuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdzdGVsbGFyX2FkZHJlc3MnKTtcbiAgICAgICAgcmVzLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbWVtb190eXBlJyk7XG4gICAgICAgIHJlcy5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ21lbW8nKTtcbiAgICAgICAgcmVzLnNob3VsZC5oYXZlLnByb3BlcnR5KCdhY2NvdW50X2lkJyk7XG4gICAgICAgIHJlcy5hY2NvdW50X2lkLnNob3VsZC5lcXVhbChhY2NvdW50SWQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVzb2x2ZSBhIHZhbGlkIGFjY291bnQgaWQgaW50byBhbiBhY2NvdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBhY2NvdW50SWQgPSAnR0RESENLTVlZWUNWWE9TQVZNU0VJWUdZTlg3NExJQVYzQUNYWVE2V1BNRFVGN1czS1pOV1RIVEgnO1xuXG4gICAgICAgIG5vY2sodXJpKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdHhsbS9mZWRlcmF0aW9uJylcbiAgICAgICAgICAucXVlcnkoe1xuICAgICAgICAgICAgcTogYWNjb3VudElkLFxuICAgICAgICAgICAgdHlwZTogJ2lkJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHN0ZWxsYXJfYWRkcmVzczogJ3Rlc3RlcipiaXRnby5jb20nLFxuICAgICAgICAgICAgYWNjb3VudF9pZDogYWNjb3VudElkLFxuICAgICAgICAgICAgbWVtb190eXBlOiAnaWQnLFxuICAgICAgICAgICAgbWVtbzogJzAnLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLmZlZGVyYXRpb25Mb29rdXBCeUFjY291bnRJZChhY2NvdW50SWQpO1xuICAgICAgICByZXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0ZWxsYXJfYWRkcmVzcycpO1xuICAgICAgICByZXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FjY291bnRfaWQnKTtcbiAgICAgICAgcmVzLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtZW1vX3R5cGUnKTtcbiAgICAgICAgcmVzLnNob3VsZC5oYXZlLnByb3BlcnR5KCdtZW1vJyk7XG4gICAgICAgIHJlcy5hY2NvdW50X2lkLnNob3VsZC5lcXVhbChhY2NvdW50SWQpO1xuICAgICAgICByZXMuc3RlbGxhcl9hZGRyZXNzLnNob3VsZC5lcXVhbCgndGVzdGVyKmJpdGdvLmNvbScpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdLZXlwYWlyczonLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhIGtleXBhaXIgZnJvbSByYW5kb20gc2VlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoKTtcbiAgICAgIGtleVBhaXIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3B1YicpO1xuICAgICAga2V5UGFpci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJ2Jyk7XG5cbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBrZXlQYWlyLnB1YjtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5lcXVhbCh0cnVlKTtcblxuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrZXlQYWlyLnB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFBydihrZXlQYWlyLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhIGtleXBhaXIgZnJvbSBzZWVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VlZCA9IHJhbmRvbUJ5dGVzKDMyKTtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoc2VlZCk7XG4gICAgICBrZXlQYWlyLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwdWInKTtcbiAgICAgIGtleVBhaXIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BydicpO1xuXG4gICAgICBjb25zdCBhZGRyZXNzID0ga2V5UGFpci5wdWI7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG5cbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa2V5UGFpci5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa2V5UGFpci5wcnYpLnNob3VsZC5lcXVhbCh0cnVlKTtcblxuICAgICAgY29uc3Qgc2VjcmV0ID0ga2V5UGFpci5wcnY7XG4gICAgICBzdGVsbGFyLlN0cktleS5lbmNvZGVFZDI1NTE5U2VjcmV0U2VlZChzZWVkKS5zaG91bGQuZXF1YWwoc2VjcmV0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgcHViIGtleScsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgcHViIH0gPSBiYXNlY29pbi5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIocHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQgUm9vdCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYSByb290IGtleXBhaXIgZnJvbSByYW5kb20gc2VlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcigpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcblxuICAgICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiBrcC5wcnYgfSkuZ2V0S2V5cyh0cnVlKTtcbiAgICAgIGtleVBhaXIuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3B1YicpO1xuICAgICAga2V5UGFpci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJ2Jyk7XG4gICAgICBrZXlQYWlyLnBydj8uc2hvdWxkLmVxdWFsKGtwLnBydi5zbGljZSgwLCA2NCkpO1xuICAgICAga2V5UGFpci5wdWIuc2hvdWxkLmVxdWFsKGtwLnB1Yik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGEgcm9vdCBrZXlwYWlyIGZyb20gc2VlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlZWQgPSBCdWZmZXIuZnJvbSgnNzYxZGU1NzBjNDYwNzkyZjEwMzc4YThiM2M3Y2MyMjgzMjQxZGIzN2Q4ZGFjMTNkYmRkODA5NWEwNWVhMDBiMicsICdoZXgnKTtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcihzZWVkKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBrcC5wdWIuc2hvdWxkLmVxdWFsKCc3ZmU0MjU0YmFhZWViZmVmZDVhNjMyZmRiNzFhYTllYzYzYWE2MTFiY2QzOTJiMDdhNzU5YTRiMjEzMDdiN2ZjJyk7XG4gICAgICBrcC5wcnYuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNzYxZGU1NzBjNDYwNzkyZjEwMzc4YThiM2M3Y2MyMjgzMjQxZGIzN2Q4ZGFjMTNkYmRkODA5NWEwNWVhMDBiMjdmZTQyNTRiYWFlZWJmZWZkNWE2MzJmZGI3MWFhOWVjNjNhYTYxMWJjZDM5MmIwN2E3NTlhNGIyMTMwN2I3ZmMnXG4gICAgICApO1xuXG4gICAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwcnY6IGtwLnBydiB9KS5nZXRLZXlzKHRydWUpO1xuICAgICAga2V5UGFpci5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJ2Jyk7XG4gICAgICBrZXlQYWlyLnBydj8uc2hvdWxkLmVxdWFsKGtwLnBydi5zbGljZSgwLCA2NCkpO1xuICAgICAga2V5UGFpci5wdWIuc2hvdWxkLmVxdWFsKGtwLnB1Yik7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=

Выполнить команду


Для локальной разработки. Не используйте в интернете!