PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/dist/test/bitgo/psbt
Просмотр файла: Musig2.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const bitgo_1 = require("../../../src/bitgo");
const testutil_1 = require("../../../src/testutil");
const Musig2_1 = require("../../../src/bitgo/Musig2");
const outputScripts_1 = require("../../../src/bitgo/outputScripts");
const Musig2Util_1 = require("./Musig2Util");
const p2trMusig2Unspent = (0, Musig2Util_1.getUnspents)(['p2trMusig2'], Musig2Util_1.rootWalletKeys);
const outputType = 'p2trMusig2';
const CHANGE_INDEX = 100;
describe('p2trMusig2', function () {
describe('p2trMusig2 key path', function () {
it(`create psbt, nonces, sign (internal verify) - success`, function () {
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex((0, bitgo_1.getExternalChainCode)('p2trMusig2'), 0);
const unspents = (0, Musig2Util_1.getUnspents)(outputScripts_1.scriptTypes2Of3.map((t) => t), Musig2Util_1.rootWalletKeys);
// WP creates PSBT during build API, serializes it, and sends the psbt to user
const buildPsbt = (0, Musig2Util_1.constructPsbt)(unspents, Musig2Util_1.rootWalletKeys, 'bitgo', 'user', outputType);
const buildPsbtSer = buildPsbt.toHex();
// User de-serialises the psbt, ands the user nonce, and sends it to the hsm so that it can add the bitgo nonce
const userPsbt = (0, bitgo_1.createPsbtFromHex)(buildPsbtSer, Musig2Util_1.network);
userPsbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
const userPsbtSer = userPsbt.toHex();
// HSM deserializes the user psbt, adds the deterministic bitgo nonce, and sends that back to the user
const bitgoPsbt = (0, bitgo_1.createPsbtFromHex)(userPsbtSer, Musig2Util_1.network);
bitgoPsbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true });
const bitgoPsbtSer = bitgoPsbt.toHex();
// User combines the psbt with the bitgo nonce, adds user signature, and sends half-signed to hsm
const bitgoPsbtDeser = (0, bitgo_1.createPsbtFromHex)(bitgoPsbtSer, Musig2Util_1.network);
userPsbt.combine(bitgoPsbtDeser);
userPsbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
const userPsbtHalfSignedHex = userPsbt.toHex();
// WP de-serialises the psbt and validates user sig
const userPsbtDes = (0, bitgo_1.createPsbtFromHex)(userPsbtHalfSignedHex, Musig2Util_1.network);
assert.ok(userPsbtDes.validateTaprootMusig2SignaturesOfInput(4, walletKeys.user.publicKey));
// WP sends to hsm for signature and returns a fully signed psbt
const psbt = (0, bitgo_1.createPsbtFromHex)(userPsbtHalfSignedHex, Musig2Util_1.network);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true });
unspents.forEach((unspent, index) => {
if ((0, bitgo_1.scriptTypeForChain)(unspent.chain) !== 'p2trMusig2') {
assert.strictEqual(psbt.getProprietaryKeyVals(index).length, 0);
return;
}
(0, Musig2Util_1.validatePsbtP2trMusig2Input)(psbt, index, unspent, 'keyPath');
(0, Musig2Util_1.validatePsbtP2trMusig2Output)(psbt, 0);
(0, Musig2Util_1.validateParticipantsKeyVals)(psbt, index, unspent);
(0, Musig2Util_1.validateNoncesKeyVals)(psbt, index, unspent);
(0, Musig2Util_1.validatePartialSigKeyVals)(psbt, index, unspent);
});
assert.ok(psbt.validateSignaturesOfAllInputs());
psbt.finalizeAllInputs();
unspents.forEach((unspent, index) => {
(0, Musig2Util_1.validateFinalizedInput)(psbt, index, unspent);
});
const tx = psbt.extractTransaction();
assert.ok((0, testutil_1.verifyFullySignedSignatures)(tx, unspents, Musig2Util_1.rootWalletKeys, 'bitgo', 'user'));
unspents.map((unspent, inputIndex) => {
assert.deepStrictEqual((0, bitgo_1.verifySignatureWithUnspent)(tx, inputIndex, unspents, Musig2Util_1.rootWalletKeys), [
true,
false,
true,
]);
});
});
it(`parse tx`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'bitgo', 'user', outputType);
(0, Musig2Util_1.validateParsedTaprootKeyPathPsbt)(psbt, 0, 'unsigned');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
(0, Musig2Util_1.validateParsedTaprootKeyPathPsbt)(psbt, 0, 'halfsigned');
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
(0, Musig2Util_1.validateParsedTaprootKeyPathPsbt)(psbt, 0, 'fullysigned');
psbt.finalizeAllInputs();
assert.throws(() => (0, bitgo_1.parsePsbtInput)(psbt.data.inputs[0]), (e) => e.message === 'Finalized PSBT parsing is not supported');
const tx = psbt.extractTransaction();
(0, Musig2Util_1.validateParsedTaprootKeyPathTxInput)(psbt, tx);
});
describe('create nonce', function () {
it(`update with new nonce should be allowed`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
let noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 1);
const userNonceKey = noncesKeyVals[0].key.keydata;
const userNonceValue = noncesKeyVals[0].value;
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 2);
noncesKeyVals = noncesKeyVals.filter((kv) => kv.key.keydata.equals(userNonceKey));
assert.strictEqual(noncesKeyVals.length, 1);
assert.ok(!noncesKeyVals[0].value.equals(userNonceValue));
});
it(`Cosigner nonce creation fail should not enforce the signer to recreate nonce`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
const tapBip32Derivation = psbt.data.inputs[0].tapBip32Derivation;
psbt.data.inputs[0].tapBip32Derivation = undefined;
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo), (e) => e.message === 'tapBip32Derivation is required to create nonce');
psbt.data.inputs[0].tapBip32Derivation = tapBip32Derivation;
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
const noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 2);
const partialSigKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PARTIAL_SIG,
});
assert.strictEqual(partialSigKeyVals.length, 2);
const participantKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PARTICIPANT_PUB_KEYS,
});
assert.strictEqual(participantKeyVals.length, 1);
});
it('Cosigner can create a deterministic nonce', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true });
const noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 2);
});
it('Cosigner cannot create a deterministic nonce if there is no signer nonce', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true }), (e) => e.message === 'No nonces found on input #0');
let noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 0);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true }), (e) => e.message === 'signer nonce must be set if cosigner nonce is to be derived deterministically');
noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 1);
});
it('Cosigner cannot add entropy to deterministic nonce creation', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, {
deterministic: true,
sessionId: Buffer.allocUnsafe(32),
}), (e) => e.message === 'Cannot add extra entropy when generating a deterministic nonce');
const noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 1);
});
it('Signer cannot create a deterministic nonce', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user, { deterministic: true }), (e) => e.message === `Only the cosigner's nonce can be set deterministically`);
const noncesKeyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
assert.strictEqual(noncesKeyVals.length, 0);
});
it(`skipped if tapInternalKey doesn't match participant pub keys agg`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.data.inputs[0].tapInternalKey = Musig2Util_1.dummyTapInternalKey;
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'tapInternalKey and aggregated participant pub keys does not match');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if sessionId size is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user, { sessionId: Buffer.allocUnsafe(33) }), (e) => e.message === 'Invalid sessionId size 33');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if private key is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user.neutered()), (e) => e.message === 'private key is required to generate nonce');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if tapBip32Derivation is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.data.inputs[0].tapBip32Derivation = [];
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'tapBip32Derivation is required to create nonce');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if participant pub keys is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.data.inputs[0].unknownKeyVals = [];
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'Found 0 matching participant key value instead of 1');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 0);
});
it(`fails if participant pub keys keydata size is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
keyVals[0].key.keydata = Buffer.concat([keyVals[0].key.keydata, Buffer.from('dummy')]);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid keydata size ${keyVals[0].key.keydata.length} for participant pub keys`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if participant keydata tapOutputKey in invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
keyVals[0].key.keydata = Buffer.concat([Musig2Util_1.dummyTapOutputKey, keyVals[0].key.keydata.subarray(32)]);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid participants keydata tapOutputKey`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if participant keydata tapInternalKey in invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
keyVals[0].key.keydata = Buffer.concat([keyVals[0].key.keydata.subarray(0, 32), Musig2Util_1.dummyTapInternalKey]);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid participants keydata tapInternalKey`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if tapInternalKey and aggregated participant pub keys don't match`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex((0, bitgo_1.getInternalChainCode)('p2trMusig2'), 1);
const tapInternalKey = (0, Musig2_1.createTapInternalKey)([walletKeys.user.publicKey, walletKeys.bitgo.publicKey]);
const tapOutputKey = (0, Musig2_1.createTapOutputKey)(tapInternalKey, psbt.data.inputs[0].tapMerkleRoot);
keyVals[0].key.keydata = Buffer.concat([tapOutputKey, tapInternalKey]);
keyVals[0].value = Buffer.concat([walletKeys.user.publicKey, walletKeys.bitgo.publicKey]);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `tapInternalKey and aggregated participant pub keys does not match`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if keydata size of participant pub keys is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
keyVals[0].key.keydata = Buffer.allocUnsafe(65);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid keydata size 65 for participant pub keys`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if valuedata size of participant pub keys is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
keyVals[0].value = Buffer.allocUnsafe(67);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid valuedata size 67 for participant pub keys`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if duplicate participant pub keys found`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
keyVals[0].value = Buffer.concat([keyVals[0].value.subarray(33), keyVals[0].value.subarray(33)]);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Duplicate participant pub keys found`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if no fingerprint match`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.data.inputs[0].tapBip32Derivation?.forEach((bv) => (bv.masterFingerprint = Buffer.allocUnsafe(4)));
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'No bip32Derivation masterFingerprint matched the HD keyPair fingerprint');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if pubkey did not match tapBip32Derivation`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex((0, bitgo_1.getInternalChainCode)('p2trMusig2'), CHANGE_INDEX);
psbt.data.inputs[0].tapBip32Derivation?.forEach((bv) => {
bv.path = walletKeys.paths[2];
});
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'pubkey did not match bip32Derivation');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if root wallet key derive more than one tapBip32Derivation`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex(p2trMusig2Unspent[0].chain, p2trMusig2Unspent[0].index);
psbt.data.inputs[0].tapBip32Derivation?.forEach((bv, index) => {
bv.path = walletKeys.paths[0];
bv.pubkey = (0, outputScripts_1.toXOnlyPublicKey)(walletKeys.publicKeys[0]);
bv.masterFingerprint = Musig2Util_1.rootWalletKeys.user.fingerprint;
});
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message.startsWith('more than one matching derivation for fingerprint'));
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
it(`fails if derived wallet key does not match any participant key`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const keyVals = psbt.getProprietaryKeyVals(0);
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex((0, bitgo_1.getInternalChainCode)('p2trMusig2'), 1);
const tapInternalKey = (0, Musig2_1.createTapInternalKey)([walletKeys.user.publicKey, walletKeys.bitgo.publicKey]);
psbt.data.inputs[0].tapInternalKey = tapInternalKey;
keyVals[0].value = Buffer.concat([walletKeys.user.publicKey, walletKeys.bitgo.publicKey]);
const tapOutputKey = (0, Musig2_1.createTapOutputKey)(tapInternalKey, psbt.data.inputs[0].tapMerkleRoot);
keyVals[0].key.keydata = Buffer.concat([tapOutputKey, tapInternalKey]);
psbt.data.inputs[0].unknownKeyVals = [];
psbt.addProprietaryKeyValToInput(0, keyVals[0]);
assert.throws(() => psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user), (e) => e.message === `participant plain pub key should match one bip32Derivation plain pub key`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 1);
});
});
describe('sign', function () {
it(`fails if privateKey is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user.neutered()), (e) => e.message === 'privateKey is required to sign p2tr musig2');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it(`fails if tapInternalKey is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex(p2trMusig2Unspent[0].chain, p2trMusig2Unspent[0].index);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.data.inputs[0].tapInternalKey = undefined;
assert.throws(() => psbt.signTaprootMusig2Input(0, {
publicKey: walletKeys.user.publicKey,
privateKey: walletKeys.user.privateKey,
}), (e) => e.message === 'not a taproot musig2 input');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it('only the cosigner can add a deterministic signature', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true });
assert.throws(() => psbt.signInputHD(0, Musig2Util_1.rootWalletKeys.user, { deterministic: true }), (e) => e.message === 'can only add a deterministic signature on the cosigner');
});
it('cosigner can sign deterministically', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true });
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: true });
assert.ok(psbt.validateSignaturesOfAllInputs());
assert.ok(psbt.finalizeAllInputs());
});
it('cosigner can sign non-deterministically', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: false });
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo, { deterministic: false });
assert.ok(psbt.validateSignaturesOfAllInputs());
assert.ok(psbt.finalizeAllInputs());
});
});
it(`fails if tapMerkleRoot is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex(p2trMusig2Unspent[0].chain, p2trMusig2Unspent[0].index);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.data.inputs[0].tapMerkleRoot = undefined;
assert.throws(() => psbt.signTaprootMusig2Input(0, {
publicKey: walletKeys.user.publicKey,
privateKey: walletKeys.user.privateKey,
}), (e) => e.message === 'not a taproot musig2 input');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it(`fails if participant pub keys is missing`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.data.inputs[0].unknownKeyVals = [];
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'Found 0 matching participant key value instead of 1');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 0);
});
it(`fails if signer pub key is not matching any participant pub keys`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
assert.throws(() => psbt.signTaprootMusig2Input(0, {
privateKey: Musig2Util_1.rootWalletKeys.backup.privateKey,
publicKey: Musig2Util_1.rootWalletKeys.backup.publicKey,
}), (e) => e.message === 'signer pub key should match one of participant pub keys');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it(`fails if more than 2 nonce key value exists`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.data.inputs[0].unknownKeyVals?.push(psbt.data.inputs[0].unknownKeyVals[2]);
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'Found 3 matching nonce key value instead of 1 or 2');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 4);
});
it(`fails if 2 nonce key value do not exist`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.data.inputs[0].unknownKeyVals?.splice(2);
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === 'Found 1 matching nonce key value instead of 2');
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 2);
});
it(`fails if nonce keydata size is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
const keyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
keyVals[1].key.keydata = Buffer.concat([keyVals[1].key.keydata, Buffer.from('dummy')]);
psbt.data.inputs[0].unknownKeyVals?.splice(2);
psbt.addProprietaryKeyValToInput(0, keyVals[1]);
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid keydata size ${keyVals[1].key.keydata.length} for nonce`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it(`fails if nonce valuedata size is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
const keyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
keyVals[1].value = Buffer.concat([keyVals[1].value, Buffer.from('dummy')]);
psbt.data.inputs[0].unknownKeyVals?.splice(2);
psbt.addProprietaryKeyValToInput(0, keyVals[1]);
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid valuedata size ${keyVals[1].value.length} for nonce`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it(`fails if nonce keydata is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
const dummyRootWalletKeys = new bitgo_1.RootWalletKeys((0, testutil_1.getKeyTriple)('dummy'));
const dummyP2trMusig2Unspent = (0, Musig2Util_1.getUnspents)(['p2trMusig2'], dummyRootWalletKeys);
const dummyPsbt = (0, Musig2Util_1.constructPsbt)(dummyP2trMusig2Unspent, dummyRootWalletKeys, 'user', 'bitgo', 'p2sh');
dummyPsbt.setAllInputsMusig2NonceHD(dummyRootWalletKeys.user);
dummyPsbt.setAllInputsMusig2NonceHD(dummyRootWalletKeys.bitgo);
const dummyKeyVals = dummyPsbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
psbt.data.inputs[0].unknownKeyVals?.splice(1);
dummyKeyVals.forEach((kv, i) => psbt.addProprietaryKeyValToInput(0, dummyKeyVals[i]));
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid nonce keydata participant pub key`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
it(`fails if nonce keydata tapOutputKey is invalid`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', 'p2sh');
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
const keyVals = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
keyVals[1].key.keydata = Buffer.concat([keyVals[1].key.keydata.subarray(0, 33), Musig2Util_1.dummyTapOutputKey]);
psbt.data.inputs[0].unknownKeyVals?.splice(2);
psbt.addProprietaryKeyValToInput(0, keyVals[1]);
assert.throws(() => psbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Invalid nonce keydata tapOutputKey`);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 3);
});
});
describe('p2trMusig2 script path', function () {
it(`psbt creation success and musig2 skips`, function () {
let psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'backup', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.backup);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 0);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.backup);
(0, Musig2Util_1.validatePsbtP2trMusig2Input)(psbt, 0, p2trMusig2Unspent[0], 'scriptPath');
(0, Musig2Util_1.validatePsbtP2trMusig2Output)(psbt, 0);
assert.ok(psbt.validateSignaturesOfAllInputs());
psbt.finalizeAllInputs();
(0, Musig2Util_1.validateFinalizedInput)(psbt, 0, p2trMusig2Unspent[0], 'scriptPath');
let tx = psbt.extractTransaction();
assert.ok((0, testutil_1.verifyFullySignedSignatures)(tx, p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'backup'));
psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'bitgo', 'backup', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.backup);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.backup);
assert.strictEqual(psbt.getProprietaryKeyVals(0).length, 0);
(0, Musig2Util_1.validatePsbtP2trMusig2Input)(psbt, 0, p2trMusig2Unspent[0], 'scriptPath');
(0, Musig2Util_1.validatePsbtP2trMusig2Output)(psbt, 0);
assert.ok(psbt.validateSignaturesOfAllInputs());
psbt.finalizeAllInputs();
(0, Musig2Util_1.validateFinalizedInput)(psbt, 0, p2trMusig2Unspent[0], 'scriptPath');
tx = psbt.extractTransaction();
assert.ok((0, testutil_1.verifyFullySignedSignatures)(tx, p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'bitgo', 'backup'));
});
it(`parse tx`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'backup', outputType);
(0, Musig2Util_1.validateParsedTaprootScriptPathPsbt)(psbt, 0, 'unsigned');
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
(0, Musig2Util_1.validateParsedTaprootScriptPathPsbt)(psbt, 0, 'halfsigned');
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.backup);
(0, Musig2Util_1.validateParsedTaprootScriptPathPsbt)(psbt, 0, 'fullysigned');
psbt.finalizeAllInputs();
const tx = psbt.extractTransaction();
const psbtDuplicate = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'backup', outputType);
(0, Musig2Util_1.validateParsedTaprootScriptPathTxInput)(psbtDuplicate, tx, 0);
});
});
describe('validate p2tr Musig2 signatures', function () {
it(`validate with pubkey`, function () {
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex(p2trMusig2Unspent[0].chain, p2trMusig2Unspent[0].index);
let psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2Nonce(walletKeys.user);
psbt.setAllInputsMusig2Nonce(walletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
assert.ok(psbt.validateTaprootMusig2SignaturesOfInput(0, walletKeys.user.publicKey));
psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setInputMusig2Nonce(0, walletKeys.user);
psbt.setInputMusig2NonceHD(0, Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
assert.ok(psbt.validateTaprootMusig2SignaturesOfInput(0, walletKeys.user.publicKey));
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
assert.ok(psbt.validateTaprootMusig2SignaturesOfInput(0, walletKeys.bitgo.publicKey));
});
it(`fails if no sig`, function () {
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex(p2trMusig2Unspent[0].chain, p2trMusig2Unspent[0].index);
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
assert.throws(() => psbt.validateSignaturesOfAllInputs(), (e) => e.message === `No signatures to validate`);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
assert.throws(() => psbt.validateTaprootMusig2SignaturesOfInput(0, walletKeys.bitgo.publicKey), (e) => e.message === `No signatures for this pubkey`);
});
it(`fails if no tapInternalKey and tapMerkleRoot`, function () {
const walletKeys = Musig2Util_1.rootWalletKeys.deriveForChainAndIndex(p2trMusig2Unspent[0].chain, p2trMusig2Unspent[0].index);
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
const tapInternalKey = psbt.data.inputs[0].tapInternalKey;
psbt.data.inputs[0].tapInternalKey = undefined;
assert.throws(() => psbt.validateTaprootMusig2SignaturesOfInput(0), (e) => e.message === `both tapInternalKey and tapMerkleRoot are required`);
psbt.data.inputs[0].tapInternalKey = tapInternalKey;
psbt.data.inputs[0].tapMerkleRoot = undefined;
assert.throws(() => psbt.validateTaprootMusig2SignaturesOfInput(0, walletKeys.bitgo.publicKey), (e) => e.message === `both tapInternalKey and tapMerkleRoot are required`);
});
it(`fails if no nonce and sig pub key match`, function () {
let psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
const partialSigs = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PARTIAL_SIG,
});
const myRootWalletKeys = new bitgo_1.RootWalletKeys((0, testutil_1.getKeyTriple)('dummy'));
const myUnspents = (0, Musig2Util_1.getUnspents)(['p2trMusig2'], myRootWalletKeys);
psbt = (0, Musig2Util_1.constructPsbt)(myUnspents, myRootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2NonceHD(myRootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(myRootWalletKeys.bitgo);
psbt.signAllInputsHD(myRootWalletKeys.user);
psbt.signAllInputsHD(myRootWalletKeys.bitgo);
const participants = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PARTICIPANT_PUB_KEYS,
});
const nonces = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PUB_NONCE,
});
psbt.data.inputs[0].unknownKeyVals = undefined;
psbt.addProprietaryKeyValToInput(0, participants[0]);
psbt.addProprietaryKeyValToInput(0, nonces[0]);
psbt.addProprietaryKeyValToInput(0, nonces[1]);
psbt.addProprietaryKeyValToInput(0, partialSigs[0]);
psbt.addProprietaryKeyValToInput(0, partialSigs[1]);
assert.throws(() => psbt.validateSignaturesOfAllInputs(), (e) => e.message === `Found no pub nonce for pubkey`);
});
it(`fails if no valid sig`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.bitgo);
const partialSigs = psbt.getProprietaryKeyVals(0, {
identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER,
subtype: bitgo_1.ProprietaryKeySubtype.MUSIG2_PARTIAL_SIG,
});
partialSigs[1].value = Musig2Util_1.dummyPartialSig;
psbt.addOrUpdateProprietaryKeyValToInput(0, partialSigs[1]);
assert.ok(!psbt.validateSignaturesOfAllInputs());
});
});
describe('finalizeTaprootMusig2Input', function () {
it('fails if invalid number for sigs', function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
psbt.signAllInputsHD(Musig2Util_1.rootWalletKeys.user);
assert.throws(() => psbt.finalizeAllInputs(), (e) => e.message === `invalid number of partial signatures 1 to finalize`);
});
});
describe('Psbt musig2 common functions', function () {
it('output script should match the scriptPubKey in the prevout', function () {
const myRootWalletKeys = new bitgo_1.RootWalletKeys((0, testutil_1.getKeyTriple)('dummy'));
const unspents = (0, Musig2Util_1.getUnspents)(outputScripts_1.scriptTypes2Of3.map((t) => t), myRootWalletKeys);
const psbt = (0, Musig2Util_1.constructPsbt)(unspents, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
unspents.forEach((u, index) => {
const scriptType = (0, bitgo_1.scriptTypeForChain)(u.chain);
assert.throws(() => scriptType === 'p2trMusig2'
? psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user)
: scriptType === 'p2tr'
? psbt.signTaprootInputHD(index, Musig2Util_1.rootWalletKeys.user)
: psbt.signInputHD(index, Musig2Util_1.rootWalletKeys.user), (e) => (0, bitgo_1.isSegwit)(u.chain) && scriptType !== 'p2shP2wsh'
? e.message === `Witness script for input #${index} doesn't match the scriptPubKey in the prevout`
: e.message === `Redeem script for input #${index} doesn't match the scriptPubKey in the prevout`);
});
const p2trMusig2ScriptPathPsbt = (0, Musig2Util_1.constructPsbt)([unspents[4]], Musig2Util_1.rootWalletKeys, 'user', 'backup', outputType);
assert.throws(() => p2trMusig2ScriptPathPsbt.signTaprootInputHD(0, Musig2Util_1.rootWalletKeys.user), (e) => e.message === `Witness script for input #0 doesn't match the scriptPubKey in the prevout`);
});
it(`decodePsbtMusig2ParticipantsKeyValData fails if invalid subtype or identifier is passed`, function () {
const kv = {
key: {
identifier: 'dummy',
subtype: 0x05,
keydata: Buffer.allocUnsafe(1),
},
value: Buffer.allocUnsafe(1),
};
assert.throws(() => (0, Musig2_1.decodePsbtMusig2Participants)(kv), (e) => e.message === `Invalid identifier ${kv.key.identifier} or subtype ${kv.key.subtype} for participants pub keys`);
kv.key.identifier = bitgo_1.PSBT_PROPRIETARY_IDENTIFIER;
assert.throws(() => (0, Musig2_1.decodePsbtMusig2Participants)(kv), (e) => e.message === `Invalid identifier ${kv.key.identifier} or subtype ${kv.key.subtype} for participants pub keys`);
});
it(`decodePsbtMusig2NonceKeyValData fails if invalid subtype or identifier is passed`, function () {
const kv = {
key: {
identifier: 'dummy',
subtype: 0x05,
keydata: Buffer.allocUnsafe(1),
},
value: Buffer.allocUnsafe(1),
};
assert.throws(() => (0, Musig2_1.decodePsbtMusig2Nonce)(kv), (e) => e.message === `Invalid identifier ${kv.key.identifier} or subtype ${kv.key.subtype} for nonce`);
kv.key.identifier = bitgo_1.PSBT_PROPRIETARY_IDENTIFIER;
assert.throws(() => (0, Musig2_1.decodePsbtMusig2Nonce)(kv), (e) => e.message === `Invalid identifier ${kv.key.identifier} or subtype ${kv.key.subtype} for nonce`);
});
it(`validatePsbtMusig2NoncesKeyValData fails if participant pub keys are duplicate`, function () {
const nonceKeyValData = [0, 1].map((i) => ({
participantPubKey: Musig2Util_1.dummyParticipantPubKeys[i],
tapOutputKey: Musig2Util_1.dummyTapOutputKey,
pubNonce: Musig2Util_1.dummyPubNonce,
}));
let participantKeyValData = {
participantPubKeys: Musig2Util_1.dummyParticipantPubKeys,
tapInternalKey: Musig2Util_1.dummyTapInternalKey,
tapOutputKey: Musig2Util_1.invalidTapOutputKey,
};
assert.throws(() => (0, Musig2_1.assertPsbtMusig2Nonces)(nonceKeyValData, participantKeyValData), (e) => e.message === `invalid size 1. Must use x-only key.`);
participantKeyValData = {
participantPubKeys: [Musig2Util_1.invalidParticipantPubKeys[0], Musig2Util_1.dummyParticipantPubKeys[0]],
tapInternalKey: Musig2Util_1.dummyTapInternalKey,
tapOutputKey: Musig2Util_1.dummyTapOutputKey,
};
assert.throws(() => (0, Musig2_1.assertPsbtMusig2Nonces)(nonceKeyValData, participantKeyValData), (e) => e.message === `invalid size 1. Must use plain key.`);
participantKeyValData = {
participantPubKeys: [Musig2Util_1.dummyParticipantPubKeys[0], Musig2Util_1.dummyParticipantPubKeys[0]],
tapInternalKey: Musig2Util_1.dummyTapInternalKey,
tapOutputKey: Musig2Util_1.dummyTapOutputKey,
};
assert.throws(() => (0, Musig2_1.assertPsbtMusig2Nonces)(nonceKeyValData, participantKeyValData), (e) => e.message === `Duplicate participant pub keys found`);
});
it(`createTapTweak fails if invalid tapInternalKey or tapMerkleRoot is passed`, function () {
assert.throws(() => (0, Musig2_1.createTapTweak)(Musig2Util_1.invalidTapInputKey, Musig2Util_1.dummyTapOutputKey), (e) => e.message === `invalid size 1. Must use x-only key.`);
assert.throws(() => (0, Musig2_1.createTapTweak)(Musig2Util_1.dummyTapInternalKey, Musig2Util_1.invalidTapOutputKey), (e) => e.message === `invalid size 1. Must use tap merkle root.`);
});
it(`musig2PartialSign fails if invalid txHash is passed`, function () {
assert.throws(() => (0, Musig2_1.musig2PartialSign)(Musig2Util_1.dummyPrivateKey, Musig2Util_1.dummyPubNonce, {
publicKey: Musig2Util_1.dummyParticipantPubKeys[0],
aggNonce: Musig2Util_1.dummyAggNonce,
msg: Musig2Util_1.invalidTxHash,
}, new Musig2_1.Musig2NonceStore()), (e) => e.message === `invalid size 1. Must use tx hash.`);
});
it(`encodePsbtMusig2PartialSigKeyKeyValData fails if invalid txHash is passed`, function () {
assert.throws(() => (0, Musig2_1.encodePsbtMusig2PartialSig)({
partialSig: Musig2Util_1.invalidPartialSig,
participantPubKey: Musig2Util_1.dummyParticipantPubKeys[0],
tapOutputKey: Musig2Util_1.dummyTapOutputKey,
}), (e) => e.message === `Invalid partialSig length 1`);
});
it(`deleteProprietaryKeyVals`, function () {
const psbt = (0, Musig2Util_1.constructPsbt)(p2trMusig2Unspent, Musig2Util_1.rootWalletKeys, 'user', 'bitgo', outputType);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.user);
psbt.setAllInputsMusig2NonceHD(Musig2Util_1.rootWalletKeys.bitgo);
const key = {
identifier: 'DUMMY',
subtype: 100,
keydata: Musig2Util_1.dummyTapOutputKey,
};
psbt.addProprietaryKeyValToInput(0, { key, value: Musig2Util_1.dummyTapInternalKey });
psbt.deleteProprietaryKeyVals(0, { identifier: bitgo_1.PSBT_PROPRIETARY_IDENTIFIER });
const keyVal = psbt.getProprietaryKeyVals(0);
assert.strictEqual(keyVal.length, 1);
assert.strictEqual(keyVal[0].key.identifier, 'DUMMY');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTXVzaWcyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC9iaXRnby9wc2J0L011c2lnMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlDQUFpQztBQUVqQyw4Q0FZNEI7QUFFNUIsb0RBQWtGO0FBQ2xGLHNEQVVtQztBQUNuQyxvRUFBcUY7QUFDckYsNkNBMkJzQjtBQUV0QixNQUFNLGlCQUFpQixHQUFHLElBQUEsd0JBQVcsRUFBQyxDQUFDLFlBQVksQ0FBQyxFQUFFLDJCQUFjLENBQUMsQ0FBQztBQUN0RSxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUM7QUFDaEMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBRXpCLFFBQVEsQ0FBQyxZQUFZLEVBQUU7SUFDckIsUUFBUSxDQUFDLHFCQUFxQixFQUFFO1FBQzlCLEVBQUUsQ0FBQyx1REFBdUQsRUFBRTtZQUMxRCxNQUFNLFVBQVUsR0FBRywyQkFBYyxDQUFDLHNCQUFzQixDQUFDLElBQUEsNEJBQW9CLEVBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDaEcsTUFBTSxRQUFRLEdBQUcsSUFBQSx3QkFBVyxFQUMxQiwrQkFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQzdCLDJCQUFjLENBQ2YsQ0FBQztZQUNGLDhFQUE4RTtZQUM5RSxNQUFNLFNBQVMsR0FBRyxJQUFBLDBCQUFhLEVBQUMsUUFBUSxFQUFFLDJCQUFjLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN2RixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFdkMsK0dBQStHO1lBQy9HLE1BQU0sUUFBUSxHQUFHLElBQUEseUJBQWlCLEVBQUMsWUFBWSxFQUFFLG9CQUFPLENBQUMsQ0FBQztZQUMxRCxRQUFRLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4RCxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFckMsc0dBQXNHO1lBQ3RHLE1BQU0sU0FBUyxHQUFHLElBQUEseUJBQWlCLEVBQUMsV0FBVyxFQUFFLG9CQUFPLENBQUMsQ0FBQztZQUMxRCxTQUFTLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNuRixNQUFNLFlBQVksR0FBRyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFdkMsaUdBQWlHO1lBQ2pHLE1BQU0sY0FBYyxHQUFHLElBQUEseUJBQWlCLEVBQUMsWUFBWSxFQUFFLG9CQUFPLENBQUMsQ0FBQztZQUNoRSxRQUFRLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ2pDLFFBQVEsQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM5QyxNQUFNLHFCQUFxQixHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUUvQyxtREFBbUQ7WUFDbkQsTUFBTSxXQUFXLEdBQUcsSUFBQSx5QkFBaUIsRUFBQyxxQkFBcUIsRUFBRSxvQkFBTyxDQUFDLENBQUM7WUFDdEUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsc0NBQXNDLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUU1RixnRUFBZ0U7WUFDaEUsTUFBTSxJQUFJLEdBQUcsSUFBQSx5QkFBaUIsRUFBQyxxQkFBcUIsRUFBRSxvQkFBTyxDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLEtBQUssRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBRXBFLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ2xDLElBQUksSUFBQSwwQkFBa0IsRUFBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssWUFBWSxFQUFFLENBQUM7b0JBQ3ZELE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDaEUsT0FBTztnQkFDVCxDQUFDO2dCQUNELElBQUEsd0NBQTJCLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQzdELElBQUEseUNBQTRCLEVBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN0QyxJQUFBLHdDQUEyQixFQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2xELElBQUEsa0NBQXFCLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDNUMsSUFBQSxzQ0FBeUIsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ2xELENBQUMsQ0FBQyxDQUFDO1lBRUgsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ2xDLElBQUEsbUNBQXNCLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMvQyxDQUFDLENBQUMsQ0FBQztZQUNILE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsRUFBNkIsQ0FBQztZQUNoRSxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUEsc0NBQTJCLEVBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSwyQkFBYyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3RGLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUU7Z0JBQ25DLE1BQU0sQ0FBQyxlQUFlLENBQUMsSUFBQSxrQ0FBMEIsRUFBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSwyQkFBYyxDQUFDLEVBQUU7b0JBQzNGLElBQUk7b0JBQ0osS0FBSztvQkFDTCxJQUFJO2lCQUNMLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsVUFBVSxFQUFFO1lBQ2IsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUMzRixJQUFBLDZDQUFnQyxFQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFFdEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckQsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFDLElBQUEsNkNBQWdDLEVBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUV4RCxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0MsSUFBQSw2Q0FBZ0MsRUFBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBRXpELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBQSxzQkFBYyxFQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ3pDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLHlDQUF5QyxDQUNwRSxDQUFDO1lBRUYsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUE2QixDQUFDO1lBQ2hFLElBQUEsZ0RBQW1DLEVBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLGNBQWMsRUFBRTtZQUN2QixFQUFFLENBQUMseUNBQXlDLEVBQUU7Z0JBQzVDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBRXZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVwRCxJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO29CQUNoRCxVQUFVLEVBQUUsbUNBQTJCO29CQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2lCQUNoRCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUM1QyxNQUFNLFlBQVksR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztnQkFDbEQsTUFBTSxjQUFjLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztnQkFFOUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3JELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVwRCxhQUFhLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRTtvQkFDNUMsVUFBVSxFQUFFLG1DQUEyQjtvQkFDdkMsT0FBTyxFQUFFLDZCQUFxQixDQUFDLGdCQUFnQjtpQkFDaEQsQ0FBQyxDQUFDO2dCQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFFNUMsYUFBYSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUNsRixNQUFNLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1lBQzVELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDhFQUE4RSxFQUFFO2dCQUNqRixNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUV2RixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFcEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDbEUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxDQUFDO2dCQUVuRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxFQUMxRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxnREFBZ0QsQ0FDM0UsQ0FBQztnQkFFRixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztnQkFFNUQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRXJELElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUUzQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO29CQUNsRCxVQUFVLEVBQUUsbUNBQTJCO29CQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2lCQUNoRCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUU1QyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEVBQUU7b0JBQ3RELFVBQVUsRUFBRSxtQ0FBMkI7b0JBQ3ZDLE9BQU8sRUFBRSw2QkFBcUIsQ0FBQyxrQkFBa0I7aUJBQ2xELENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsV0FBVyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFFaEQsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO29CQUN2RCxVQUFVLEVBQUUsbUNBQTJCO29CQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsMkJBQTJCO2lCQUMzRCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUU7Z0JBQzlDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFFOUUsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRTtvQkFDbEQsVUFBVSxFQUFFLG1DQUEyQjtvQkFDdkMsT0FBTyxFQUFFLDZCQUFxQixDQUFDLGdCQUFnQjtpQkFDaEQsQ0FBQyxDQUFDO2dCQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5QyxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwRUFBMEUsRUFBRTtnQkFDN0UsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFFdkYsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFDbkYsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssNkJBQTZCLENBQ3hELENBQUM7Z0JBRUYsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRTtvQkFDaEQsVUFBVSxFQUFFLG1DQUEyQjtvQkFDdkMsT0FBTyxFQUFFLDZCQUFxQixDQUFDLGdCQUFnQjtpQkFDaEQsQ0FBQyxDQUFDO2dCQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFFNUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3JELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQ25GLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLCtFQUErRSxDQUMxRyxDQUFDO2dCQUVGLGFBQWEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO29CQUM1QyxVQUFVLEVBQUUsbUNBQTJCO29CQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2lCQUNoRCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDZEQUE2RCxFQUFFO2dCQUNoRSxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEQsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FDSCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLEVBQUU7b0JBQ25ELGFBQWEsRUFBRSxJQUFJO29CQUNuQixTQUFTLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7aUJBQ2xDLENBQUMsRUFDSixDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxnRUFBZ0UsQ0FDM0YsQ0FBQztnQkFDRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO29CQUNsRCxVQUFVLEVBQUUsbUNBQTJCO29CQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2lCQUNoRCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO2dCQUMvQyxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUNsRixDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyx3REFBd0QsQ0FDbkYsQ0FBQztnQkFDRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO29CQUNsRCxVQUFVLEVBQUUsbUNBQTJCO29CQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2lCQUNoRCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGtFQUFrRSxFQUFFO2dCQUNyRSxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsZ0NBQW1CLENBQUM7Z0JBQ3pELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ3pELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLG1FQUFtRSxDQUM5RixDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtnQkFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQ2hHLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLDJCQUEyQixDQUN0RCxDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRTtnQkFDcEMsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFDcEUsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssMkNBQTJDLENBQ3RFLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHdDQUF3QyxFQUFFO2dCQUMzQyxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsR0FBRyxFQUFFLENBQUM7Z0JBQzVDLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ3pELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLGdEQUFnRCxDQUMzRSxDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRTtnQkFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztnQkFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsRUFDekQsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUsscURBQXFELENBQ2hGLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHVEQUF1RCxFQUFFO2dCQUMxRCxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdkYsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsRUFDekQsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssd0JBQXdCLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sMkJBQTJCLENBQzNHLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHNEQUFzRCxFQUFFO2dCQUN6RCxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyw4QkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSywyQ0FBMkMsQ0FDdEUsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsd0RBQXdELEVBQUU7Z0JBQzNELE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsZ0NBQW1CLENBQUMsQ0FBQyxDQUFDO2dCQUN0RyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyw2Q0FBNkMsQ0FDeEUsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMseUVBQXlFLEVBQUU7Z0JBQzVFLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFOUMsTUFBTSxVQUFVLEdBQUcsMkJBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFBLDRCQUFvQixFQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNoRyxNQUFNLGNBQWMsR0FBRyxJQUFBLDZCQUFvQixFQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUNyRyxNQUFNLFlBQVksR0FBRyxJQUFBLDJCQUFrQixFQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFjLENBQUMsQ0FBQztnQkFFNUYsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFlBQVksRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDO2dCQUN2RSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBRTFGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7Z0JBQ3hDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2hELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ3pELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLG1FQUFtRSxDQUM5RixDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwREFBMEQsRUFBRTtnQkFDN0QsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM5QyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxrREFBa0QsQ0FDN0UsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsNERBQTRELEVBQUU7Z0JBQy9ELE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxvREFBb0QsQ0FDL0UsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUU7Z0JBQ2xELE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxzQ0FBc0MsQ0FDakUsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0JBQStCLEVBQUU7Z0JBQ2xDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hHLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ3pELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLHlFQUF5RSxDQUNwRyxDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtnQkFDckQsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsTUFBTSxVQUFVLEdBQUcsMkJBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFBLDRCQUFvQixFQUFDLFlBQVksQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO2dCQUMzRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtvQkFDckQsRUFBRSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNoQyxDQUFDLENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxzQ0FBc0MsQ0FDakUsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQUU7Z0JBQ3JFLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU0sVUFBVSxHQUFHLDJCQUFjLENBQUMsc0JBQXNCLENBQ3RELGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFDMUIsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUMzQixDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRTtvQkFDNUQsRUFBRSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUM5QixFQUFFLENBQUMsTUFBTSxHQUFHLElBQUEsZ0NBQWdCLEVBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN2RCxFQUFFLENBQUMsaUJBQWlCLEdBQUcsMkJBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO2dCQUN6RCxDQUFDLENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsbURBQW1ELENBQUMsQ0FDdEYsQ0FBQztnQkFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsZ0VBQWdFLEVBQUU7Z0JBQ25FLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFOUMsTUFBTSxVQUFVLEdBQUcsMkJBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFBLDRCQUFvQixFQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNoRyxNQUFNLGNBQWMsR0FBRyxJQUFBLDZCQUFvQixFQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUNyRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO2dCQUVwRCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFGLE1BQU0sWUFBWSxHQUFHLElBQUEsMkJBQWtCLEVBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWMsQ0FBQyxDQUFDO2dCQUM1RixPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7Z0JBQ3hDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRWhELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ3pELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLDBFQUEwRSxDQUNyRyxDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUNmLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRTtnQkFDbkMsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNyRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsMkJBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsRUFDaEUsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssNENBQTRDLENBQ3ZFLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzlELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLG9DQUFvQyxFQUFFO2dCQUN2QyxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUV2RixNQUFNLFVBQVUsR0FBRywyQkFBYyxDQUFDLHNCQUFzQixDQUN0RCxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQzFCLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FDM0IsQ0FBQztnQkFFRixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBRXJELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7Z0JBQy9DLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQ0gsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsRUFBRTtvQkFDN0IsU0FBUyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUztvQkFDcEMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVztpQkFDeEMsQ0FBQyxFQUNKLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLDRCQUE0QixDQUN2RCxDQUFDO2dCQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxxREFBcUQsRUFBRTtnQkFDeEQsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDdkYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM5RSxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLDJCQUFjLENBQUMsSUFBSSxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQ3ZFLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLHdEQUF3RCxDQUNuRixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMscUNBQXFDLEVBQUU7Z0JBQ3hDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ3ZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDOUUsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsS0FBSyxFQUFFLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3BFLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO1lBQ3RDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHlDQUF5QyxFQUFFO2dCQUM1QyxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUN2RixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxFQUFFLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7Z0JBQy9FLElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLEtBQUssRUFBRSxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUNyRSxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDLENBQUM7Z0JBQ2hELE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztZQUN0QyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFO1lBQ3RDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFFdkYsTUFBTSxVQUFVLEdBQUcsMkJBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFakgsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFckQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztZQUM5QyxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUNILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUU7Z0JBQzdCLFNBQVMsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVM7Z0JBQ3BDLFVBQVUsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVc7YUFDeEMsQ0FBQyxFQUNKLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLDRCQUE0QixDQUN2RCxDQUFDO1lBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFO1lBQzdDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztZQUN4QyxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsMkJBQWMsQ0FBQyxJQUFJLENBQUMsRUFDckQsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUsscURBQXFELENBQ2hGLENBQUM7WUFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQUU7WUFDckUsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUNILElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUU7Z0JBQzdCLFVBQVUsRUFBRSwyQkFBYyxDQUFDLE1BQU0sQ0FBQyxVQUFXO2dCQUM3QyxTQUFTLEVBQUUsMkJBQWMsQ0FBQyxNQUFNLENBQUMsU0FBVTthQUM1QyxDQUFDLEVBQ0osQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUsseURBQXlELENBQ3BGLENBQUM7WUFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkNBQTZDLEVBQUU7WUFDaEQsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hGLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsRUFBRSwyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUNyRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxvREFBb0QsQ0FDL0UsQ0FBQztZQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRTtZQUM1QyxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ3JELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLCtDQUErQyxDQUMxRSxDQUFDO1lBQ0YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzlELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdDQUF3QyxFQUFFO1lBQzNDLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFckQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRTtnQkFDNUMsVUFBVSxFQUFFLG1DQUEyQjtnQkFDdkMsT0FBTyxFQUFFLDZCQUFxQixDQUFDLGdCQUFnQjthQUNoRCxDQUFDLENBQUM7WUFDSCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkYsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsRUFBRSwyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUNyRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyx3QkFBd0IsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxZQUFZLENBQzVGLENBQUM7WUFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUU7WUFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVyRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO2dCQUM1QyxVQUFVLEVBQUUsbUNBQTJCO2dCQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2FBQ2hELENBQUMsQ0FBQztZQUNILE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0UsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsRUFBRSwyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUNyRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSywwQkFBMEIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLFlBQVksQ0FDeEYsQ0FBQztZQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRTtZQUN0QyxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXJELE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxzQkFBYyxDQUFDLElBQUEsdUJBQVksRUFBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ3RFLE1BQU0sc0JBQXNCLEdBQUcsSUFBQSx3QkFBVyxFQUFDLENBQUMsWUFBWSxDQUFDLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUNoRixNQUFNLFNBQVMsR0FBRyxJQUFBLDBCQUFhLEVBQUMsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN0RyxTQUFTLENBQUMseUJBQXlCLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUQsU0FBUyxDQUFDLHlCQUF5QixDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRS9ELE1BQU0sWUFBWSxHQUFHLFNBQVMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3RELFVBQVUsRUFBRSxtQ0FBMkI7Z0JBQ3ZDLE9BQU8sRUFBRSw2QkFBcUIsQ0FBQyxnQkFBZ0I7YUFDaEQsQ0FBQyxDQUFDO1lBRUgsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RGLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsRUFBRSwyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUNyRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSywyQ0FBMkMsQ0FDdEUsQ0FBQztZQUNGLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnREFBZ0QsRUFBRTtZQUNuRCxNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXJELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQzVDLFVBQVUsRUFBRSxtQ0FBMkI7Z0JBQ3ZDLE9BQU8sRUFBRSw2QkFBcUIsQ0FBQyxnQkFBZ0I7YUFDaEQsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsOEJBQWlCLENBQUMsQ0FBQyxDQUFDO1lBRXBHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLEVBQUUsMkJBQWMsQ0FBQyxJQUFJLENBQUMsRUFDckQsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssb0NBQW9DLENBQy9ELENBQUM7WUFDRixNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx3QkFBd0IsRUFBRTtRQUNqQyxFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsSUFBSSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUMxRixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFDLElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1QyxJQUFBLHdDQUEyQixFQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDekUsSUFBQSx5Q0FBNEIsRUFBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDdEMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ3pCLElBQUEsbUNBQXNCLEVBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUNwRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQTZCLENBQUM7WUFDOUQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFBLHNDQUEyQixFQUFDLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBRWhHLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3ZGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVELElBQUEsd0NBQTJCLEVBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUN6RSxJQUFBLHlDQUE0QixFQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN0QyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDekIsSUFBQSxtQ0FBc0IsRUFBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQ3BFLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQTZCLENBQUM7WUFDMUQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFBLHNDQUEyQixFQUFDLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ25HLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLFVBQVUsRUFBRTtZQUNiLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDNUYsSUFBQSxnREFBbUMsRUFBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXpELElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxQyxJQUFBLGdEQUFtQyxFQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFFM0QsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVDLElBQUEsZ0RBQW1DLEVBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUU1RCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUN6QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQTZCLENBQUM7WUFFaEUsTUFBTSxhQUFhLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNyRyxJQUFBLG1EQUFzQyxFQUFDLGFBQWEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDL0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxpQ0FBaUMsRUFBRTtRQUMxQyxFQUFFLENBQUMsc0JBQXNCLEVBQUU7WUFDekIsTUFBTSxVQUFVLEdBQUcsMkJBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakgsSUFBSSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN6RixJQUFJLENBQUMsdUJBQXVCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFFckYsSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDckYsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRSwyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3JGLElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ3hGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlCQUFpQixFQUFFO1lBQ3BCLE1BQU0sVUFBVSxHQUFHLDJCQUFjLENBQUMsc0JBQXNCLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pILE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDM0YsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEVBQUUsRUFDMUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssMkJBQTJCLENBQ3RELENBQUM7WUFFRixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUVyRCxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFMUMsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsc0NBQXNDLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQ2hGLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLCtCQUErQixDQUMxRCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsTUFBTSxVQUFVLEdBQUcsMkJBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakgsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUMzRixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztZQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1lBQy9DLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUMsQ0FBQyxFQUNwRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxvREFBb0QsQ0FDL0UsQ0FBQztZQUVGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7WUFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztZQUM5QyxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFDaEYsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssb0RBQW9ELENBQy9FLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRTtZQUM1QyxJQUFJLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsaUJBQWlCLEVBQUUsMkJBQWMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3pGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRTtnQkFDaEQsVUFBVSxFQUFFLG1DQUEyQjtnQkFDdkMsT0FBTyxFQUFFLDZCQUFxQixDQUFDLGtCQUFrQjthQUNsRCxDQUFDLENBQUM7WUFFSCxNQUFNLGdCQUFnQixHQUFHLElBQUksc0JBQWMsQ0FBQyxJQUFBLHVCQUFZLEVBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNuRSxNQUFNLFVBQVUsR0FBRyxJQUFBLHdCQUFXLEVBQUMsQ0FBQyxZQUFZLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2pFLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDaEYsSUFBSSxDQUFDLHlCQUF5QixDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RELElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFN0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsRUFBRTtnQkFDakQsVUFBVSxFQUFFLG1DQUEyQjtnQkFDdkMsT0FBTyxFQUFFLDZCQUFxQixDQUFDLDJCQUEyQjthQUMzRCxDQUFDLENBQUM7WUFFSCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxFQUFFO2dCQUMzQyxVQUFVLEVBQUUsbUNBQTJCO2dCQUN2QyxPQUFPLEVBQUUsNkJBQXFCLENBQUMsZ0JBQWdCO2FBQ2hELENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7WUFDL0MsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9DLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsMkJBQTJCLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRXBELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFLEVBQzFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLCtCQUErQixDQUMxRCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUJBQXVCLEVBQUU7WUFDMUIsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUMzRixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2hELFVBQVUsRUFBRSxtQ0FBMkI7Z0JBQ3ZDLE9BQU8sRUFBRSw2QkFBcUIsQ0FBQyxrQkFBa0I7YUFDbEQsQ0FBQyxDQUFDO1lBRUgsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyw0QkFBZSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFNUQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyw0QkFBNEIsRUFBRTtRQUNyQyxFQUFFLENBQUMsa0NBQWtDLEVBQUU7WUFDckMsTUFBTSxJQUFJLEdBQUcsSUFBQSwwQkFBYSxFQUFDLGlCQUFpQixFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUMzRixJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMseUJBQXlCLENBQUMsMkJBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsZUFBZSxDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFMUMsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFDOUIsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssb0RBQW9ELENBQy9FLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDhCQUE4QixFQUFFO1FBQ3ZDLEVBQUUsQ0FBQyw0REFBNEQsRUFBRTtZQUMvRCxNQUFNLGdCQUFnQixHQUFHLElBQUksc0JBQWMsQ0FBQyxJQUFBLHVCQUFZLEVBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUNuRSxNQUFNLFFBQVEsR0FBRyxJQUFBLHdCQUFXLEVBQzFCLCtCQUFlLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFDN0IsZ0JBQWdCLENBQ2pCLENBQUM7WUFFRixNQUFNLElBQUksR0FBRyxJQUFBLDBCQUFhLEVBQUMsUUFBUSxFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNsRixRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUM1QixNQUFNLFVBQVUsR0FBRyxJQUFBLDBCQUFrQixFQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDL0MsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FDSCxVQUFVLEtBQUssWUFBWTtvQkFDekIsQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQywyQkFBYyxDQUFDLElBQUksQ0FBQztvQkFDckQsQ0FBQyxDQUFDLFVBQVUsS0FBSyxNQUFNO3dCQUN2QixDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssRUFBRSwyQkFBYyxDQUFDLElBQUksQ0FBQzt3QkFDckQsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLDJCQUFjLENBQUMsSUFBSSxDQUFDLEVBQ2xELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FDVCxJQUFBLGdCQUFRLEVBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLFVBQVUsS0FBSyxXQUFXO29CQUM3QyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyw2QkFBNkIsS0FBSyxnREFBZ0Q7b0JBQ2xHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLDRCQUE0QixLQUFLLGdEQUFnRCxDQUN0RyxDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxNQUFNLHdCQUF3QixHQUFHLElBQUEsMEJBQWEsRUFBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLDJCQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUM1RyxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLHdCQUF3QixDQUFDLGtCQUFrQixDQUFDLENBQUMsRUFBRSwyQkFBYyxDQUFDLElBQUksQ0FBQyxFQUN6RSxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSywyRUFBMkUsQ0FDdEcsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlGQUF5RixFQUFFO1lBQzVGLE1BQU0sRUFBRSxHQUFHO2dCQUNULEdBQUcsRUFBRTtvQkFDSCxVQUFVLEVBQUUsT0FBTztvQkFDbkIsT0FBTyxFQUFFLElBQUk7b0JBQ2IsT0FBTyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO2lCQUMvQjtnQkFDRCxLQUFLLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7YUFDN0IsQ0FBQztZQUVGLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBQSxxQ0FBNEIsRUFBQyxFQUFFLENBQUMsRUFDdEMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUNULENBQUMsQ0FBQyxPQUFPLEtBQUssc0JBQXNCLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyw0QkFBNEIsQ0FDakgsQ0FBQztZQUVGLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxHQUFHLG1DQUEyQixDQUFDO1lBQ2hELE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBQSxxQ0FBNEIsRUFBQyxFQUFFLENBQUMsRUFDdEMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUNULENBQUMsQ0FBQyxPQUFPLEtBQUssc0JBQXNCLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyw0QkFBNEIsQ0FDakgsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtGQUFrRixFQUFFO1lBQ3JGLE1BQU0sRUFBRSxHQUFHO2dCQUNULEdBQUcsRUFBRTtvQkFDSCxVQUFVLEVBQUUsT0FBTztvQkFDbkIsT0FBTyxFQUFFLElBQUk7b0JBQ2IsT0FBTyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO2lCQUMvQjtnQkFDRCxLQUFLLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7YUFDN0IsQ0FBQztZQUVGLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBQSw4QkFBcUIsRUFBQyxFQUFFLENBQUMsRUFDL0IsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssc0JBQXNCLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBVSxlQUFlLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxZQUFZLENBQzNHLENBQUM7WUFFRixFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxtQ0FBMkIsQ0FBQztZQUNoRCxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUEsOEJBQXFCLEVBQUMsRUFBRSxDQUFDLEVBQy9CLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLHNCQUFzQixFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsZUFBZSxFQUFFLENBQUMsR0FBRyxDQUFDLE9BQU8sWUFBWSxDQUMzRyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0ZBQWdGLEVBQUU7WUFDbkYsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QyxpQkFBaUIsRUFBRSxvQ0FBdUIsQ0FBQyxDQUFDLENBQUM7Z0JBQzdDLFlBQVksRUFBRSw4QkFBaUI7Z0JBQy9CLFFBQVEsRUFBRSwwQkFBYTthQUN4QixDQUFDLENBQUMsQ0FBQztZQUVKLElBQUkscUJBQXFCLEdBQUc7Z0JBQzFCLGtCQUFrQixFQUFFLG9DQUF1QjtnQkFDM0MsY0FBYyxFQUFFLGdDQUFtQjtnQkFDbkMsWUFBWSxFQUFFLGdDQUFtQjthQUNsQyxDQUFDO1lBRUYsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FBQyxJQUFBLCtCQUFzQixFQUFDLGVBQWUsRUFBRSxxQkFBcUIsQ0FBQyxFQUNwRSxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxzQ0FBc0MsQ0FDakUsQ0FBQztZQUVGLHFCQUFxQixHQUFHO2dCQUN0QixrQkFBa0IsRUFBRSxDQUFDLHNDQUF5QixDQUFDLENBQUMsQ0FBQyxFQUFFLG9DQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM5RSxjQUFjLEVBQUUsZ0NBQW1CO2dCQUNuQyxZQUFZLEVBQUUsOEJBQWlCO2FBQ2hDLENBQUM7WUFDRixNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUEsK0JBQXNCLEVBQUMsZUFBZSxFQUFFLHFCQUFxQixDQUFDLEVBQ3BFLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLHFDQUFxQyxDQUNoRSxDQUFDO1lBRUYscUJBQXFCLEdBQUc7Z0JBQ3RCLGtCQUFrQixFQUFFLENBQUMsb0NBQXVCLENBQUMsQ0FBQyxDQUFDLEVBQUUsb0NBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzVFLGNBQWMsRUFBRSxnQ0FBbUI7Z0JBQ25DLFlBQVksRUFBRSw4QkFBaUI7YUFDaEMsQ0FBQztZQUNGLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBQSwrQkFBc0IsRUFBQyxlQUFlLEVBQUUscUJBQXFCLENBQUMsRUFDcEUsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssc0NBQXNDLENBQ2pFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyRUFBMkUsRUFBRTtZQUM5RSxNQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUFDLElBQUEsdUJBQWMsRUFBQywrQkFBa0IsRUFBRSw4QkFBaUIsQ0FBQyxFQUMzRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxzQ0FBc0MsQ0FDakUsQ0FBQztZQUVGLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQUMsSUFBQSx1QkFBYyxFQUFDLGdDQUFtQixFQUFFLGdDQUFtQixDQUFDLEVBQzlELENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxLQUFLLDJDQUEyQyxDQUN0RSxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUU7WUFDeEQsTUFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FDSCxJQUFBLDBCQUFpQixFQUNmLDRCQUFlLEVBQ2YsMEJBQWEsRUFDYjtnQkFDRSxTQUFTLEVBQUUsb0NBQXVCLENBQUMsQ0FBQyxDQUFDO2dCQUNyQyxRQUFRLEVBQUUsMEJBQWE7Z0JBQ3ZCLEdBQUcsRUFBRSwwQkFBYTthQUNuQixFQUNELElBQUkseUJBQWdCLEVBQUUsQ0FDdkIsRUFDSCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxtQ0FBbUMsQ0FDOUQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJFQUEyRSxFQUFFO1lBQzlFLE1BQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFLENBQ0gsSUFBQSxtQ0FBMEIsRUFBQztnQkFDekIsVUFBVSxFQUFFLDhCQUFpQjtnQkFDN0IsaUJBQWlCLEVBQUUsb0NBQXVCLENBQUMsQ0FBQyxDQUFDO2dCQUM3QyxZQUFZLEVBQUUsOEJBQWlCO2FBQ2hDLENBQUMsRUFDSixDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyw2QkFBNkIsQ0FDeEQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBCQUEwQixFQUFFO1lBQzdCLE1BQU0sSUFBSSxHQUFHLElBQUEsMEJBQWEsRUFBQyxpQkFBaUIsRUFBRSwyQkFBYyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDM0YsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLHlCQUF5QixDQUFDLDJCQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckQsTUFBTSxHQUFHLEdBQUc7Z0JBQ1YsVUFBVSxFQUFFLE9BQU87Z0JBQ25CLE9BQU8sRUFBRSxHQUFHO2dCQUNaLE9BQU8sRUFBRSw4QkFBaUI7YUFDM0IsQ0FBQztZQUNGLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLGdDQUFtQixFQUFFLENBQUMsQ0FBQztZQUN6RSxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLG1DQUEyQixFQUFFLENBQUMsQ0FBQztZQUM5RSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZVBzYnRGcm9tSGV4LFxuICBnZXRFeHRlcm5hbENoYWluQ29kZSxcbiAgZ2V0SW50ZXJuYWxDaGFpbkNvZGUsXG4gIGlzU2Vnd2l0LFxuICBwYXJzZVBzYnRJbnB1dCxcbiAgUHJvcHJpZXRhcnlLZXlTdWJ0eXBlLFxuICBQU0JUX1BST1BSSUVUQVJZX0lERU5USUZJRVIsXG4gIFJvb3RXYWxsZXRLZXlzLFxuICBzY3JpcHRUeXBlRm9yQ2hhaW4sXG4gIFV0eG9UcmFuc2FjdGlvbixcbiAgdmVyaWZ5U2lnbmF0dXJlV2l0aFVuc3BlbnQsXG59IGZyb20gJy4uLy4uLy4uL3NyYy9iaXRnbyc7XG5cbmltcG9ydCB7IGdldEtleVRyaXBsZSwgdmVyaWZ5RnVsbHlTaWduZWRTaWduYXR1cmVzIH0gZnJvbSAnLi4vLi4vLi4vc3JjL3Rlc3R1dGlsJztcbmltcG9ydCB7XG4gIGNyZWF0ZVRhcEludGVybmFsS2V5LFxuICBjcmVhdGVUYXBPdXRwdXRLZXksXG4gIGNyZWF0ZVRhcFR3ZWFrLFxuICBkZWNvZGVQc2J0TXVzaWcyTm9uY2UsXG4gIGRlY29kZVBzYnRNdXNpZzJQYXJ0aWNpcGFudHMsXG4gIGVuY29kZVBzYnRNdXNpZzJQYXJ0aWFsU2lnLFxuICBtdXNpZzJQYXJ0aWFsU2lnbixcbiAgYXNzZXJ0UHNidE11c2lnMk5vbmNlcyxcbiAgTXVzaWcyTm9uY2VTdG9yZSxcbn0gZnJvbSAnLi4vLi4vLi4vc3JjL2JpdGdvL011c2lnMic7XG5pbXBvcnQgeyBzY3JpcHRUeXBlczJPZjMsIHRvWE9ubHlQdWJsaWNLZXkgfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28vb3V0cHV0U2NyaXB0cyc7XG5pbXBvcnQge1xuICBjb25zdHJ1Y3RQc2J0LFxuICBnZXRVbnNwZW50cyxcbiAgaW52YWxpZFBhcnRpYWxTaWcsXG4gIGludmFsaWRQYXJ0aWNpcGFudFB1YktleXMsXG4gIGludmFsaWRUYXBJbnB1dEtleSxcbiAgaW52YWxpZFRhcE91dHB1dEtleSxcbiAgaW52YWxpZFR4SGFzaCxcbiAgZHVtbXlBZ2dOb25jZSxcbiAgdmFsaWRhdGVOb25jZXNLZXlWYWxzLFxuICB2YWxpZGF0ZVBhcnRpYWxTaWdLZXlWYWxzLFxuICB2YWxpZGF0ZVBhcnRpY2lwYW50c0tleVZhbHMsXG4gIHZhbGlkYXRlUHNidFAydHJNdXNpZzJJbnB1dCxcbiAgdmFsaWRhdGVQc2J0UDJ0ck11c2lnMk91dHB1dCxcbiAgZHVtbXlQYXJ0aWNpcGFudFB1YktleXMsXG4gIGR1bW15UHJpdmF0ZUtleSxcbiAgZHVtbXlQdWJOb25jZSxcbiAgZHVtbXlUYXBJbnRlcm5hbEtleSxcbiAgZHVtbXlUYXBPdXRwdXRLZXksXG4gIGR1bW15UGFydGlhbFNpZyxcbiAgdmFsaWRhdGVGaW5hbGl6ZWRJbnB1dCxcbiAgbmV0d29yayxcbiAgdmFsaWRhdGVQYXJzZWRUYXByb290S2V5UGF0aFR4SW5wdXQsXG4gIHZhbGlkYXRlUGFyc2VkVGFwcm9vdFNjcmlwdFBhdGhUeElucHV0LFxuICB2YWxpZGF0ZVBhcnNlZFRhcHJvb3RLZXlQYXRoUHNidCxcbiAgdmFsaWRhdGVQYXJzZWRUYXByb290U2NyaXB0UGF0aFBzYnQsXG4gIHJvb3RXYWxsZXRLZXlzLFxufSBmcm9tICcuL011c2lnMlV0aWwnO1xuXG5jb25zdCBwMnRyTXVzaWcyVW5zcGVudCA9IGdldFVuc3BlbnRzKFsncDJ0ck11c2lnMiddLCByb290V2FsbGV0S2V5cyk7XG5jb25zdCBvdXRwdXRUeXBlID0gJ3AydHJNdXNpZzInO1xuY29uc3QgQ0hBTkdFX0lOREVYID0gMTAwO1xuXG5kZXNjcmliZSgncDJ0ck11c2lnMicsIGZ1bmN0aW9uICgpIHtcbiAgZGVzY3JpYmUoJ3AydHJNdXNpZzIga2V5IHBhdGgnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoYGNyZWF0ZSBwc2J0LCBub25jZXMsIHNpZ24gKGludGVybmFsIHZlcmlmeSkgLSBzdWNjZXNzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0S2V5cyA9IHJvb3RXYWxsZXRLZXlzLmRlcml2ZUZvckNoYWluQW5kSW5kZXgoZ2V0RXh0ZXJuYWxDaGFpbkNvZGUoJ3AydHJNdXNpZzInKSwgMCk7XG4gICAgICBjb25zdCB1bnNwZW50cyA9IGdldFVuc3BlbnRzKFxuICAgICAgICBzY3JpcHRUeXBlczJPZjMubWFwKCh0KSA9PiB0KSxcbiAgICAgICAgcm9vdFdhbGxldEtleXNcbiAgICAgICk7XG4gICAgICAvLyBXUCBjcmVhdGVzIFBTQlQgZHVyaW5nIGJ1aWxkIEFQSSwgc2VyaWFsaXplcyBpdCwgYW5kIHNlbmRzIHRoZSBwc2J0IHRvIHVzZXJcbiAgICAgIGNvbnN0IGJ1aWxkUHNidCA9IGNvbnN0cnVjdFBzYnQodW5zcGVudHMsIHJvb3RXYWxsZXRLZXlzLCAnYml0Z28nLCAndXNlcicsIG91dHB1dFR5cGUpO1xuICAgICAgY29uc3QgYnVpbGRQc2J0U2VyID0gYnVpbGRQc2J0LnRvSGV4KCk7XG5cbiAgICAgIC8vIFVzZXIgZGUtc2VyaWFsaXNlcyB0aGUgcHNidCwgYW5kcyB0aGUgdXNlciBub25jZSwgYW5kIHNlbmRzIGl0IHRvIHRoZSBoc20gc28gdGhhdCBpdCBjYW4gYWRkIHRoZSBiaXRnbyBub25jZVxuICAgICAgY29uc3QgdXNlclBzYnQgPSBjcmVhdGVQc2J0RnJvbUhleChidWlsZFBzYnRTZXIsIG5ldHdvcmspO1xuICAgICAgdXNlclBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIGNvbnN0IHVzZXJQc2J0U2VyID0gdXNlclBzYnQudG9IZXgoKTtcblxuICAgICAgLy8gSFNNIGRlc2VyaWFsaXplcyB0aGUgdXNlciBwc2J0LCBhZGRzIHRoZSBkZXRlcm1pbmlzdGljIGJpdGdvIG5vbmNlLCBhbmQgc2VuZHMgdGhhdCBiYWNrIHRvIHRoZSB1c2VyXG4gICAgICBjb25zdCBiaXRnb1BzYnQgPSBjcmVhdGVQc2J0RnJvbUhleCh1c2VyUHNidFNlciwgbmV0d29yayk7XG4gICAgICBiaXRnb1BzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbywgeyBkZXRlcm1pbmlzdGljOiB0cnVlIH0pO1xuICAgICAgY29uc3QgYml0Z29Qc2J0U2VyID0gYml0Z29Qc2J0LnRvSGV4KCk7XG5cbiAgICAgIC8vIFVzZXIgY29tYmluZXMgdGhlIHBzYnQgd2l0aCB0aGUgYml0Z28gbm9uY2UsIGFkZHMgdXNlciBzaWduYXR1cmUsIGFuZCBzZW5kcyBoYWxmLXNpZ25lZCB0byBoc21cbiAgICAgIGNvbnN0IGJpdGdvUHNidERlc2VyID0gY3JlYXRlUHNidEZyb21IZXgoYml0Z29Qc2J0U2VyLCBuZXR3b3JrKTtcbiAgICAgIHVzZXJQc2J0LmNvbWJpbmUoYml0Z29Qc2J0RGVzZXIpO1xuICAgICAgdXNlclBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgY29uc3QgdXNlclBzYnRIYWxmU2lnbmVkSGV4ID0gdXNlclBzYnQudG9IZXgoKTtcblxuICAgICAgLy8gV1AgZGUtc2VyaWFsaXNlcyB0aGUgcHNidCBhbmQgdmFsaWRhdGVzIHVzZXIgc2lnXG4gICAgICBjb25zdCB1c2VyUHNidERlcyA9IGNyZWF0ZVBzYnRGcm9tSGV4KHVzZXJQc2J0SGFsZlNpZ25lZEhleCwgbmV0d29yayk7XG4gICAgICBhc3NlcnQub2sodXNlclBzYnREZXMudmFsaWRhdGVUYXByb290TXVzaWcyU2lnbmF0dXJlc09mSW5wdXQoNCwgd2FsbGV0S2V5cy51c2VyLnB1YmxpY0tleSkpO1xuXG4gICAgICAvLyBXUCBzZW5kcyB0byBoc20gZm9yIHNpZ25hdHVyZSBhbmQgcmV0dXJucyBhIGZ1bGx5IHNpZ25lZCBwc2J0XG4gICAgICBjb25zdCBwc2J0ID0gY3JlYXRlUHNidEZyb21IZXgodXNlclBzYnRIYWxmU2lnbmVkSGV4LCBuZXR3b3JrKTtcbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLmJpdGdvLCB7IGRldGVybWluaXN0aWM6IHRydWUgfSk7XG5cbiAgICAgIHVuc3BlbnRzLmZvckVhY2goKHVuc3BlbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChzY3JpcHRUeXBlRm9yQ2hhaW4odW5zcGVudC5jaGFpbikgIT09ICdwMnRyTXVzaWcyJykge1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscyhpbmRleCkubGVuZ3RoLCAwKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVQc2J0UDJ0ck11c2lnMklucHV0KHBzYnQsIGluZGV4LCB1bnNwZW50LCAna2V5UGF0aCcpO1xuICAgICAgICB2YWxpZGF0ZVBzYnRQMnRyTXVzaWcyT3V0cHV0KHBzYnQsIDApO1xuICAgICAgICB2YWxpZGF0ZVBhcnRpY2lwYW50c0tleVZhbHMocHNidCwgaW5kZXgsIHVuc3BlbnQpO1xuICAgICAgICB2YWxpZGF0ZU5vbmNlc0tleVZhbHMocHNidCwgaW5kZXgsIHVuc3BlbnQpO1xuICAgICAgICB2YWxpZGF0ZVBhcnRpYWxTaWdLZXlWYWxzKHBzYnQsIGluZGV4LCB1bnNwZW50KTtcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQub2socHNidC52YWxpZGF0ZVNpZ25hdHVyZXNPZkFsbElucHV0cygpKTtcbiAgICAgIHBzYnQuZmluYWxpemVBbGxJbnB1dHMoKTtcbiAgICAgIHVuc3BlbnRzLmZvckVhY2goKHVuc3BlbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIHZhbGlkYXRlRmluYWxpemVkSW5wdXQocHNidCwgaW5kZXgsIHVuc3BlbnQpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCB0eCA9IHBzYnQuZXh0cmFjdFRyYW5zYWN0aW9uKCkgYXMgVXR4b1RyYW5zYWN0aW9uPGJpZ2ludD47XG4gICAgICBhc3NlcnQub2sodmVyaWZ5RnVsbHlTaWduZWRTaWduYXR1cmVzKHR4LCB1bnNwZW50cywgcm9vdFdhbGxldEtleXMsICdiaXRnbycsICd1c2VyJykpO1xuICAgICAgdW5zcGVudHMubWFwKCh1bnNwZW50LCBpbnB1dEluZGV4KSA9PiB7XG4gICAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodmVyaWZ5U2lnbmF0dXJlV2l0aFVuc3BlbnQodHgsIGlucHV0SW5kZXgsIHVuc3BlbnRzLCByb290V2FsbGV0S2V5cyksIFtcbiAgICAgICAgICB0cnVlLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgIF0pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChgcGFyc2UgdHhgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICdiaXRnbycsICd1c2VyJywgb3V0cHV0VHlwZSk7XG4gICAgICB2YWxpZGF0ZVBhcnNlZFRhcHJvb3RLZXlQYXRoUHNidChwc2J0LCAwLCAndW5zaWduZWQnKTtcblxuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgdmFsaWRhdGVQYXJzZWRUYXByb290S2V5UGF0aFBzYnQocHNidCwgMCwgJ2hhbGZzaWduZWQnKTtcblxuICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuICAgICAgdmFsaWRhdGVQYXJzZWRUYXByb290S2V5UGF0aFBzYnQocHNidCwgMCwgJ2Z1bGx5c2lnbmVkJyk7XG5cbiAgICAgIHBzYnQuZmluYWxpemVBbGxJbnB1dHMoKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBhcnNlUHNidElucHV0KHBzYnQuZGF0YS5pbnB1dHNbMF0pLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdGaW5hbGl6ZWQgUFNCVCBwYXJzaW5nIGlzIG5vdCBzdXBwb3J0ZWQnXG4gICAgICApO1xuXG4gICAgICBjb25zdCB0eCA9IHBzYnQuZXh0cmFjdFRyYW5zYWN0aW9uKCkgYXMgVXR4b1RyYW5zYWN0aW9uPGJpZ2ludD47XG4gICAgICB2YWxpZGF0ZVBhcnNlZFRhcHJvb3RLZXlQYXRoVHhJbnB1dChwc2J0LCB0eCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlIG5vbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoYHVwZGF0ZSB3aXRoIG5ldyBub25jZSBzaG91bGQgYmUgYWxsb3dlZGAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG5cbiAgICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuXG4gICAgICAgIGxldCBub25jZXNLZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCwge1xuICAgICAgICAgIGlkZW50aWZpZXI6IFBTQlRfUFJPUFJJRVRBUllfSURFTlRJRklFUixcbiAgICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChub25jZXNLZXlWYWxzLmxlbmd0aCwgMSk7XG4gICAgICAgIGNvbnN0IHVzZXJOb25jZUtleSA9IG5vbmNlc0tleVZhbHNbMF0ua2V5LmtleWRhdGE7XG4gICAgICAgIGNvbnN0IHVzZXJOb25jZVZhbHVlID0gbm9uY2VzS2V5VmFsc1swXS52YWx1ZTtcblxuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG5cbiAgICAgICAgbm9uY2VzS2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgICBpZGVudGlmaWVyOiBQU0JUX1BST1BSSUVUQVJZX0lERU5USUZJRVIsXG4gICAgICAgICAgc3VidHlwZTogUHJvcHJpZXRhcnlLZXlTdWJ0eXBlLk1VU0lHMl9QVUJfTk9OQ0UsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwobm9uY2VzS2V5VmFscy5sZW5ndGgsIDIpO1xuXG4gICAgICAgIG5vbmNlc0tleVZhbHMgPSBub25jZXNLZXlWYWxzLmZpbHRlcigoa3YpID0+IGt2LmtleS5rZXlkYXRhLmVxdWFscyh1c2VyTm9uY2VLZXkpKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG5vbmNlc0tleVZhbHMubGVuZ3RoLCAxKTtcbiAgICAgICAgYXNzZXJ0Lm9rKCFub25jZXNLZXlWYWxzWzBdLnZhbHVlLmVxdWFscyh1c2VyTm9uY2VWYWx1ZSkpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBDb3NpZ25lciBub25jZSBjcmVhdGlvbiBmYWlsIHNob3VsZCBub3QgZW5mb3JjZSB0aGUgc2lnbmVyIHRvIHJlY3JlYXRlIG5vbmNlYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcblxuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG5cbiAgICAgICAgY29uc3QgdGFwQmlwMzJEZXJpdmF0aW9uID0gcHNidC5kYXRhLmlucHV0c1swXS50YXBCaXAzMkRlcml2YXRpb247XG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwQmlwMzJEZXJpdmF0aW9uID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT4gcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICd0YXBCaXAzMkRlcml2YXRpb24gaXMgcmVxdWlyZWQgdG8gY3JlYXRlIG5vbmNlJ1xuICAgICAgICApO1xuXG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwQmlwMzJEZXJpdmF0aW9uID0gdGFwQmlwMzJEZXJpdmF0aW9uO1xuXG4gICAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG5cbiAgICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcblxuICAgICAgICBjb25zdCBub25jZXNLZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCwge1xuICAgICAgICAgIGlkZW50aWZpZXI6IFBTQlRfUFJPUFJJRVRBUllfSURFTlRJRklFUixcbiAgICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChub25jZXNLZXlWYWxzLmxlbmd0aCwgMik7XG5cbiAgICAgICAgY29uc3QgcGFydGlhbFNpZ0tleVZhbHMgPSBwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwLCB7XG4gICAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICAgIHN1YnR5cGU6IFByb3ByaWV0YXJ5S2V5U3VidHlwZS5NVVNJRzJfUEFSVElBTF9TSUcsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFydGlhbFNpZ0tleVZhbHMubGVuZ3RoLCAyKTtcblxuICAgICAgICBjb25zdCBwYXJ0aWNpcGFudEtleVZhbHMgPSBwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwLCB7XG4gICAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICAgIHN1YnR5cGU6IFByb3ByaWV0YXJ5S2V5U3VidHlwZS5NVVNJRzJfUEFSVElDSVBBTlRfUFVCX0tFWVMsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFydGljaXBhbnRLZXlWYWxzLmxlbmd0aCwgMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ0Nvc2lnbmVyIGNhbiBjcmVhdGUgYSBkZXRlcm1pbmlzdGljIG5vbmNlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28sIHsgZGV0ZXJtaW5pc3RpYzogdHJ1ZSB9KTtcblxuICAgICAgICBjb25zdCBub25jZXNLZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCwge1xuICAgICAgICAgIGlkZW50aWZpZXI6IFBTQlRfUFJPUFJJRVRBUllfSURFTlRJRklFUixcbiAgICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChub25jZXNLZXlWYWxzLmxlbmd0aCwgMik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ0Nvc2lnbmVyIGNhbm5vdCBjcmVhdGUgYSBkZXRlcm1pbmlzdGljIG5vbmNlIGlmIHRoZXJlIGlzIG5vIHNpZ25lciBub25jZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG5cbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28sIHsgZGV0ZXJtaW5pc3RpYzogdHJ1ZSB9KSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdObyBub25jZXMgZm91bmQgb24gaW5wdXQgIzAnXG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IG5vbmNlc0tleVZhbHMgPSBwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwLCB7XG4gICAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICAgIHN1YnR5cGU6IFByb3ByaWV0YXJ5S2V5U3VidHlwZS5NVVNJRzJfUFVCX05PTkNFLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG5vbmNlc0tleVZhbHMubGVuZ3RoLCAwKTtcblxuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbywgeyBkZXRlcm1pbmlzdGljOiB0cnVlIH0pLFxuICAgICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ3NpZ25lciBub25jZSBtdXN0IGJlIHNldCBpZiBjb3NpZ25lciBub25jZSBpcyB0byBiZSBkZXJpdmVkIGRldGVybWluaXN0aWNhbGx5J1xuICAgICAgICApO1xuXG4gICAgICAgIG5vbmNlc0tleVZhbHMgPSBwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwLCB7XG4gICAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICAgIHN1YnR5cGU6IFByb3ByaWV0YXJ5S2V5U3VidHlwZS5NVVNJRzJfUFVCX05PTkNFLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG5vbmNlc0tleVZhbHMubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnQ29zaWduZXIgY2Fubm90IGFkZCBlbnRyb3B5IHRvIGRldGVybWluaXN0aWMgbm9uY2UgY3JlYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbywge1xuICAgICAgICAgICAgICBkZXRlcm1pbmlzdGljOiB0cnVlLFxuICAgICAgICAgICAgICBzZXNzaW9uSWQ6IEJ1ZmZlci5hbGxvY1Vuc2FmZSgzMiksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdDYW5ub3QgYWRkIGV4dHJhIGVudHJvcHkgd2hlbiBnZW5lcmF0aW5nIGEgZGV0ZXJtaW5pc3RpYyBub25jZSdcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgbm9uY2VzS2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgICBpZGVudGlmaWVyOiBQU0JUX1BST1BSSUVUQVJZX0lERU5USUZJRVIsXG4gICAgICAgICAgc3VidHlwZTogUHJvcHJpZXRhcnlLZXlTdWJ0eXBlLk1VU0lHMl9QVUJfTk9OQ0UsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwobm9uY2VzS2V5VmFscy5sZW5ndGgsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdTaWduZXIgY2Fubm90IGNyZWF0ZSBhIGRldGVybWluaXN0aWMgbm9uY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyLCB7IGRldGVybWluaXN0aWM6IHRydWUgfSksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgT25seSB0aGUgY29zaWduZXIncyBub25jZSBjYW4gYmUgc2V0IGRldGVybWluaXN0aWNhbGx5YFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBub25jZXNLZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCwge1xuICAgICAgICAgIGlkZW50aWZpZXI6IFBTQlRfUFJPUFJJRVRBUllfSURFTlRJRklFUixcbiAgICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChub25jZXNLZXlWYWxzLmxlbmd0aCwgMCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNraXBwZWQgaWYgdGFwSW50ZXJuYWxLZXkgZG9lc24ndCBtYXRjaCBwYXJ0aWNpcGFudCBwdWIga2V5cyBhZ2dgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnRhcEludGVybmFsS2V5ID0gZHVtbXlUYXBJbnRlcm5hbEtleTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAndGFwSW50ZXJuYWxLZXkgYW5kIGFnZ3JlZ2F0ZWQgcGFydGljaXBhbnQgcHViIGtleXMgZG9lcyBub3QgbWF0Y2gnXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBmYWlscyBpZiBzZXNzaW9uSWQgc2l6ZSBpcyBpbnZhbGlkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciwgeyBzZXNzaW9uSWQ6IEJ1ZmZlci5hbGxvY1Vuc2FmZSgzMykgfSksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCBzZXNzaW9uSWQgc2l6ZSAzMydcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYGZhaWxzIGlmIHByaXZhdGUga2V5IGlzIG1pc3NpbmdgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyLm5ldXRlcmVkKCkpLFxuICAgICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ3ByaXZhdGUga2V5IGlzIHJlcXVpcmVkIHRvIGdlbmVyYXRlIG5vbmNlJ1xuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgdGFwQmlwMzJEZXJpdmF0aW9uIGlzIG1pc3NpbmdgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnRhcEJpcDMyRGVyaXZhdGlvbiA9IFtdO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICd0YXBCaXAzMkRlcml2YXRpb24gaXMgcmVxdWlyZWQgdG8gY3JlYXRlIG5vbmNlJ1xuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgcGFydGljaXBhbnQgcHViIGtleXMgaXMgbWlzc2luZ2AsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udW5rbm93bktleVZhbHMgPSBbXTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRm91bmQgMCBtYXRjaGluZyBwYXJ0aWNpcGFudCBrZXkgdmFsdWUgaW5zdGVhZCBvZiAxJ1xuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAwKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgcGFydGljaXBhbnQgcHViIGtleXMga2V5ZGF0YSBzaXplIGlzIGludmFsaWRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBjb25zdCBrZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCk7XG4gICAgICAgIGtleVZhbHNbMF0ua2V5LmtleWRhdGEgPSBCdWZmZXIuY29uY2F0KFtrZXlWYWxzWzBdLmtleS5rZXlkYXRhLCBCdWZmZXIuZnJvbSgnZHVtbXknKV0pO1xuICAgICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnVua25vd25LZXlWYWxzID0gW107XG4gICAgICAgIHBzYnQuYWRkUHJvcHJpZXRhcnlLZXlWYWxUb0lucHV0KDAsIGtleVZhbHNbMF0pO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBJbnZhbGlkIGtleWRhdGEgc2l6ZSAke2tleVZhbHNbMF0ua2V5LmtleWRhdGEubGVuZ3RofSBmb3IgcGFydGljaXBhbnQgcHViIGtleXNgXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBmYWlscyBpZiBwYXJ0aWNpcGFudCBrZXlkYXRhIHRhcE91dHB1dEtleSBpbiBpbnZhbGlkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgY29uc3Qga2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApO1xuICAgICAgICBrZXlWYWxzWzBdLmtleS5rZXlkYXRhID0gQnVmZmVyLmNvbmNhdChbZHVtbXlUYXBPdXRwdXRLZXksIGtleVZhbHNbMF0ua2V5LmtleWRhdGEuc3ViYXJyYXkoMzIpXSk7XG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udW5rbm93bktleVZhbHMgPSBbXTtcbiAgICAgICAgcHNidC5hZGRQcm9wcmlldGFyeUtleVZhbFRvSW5wdXQoMCwga2V5VmFsc1swXSk7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT4gcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpLFxuICAgICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYEludmFsaWQgcGFydGljaXBhbnRzIGtleWRhdGEgdGFwT3V0cHV0S2V5YFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgcGFydGljaXBhbnQga2V5ZGF0YSB0YXBJbnRlcm5hbEtleSBpbiBpbnZhbGlkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgY29uc3Qga2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApO1xuICAgICAgICBrZXlWYWxzWzBdLmtleS5rZXlkYXRhID0gQnVmZmVyLmNvbmNhdChba2V5VmFsc1swXS5rZXkua2V5ZGF0YS5zdWJhcnJheSgwLCAzMiksIGR1bW15VGFwSW50ZXJuYWxLZXldKTtcbiAgICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscyA9IFtdO1xuICAgICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBrZXlWYWxzWzBdKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgSW52YWxpZCBwYXJ0aWNpcGFudHMga2V5ZGF0YSB0YXBJbnRlcm5hbEtleWBcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYGZhaWxzIGlmIHRhcEludGVybmFsS2V5IGFuZCBhZ2dyZWdhdGVkIHBhcnRpY2lwYW50IHB1YiBrZXlzIGRvbid0IG1hdGNoYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgY29uc3Qga2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldEtleXMgPSByb290V2FsbGV0S2V5cy5kZXJpdmVGb3JDaGFpbkFuZEluZGV4KGdldEludGVybmFsQ2hhaW5Db2RlKCdwMnRyTXVzaWcyJyksIDEpO1xuICAgICAgICBjb25zdCB0YXBJbnRlcm5hbEtleSA9IGNyZWF0ZVRhcEludGVybmFsS2V5KFt3YWxsZXRLZXlzLnVzZXIucHVibGljS2V5LCB3YWxsZXRLZXlzLmJpdGdvLnB1YmxpY0tleV0pO1xuICAgICAgICBjb25zdCB0YXBPdXRwdXRLZXkgPSBjcmVhdGVUYXBPdXRwdXRLZXkodGFwSW50ZXJuYWxLZXksIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwTWVya2xlUm9vdCEpO1xuXG4gICAgICAgIGtleVZhbHNbMF0ua2V5LmtleWRhdGEgPSBCdWZmZXIuY29uY2F0KFt0YXBPdXRwdXRLZXksIHRhcEludGVybmFsS2V5XSk7XG4gICAgICAgIGtleVZhbHNbMF0udmFsdWUgPSBCdWZmZXIuY29uY2F0KFt3YWxsZXRLZXlzLnVzZXIucHVibGljS2V5LCB3YWxsZXRLZXlzLmJpdGdvLnB1YmxpY0tleV0pO1xuXG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udW5rbm93bktleVZhbHMgPSBbXTtcbiAgICAgICAgcHNidC5hZGRQcm9wcmlldGFyeUtleVZhbFRvSW5wdXQoMCwga2V5VmFsc1swXSk7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT4gcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpLFxuICAgICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYHRhcEludGVybmFsS2V5IGFuZCBhZ2dyZWdhdGVkIHBhcnRpY2lwYW50IHB1YiBrZXlzIGRvZXMgbm90IG1hdGNoYFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYga2V5ZGF0YSBzaXplIG9mIHBhcnRpY2lwYW50IHB1YiBrZXlzIGlzIGludmFsaWRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBjb25zdCBrZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCk7XG4gICAgICAgIGtleVZhbHNbMF0ua2V5LmtleWRhdGEgPSBCdWZmZXIuYWxsb2NVbnNhZmUoNjUpO1xuICAgICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnVua25vd25LZXlWYWxzID0gW107XG4gICAgICAgIHBzYnQuYWRkUHJvcHJpZXRhcnlLZXlWYWxUb0lucHV0KDAsIGtleVZhbHNbMF0pO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBJbnZhbGlkIGtleWRhdGEgc2l6ZSA2NSBmb3IgcGFydGljaXBhbnQgcHViIGtleXNgXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBmYWlscyBpZiB2YWx1ZWRhdGEgc2l6ZSBvZiBwYXJ0aWNpcGFudCBwdWIga2V5cyBpcyBpbnZhbGlkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgY29uc3Qga2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApO1xuICAgICAgICBrZXlWYWxzWzBdLnZhbHVlID0gQnVmZmVyLmFsbG9jVW5zYWZlKDY3KTtcbiAgICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscyA9IFtdO1xuICAgICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBrZXlWYWxzWzBdKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgSW52YWxpZCB2YWx1ZWRhdGEgc2l6ZSA2NyBmb3IgcGFydGljaXBhbnQgcHViIGtleXNgXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBmYWlscyBpZiBkdXBsaWNhdGUgcGFydGljaXBhbnQgcHViIGtleXMgZm91bmRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBjb25zdCBrZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCk7XG4gICAgICAgIGtleVZhbHNbMF0udmFsdWUgPSBCdWZmZXIuY29uY2F0KFtrZXlWYWxzWzBdLnZhbHVlLnN1YmFycmF5KDMzKSwga2V5VmFsc1swXS52YWx1ZS5zdWJhcnJheSgzMyldKTtcbiAgICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscyA9IFtdO1xuICAgICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBrZXlWYWxzWzBdKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgRHVwbGljYXRlIHBhcnRpY2lwYW50IHB1YiBrZXlzIGZvdW5kYFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgbm8gZmluZ2VycHJpbnQgbWF0Y2hgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnRhcEJpcDMyRGVyaXZhdGlvbj8uZm9yRWFjaCgoYnYpID0+IChidi5tYXN0ZXJGaW5nZXJwcmludCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSg0KSkpO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdObyBiaXAzMkRlcml2YXRpb24gbWFzdGVyRmluZ2VycHJpbnQgbWF0Y2hlZCB0aGUgSEQga2V5UGFpciBmaW5nZXJwcmludCdcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYGZhaWxzIGlmIHB1YmtleSBkaWQgbm90IG1hdGNoIHRhcEJpcDMyRGVyaXZhdGlvbmAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG4gICAgICAgIGNvbnN0IHdhbGxldEtleXMgPSByb290V2FsbGV0S2V5cy5kZXJpdmVGb3JDaGFpbkFuZEluZGV4KGdldEludGVybmFsQ2hhaW5Db2RlKCdwMnRyTXVzaWcyJyksIENIQU5HRV9JTkRFWCk7XG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwQmlwMzJEZXJpdmF0aW9uPy5mb3JFYWNoKChidikgPT4ge1xuICAgICAgICAgIGJ2LnBhdGggPSB3YWxsZXRLZXlzLnBhdGhzWzJdO1xuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAncHVia2V5IGRpZCBub3QgbWF0Y2ggYmlwMzJEZXJpdmF0aW9uJ1xuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgcm9vdCB3YWxsZXQga2V5IGRlcml2ZSBtb3JlIHRoYW4gb25lIHRhcEJpcDMyRGVyaXZhdGlvbmAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG4gICAgICAgIGNvbnN0IHdhbGxldEtleXMgPSByb290V2FsbGV0S2V5cy5kZXJpdmVGb3JDaGFpbkFuZEluZGV4KFxuICAgICAgICAgIHAydHJNdXNpZzJVbnNwZW50WzBdLmNoYWluLFxuICAgICAgICAgIHAydHJNdXNpZzJVbnNwZW50WzBdLmluZGV4XG4gICAgICAgICk7XG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwQmlwMzJEZXJpdmF0aW9uPy5mb3JFYWNoKChidiwgaW5kZXgpID0+IHtcbiAgICAgICAgICBidi5wYXRoID0gd2FsbGV0S2V5cy5wYXRoc1swXTtcbiAgICAgICAgICBidi5wdWJrZXkgPSB0b1hPbmx5UHVibGljS2V5KHdhbGxldEtleXMucHVibGljS2V5c1swXSk7XG4gICAgICAgICAgYnYubWFzdGVyRmluZ2VycHJpbnQgPSByb290V2FsbGV0S2V5cy51c2VyLmZpbmdlcnByaW50O1xuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlLnN0YXJ0c1dpdGgoJ21vcmUgdGhhbiBvbmUgbWF0Y2hpbmcgZGVyaXZhdGlvbiBmb3IgZmluZ2VycHJpbnQnKVxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgZmFpbHMgaWYgZGVyaXZlZCB3YWxsZXQga2V5IGRvZXMgbm90IG1hdGNoIGFueSBwYXJ0aWNpcGFudCBrZXlgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBjb25zdCBrZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0S2V5cyA9IHJvb3RXYWxsZXRLZXlzLmRlcml2ZUZvckNoYWluQW5kSW5kZXgoZ2V0SW50ZXJuYWxDaGFpbkNvZGUoJ3AydHJNdXNpZzInKSwgMSk7XG4gICAgICAgIGNvbnN0IHRhcEludGVybmFsS2V5ID0gY3JlYXRlVGFwSW50ZXJuYWxLZXkoW3dhbGxldEtleXMudXNlci5wdWJsaWNLZXksIHdhbGxldEtleXMuYml0Z28ucHVibGljS2V5XSk7XG4gICAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwSW50ZXJuYWxLZXkgPSB0YXBJbnRlcm5hbEtleTtcblxuICAgICAgICBrZXlWYWxzWzBdLnZhbHVlID0gQnVmZmVyLmNvbmNhdChbd2FsbGV0S2V5cy51c2VyLnB1YmxpY0tleSwgd2FsbGV0S2V5cy5iaXRnby5wdWJsaWNLZXldKTtcbiAgICAgICAgY29uc3QgdGFwT3V0cHV0S2V5ID0gY3JlYXRlVGFwT3V0cHV0S2V5KHRhcEludGVybmFsS2V5LCBwc2J0LmRhdGEuaW5wdXRzWzBdLnRhcE1lcmtsZVJvb3QhKTtcbiAgICAgICAga2V5VmFsc1swXS5rZXkua2V5ZGF0YSA9IEJ1ZmZlci5jb25jYXQoW3RhcE91dHB1dEtleSwgdGFwSW50ZXJuYWxLZXldKTtcbiAgICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscyA9IFtdO1xuICAgICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBrZXlWYWxzWzBdKTtcblxuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+IHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBwYXJ0aWNpcGFudCBwbGFpbiBwdWIga2V5IHNob3VsZCBtYXRjaCBvbmUgYmlwMzJEZXJpdmF0aW9uIHBsYWluIHB1YiBrZXlgXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDEpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2lnbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KGBmYWlscyBpZiBwcml2YXRlS2V5IGlzIG1pc3NpbmdgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT4gcHNidC5zaWduVGFwcm9vdElucHV0SEQoMCwgcm9vdFdhbGxldEtleXMudXNlci5uZXV0ZXJlZCgpKSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdwcml2YXRlS2V5IGlzIHJlcXVpcmVkIHRvIHNpZ24gcDJ0ciBtdXNpZzInXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDMpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KGBmYWlscyBpZiB0YXBJbnRlcm5hbEtleSBpcyBtaXNzaW5nYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcblxuICAgICAgICBjb25zdCB3YWxsZXRLZXlzID0gcm9vdFdhbGxldEtleXMuZGVyaXZlRm9yQ2hhaW5BbmRJbmRleChcbiAgICAgICAgICBwMnRyTXVzaWcyVW5zcGVudFswXS5jaGFpbixcbiAgICAgICAgICBwMnRyTXVzaWcyVW5zcGVudFswXS5pbmRleFxuICAgICAgICApO1xuXG4gICAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcblxuICAgICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnRhcEludGVybmFsS2V5ID0gdW5kZWZpbmVkO1xuICAgICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAgICgpID0+XG4gICAgICAgICAgICBwc2J0LnNpZ25UYXByb290TXVzaWcySW5wdXQoMCwge1xuICAgICAgICAgICAgICBwdWJsaWNLZXk6IHdhbGxldEtleXMudXNlci5wdWJsaWNLZXksXG4gICAgICAgICAgICAgIHByaXZhdGVLZXk6IHdhbGxldEtleXMudXNlci5wcml2YXRlS2V5ISxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ25vdCBhIHRhcHJvb3QgbXVzaWcyIGlucHV0J1xuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAzKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnb25seSB0aGUgY29zaWduZXIgY2FuIGFkZCBhIGRldGVybWluaXN0aWMgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28sIHsgZGV0ZXJtaW5pc3RpYzogdHJ1ZSB9KTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PiBwc2J0LnNpZ25JbnB1dEhEKDAsIHJvb3RXYWxsZXRLZXlzLnVzZXIsIHsgZGV0ZXJtaW5pc3RpYzogdHJ1ZSB9KSxcbiAgICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdjYW4gb25seSBhZGQgYSBkZXRlcm1pbmlzdGljIHNpZ25hdHVyZSBvbiB0aGUgY29zaWduZXInXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2Nvc2lnbmVyIGNhbiBzaWduIGRldGVybWluaXN0aWNhbGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28sIHsgZGV0ZXJtaW5pc3RpYzogdHJ1ZSB9KTtcbiAgICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLmJpdGdvLCB7IGRldGVybWluaXN0aWM6IHRydWUgfSk7XG4gICAgICAgIGFzc2VydC5vayhwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mQWxsSW5wdXRzKCkpO1xuICAgICAgICBhc3NlcnQub2socHNidC5maW5hbGl6ZUFsbElucHV0cygpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY29zaWduZXIgY2FuIHNpZ24gbm9uLWRldGVybWluaXN0aWNhbGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28sIHsgZGV0ZXJtaW5pc3RpYzogZmFsc2UgfSk7XG4gICAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy5iaXRnbywgeyBkZXRlcm1pbmlzdGljOiBmYWxzZSB9KTtcbiAgICAgICAgYXNzZXJ0Lm9rKHBzYnQudmFsaWRhdGVTaWduYXR1cmVzT2ZBbGxJbnB1dHMoKSk7XG4gICAgICAgIGFzc2VydC5vayhwc2J0LmZpbmFsaXplQWxsSW5wdXRzKCkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgdGFwTWVya2xlUm9vdCBpcyBtaXNzaW5nYCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG5cbiAgICAgIGNvbnN0IHdhbGxldEtleXMgPSByb290V2FsbGV0S2V5cy5kZXJpdmVGb3JDaGFpbkFuZEluZGV4KHAydHJNdXNpZzJVbnNwZW50WzBdLmNoYWluLCBwMnRyTXVzaWcyVW5zcGVudFswXS5pbmRleCk7XG5cbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG5cbiAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udGFwTWVya2xlUm9vdCA9IHVuZGVmaW5lZDtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+XG4gICAgICAgICAgcHNidC5zaWduVGFwcm9vdE11c2lnMklucHV0KDAsIHtcbiAgICAgICAgICAgIHB1YmxpY0tleTogd2FsbGV0S2V5cy51c2VyLnB1YmxpY0tleSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHdhbGxldEtleXMudXNlci5wcml2YXRlS2V5ISxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnbm90IGEgdGFwcm9vdCBtdXNpZzIgaW5wdXQnXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMyk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgcGFydGljaXBhbnQgcHViIGtleXMgaXMgbWlzc2luZ2AsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udW5rbm93bktleVZhbHMgPSBbXTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBzYnQuc2lnblRhcHJvb3RJbnB1dEhEKDAsIHJvb3RXYWxsZXRLZXlzLnVzZXIpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdGb3VuZCAwIG1hdGNoaW5nIHBhcnRpY2lwYW50IGtleSB2YWx1ZSBpbnN0ZWFkIG9mIDEnXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMCk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgc2lnbmVyIHB1YiBrZXkgaXMgbm90IG1hdGNoaW5nIGFueSBwYXJ0aWNpcGFudCBwdWIga2V5c2AsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+XG4gICAgICAgICAgcHNidC5zaWduVGFwcm9vdE11c2lnMklucHV0KDAsIHtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IHJvb3RXYWxsZXRLZXlzLmJhY2t1cC5wcml2YXRlS2V5ISxcbiAgICAgICAgICAgIHB1YmxpY0tleTogcm9vdFdhbGxldEtleXMuYmFja3VwLnB1YmxpY0tleSEsXG4gICAgICAgICAgfSksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ3NpZ25lciBwdWIga2V5IHNob3VsZCBtYXRjaCBvbmUgb2YgcGFydGljaXBhbnQgcHViIGtleXMnXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMyk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgbW9yZSB0aGFuIDIgbm9uY2Uga2V5IHZhbHVlIGV4aXN0c2AsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0udW5rbm93bktleVZhbHM/LnB1c2gocHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFsc1syXSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwc2J0LnNpZ25UYXByb290SW5wdXRIRCgwLCByb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRm91bmQgMyBtYXRjaGluZyBub25jZSBrZXkgdmFsdWUgaW5zdGVhZCBvZiAxIG9yIDInXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgNCk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgMiBub25jZSBrZXkgdmFsdWUgZG8gbm90IGV4aXN0YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscz8uc3BsaWNlKDIpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gcHNidC5zaWduVGFwcm9vdElucHV0SEQoMCwgcm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gJ0ZvdW5kIDEgbWF0Y2hpbmcgbm9uY2Uga2V5IHZhbHVlIGluc3RlYWQgb2YgMidcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAyKTtcbiAgICB9KTtcblxuICAgIGl0KGBmYWlscyBpZiBub25jZSBrZXlkYXRhIHNpemUgaXMgaW52YWxpZGAsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcblxuICAgICAgY29uc3Qga2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgIH0pO1xuICAgICAga2V5VmFsc1sxXS5rZXkua2V5ZGF0YSA9IEJ1ZmZlci5jb25jYXQoW2tleVZhbHNbMV0ua2V5LmtleWRhdGEsIEJ1ZmZlci5mcm9tKCdkdW1teScpXSk7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnVua25vd25LZXlWYWxzPy5zcGxpY2UoMik7XG4gICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBrZXlWYWxzWzFdKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBzYnQuc2lnblRhcHJvb3RJbnB1dEhEKDAsIHJvb3RXYWxsZXRLZXlzLnVzZXIpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBJbnZhbGlkIGtleWRhdGEgc2l6ZSAke2tleVZhbHNbMV0ua2V5LmtleWRhdGEubGVuZ3RofSBmb3Igbm9uY2VgXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMyk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgbm9uY2UgdmFsdWVkYXRhIHNpemUgaXMgaW52YWxpZGAsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCAncDJzaCcpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcblxuICAgICAgY29uc3Qga2V5VmFscyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgIH0pO1xuICAgICAga2V5VmFsc1sxXS52YWx1ZSA9IEJ1ZmZlci5jb25jYXQoW2tleVZhbHNbMV0udmFsdWUsIEJ1ZmZlci5mcm9tKCdkdW1teScpXSk7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnVua25vd25LZXlWYWxzPy5zcGxpY2UoMik7XG4gICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBrZXlWYWxzWzFdKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBzYnQuc2lnblRhcHJvb3RJbnB1dEhEKDAsIHJvb3RXYWxsZXRLZXlzLnVzZXIpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBJbnZhbGlkIHZhbHVlZGF0YSBzaXplICR7a2V5VmFsc1sxXS52YWx1ZS5sZW5ndGh9IGZvciBub25jZWBcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAzKTtcbiAgICB9KTtcblxuICAgIGl0KGBmYWlscyBpZiBub25jZSBrZXlkYXRhIGlzIGludmFsaWRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG5cbiAgICAgIGNvbnN0IGR1bW15Um9vdFdhbGxldEtleXMgPSBuZXcgUm9vdFdhbGxldEtleXMoZ2V0S2V5VHJpcGxlKCdkdW1teScpKTtcbiAgICAgIGNvbnN0IGR1bW15UDJ0ck11c2lnMlVuc3BlbnQgPSBnZXRVbnNwZW50cyhbJ3AydHJNdXNpZzInXSwgZHVtbXlSb290V2FsbGV0S2V5cyk7XG4gICAgICBjb25zdCBkdW1teVBzYnQgPSBjb25zdHJ1Y3RQc2J0KGR1bW15UDJ0ck11c2lnMlVuc3BlbnQsIGR1bW15Um9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgJ3Ayc2gnKTtcbiAgICAgIGR1bW15UHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKGR1bW15Um9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBkdW1teVBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChkdW1teVJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcblxuICAgICAgY29uc3QgZHVtbXlLZXlWYWxzID0gZHVtbXlQc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwLCB7XG4gICAgICAgIGlkZW50aWZpZXI6IFBTQlRfUFJPUFJJRVRBUllfSURFTlRJRklFUixcbiAgICAgICAgc3VidHlwZTogUHJvcHJpZXRhcnlLZXlTdWJ0eXBlLk1VU0lHMl9QVUJfTk9OQ0UsXG4gICAgICB9KTtcblxuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscz8uc3BsaWNlKDEpO1xuICAgICAgZHVtbXlLZXlWYWxzLmZvckVhY2goKGt2LCBpKSA9PiBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBkdW1teUtleVZhbHNbaV0pKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBzYnQuc2lnblRhcHJvb3RJbnB1dEhEKDAsIHJvb3RXYWxsZXRLZXlzLnVzZXIpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBJbnZhbGlkIG5vbmNlIGtleWRhdGEgcGFydGljaXBhbnQgcHViIGtleWBcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAzKTtcbiAgICB9KTtcblxuICAgIGl0KGBmYWlscyBpZiBub25jZSBrZXlkYXRhIHRhcE91dHB1dEtleSBpcyBpbnZhbGlkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsICdwMnNoJyk7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuXG4gICAgICBjb25zdCBrZXlWYWxzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCwge1xuICAgICAgICBpZGVudGlmaWVyOiBQU0JUX1BST1BSSUVUQVJZX0lERU5USUZJRVIsXG4gICAgICAgIHN1YnR5cGU6IFByb3ByaWV0YXJ5S2V5U3VidHlwZS5NVVNJRzJfUFVCX05PTkNFLFxuICAgICAgfSk7XG5cbiAgICAgIGtleVZhbHNbMV0ua2V5LmtleWRhdGEgPSBCdWZmZXIuY29uY2F0KFtrZXlWYWxzWzFdLmtleS5rZXlkYXRhLnN1YmFycmF5KDAsIDMzKSwgZHVtbXlUYXBPdXRwdXRLZXldKTtcblxuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS51bmtub3duS2V5VmFscz8uc3BsaWNlKDIpO1xuICAgICAgcHNidC5hZGRQcm9wcmlldGFyeUtleVZhbFRvSW5wdXQoMCwga2V5VmFsc1sxXSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwc2J0LnNpZ25UYXByb290SW5wdXRIRCgwLCByb290V2FsbGV0S2V5cy51c2VyKSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgSW52YWxpZCBub25jZSBrZXlkYXRhIHRhcE91dHB1dEtleWBcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCkubGVuZ3RoLCAzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3AydHJNdXNpZzIgc2NyaXB0IHBhdGgnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoYHBzYnQgY3JlYXRpb24gc3VjY2VzcyBhbmQgbXVzaWcyIHNraXBzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgbGV0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYmFja3VwJywgb3V0cHV0VHlwZSk7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYmFja3VwKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwc2J0LmdldFByb3ByaWV0YXJ5S2V5VmFscygwKS5sZW5ndGgsIDApO1xuICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy5iYWNrdXApO1xuICAgICAgdmFsaWRhdGVQc2J0UDJ0ck11c2lnMklucHV0KHBzYnQsIDAsIHAydHJNdXNpZzJVbnNwZW50WzBdLCAnc2NyaXB0UGF0aCcpO1xuICAgICAgdmFsaWRhdGVQc2J0UDJ0ck11c2lnMk91dHB1dChwc2J0LCAwKTtcbiAgICAgIGFzc2VydC5vayhwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mQWxsSW5wdXRzKCkpO1xuICAgICAgcHNidC5maW5hbGl6ZUFsbElucHV0cygpO1xuICAgICAgdmFsaWRhdGVGaW5hbGl6ZWRJbnB1dChwc2J0LCAwLCBwMnRyTXVzaWcyVW5zcGVudFswXSwgJ3NjcmlwdFBhdGgnKTtcbiAgICAgIGxldCB0eCA9IHBzYnQuZXh0cmFjdFRyYW5zYWN0aW9uKCkgYXMgVXR4b1RyYW5zYWN0aW9uPGJpZ2ludD47XG4gICAgICBhc3NlcnQub2sodmVyaWZ5RnVsbHlTaWduZWRTaWduYXR1cmVzKHR4LCBwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JhY2t1cCcpKTtcblxuICAgICAgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAnYml0Z28nLCAnYmFja3VwJywgb3V0cHV0VHlwZSk7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJhY2t1cCk7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy5iYWNrdXApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApLmxlbmd0aCwgMCk7XG4gICAgICB2YWxpZGF0ZVBzYnRQMnRyTXVzaWcySW5wdXQocHNidCwgMCwgcDJ0ck11c2lnMlVuc3BlbnRbMF0sICdzY3JpcHRQYXRoJyk7XG4gICAgICB2YWxpZGF0ZVBzYnRQMnRyTXVzaWcyT3V0cHV0KHBzYnQsIDApO1xuICAgICAgYXNzZXJ0Lm9rKHBzYnQudmFsaWRhdGVTaWduYXR1cmVzT2ZBbGxJbnB1dHMoKSk7XG4gICAgICBwc2J0LmZpbmFsaXplQWxsSW5wdXRzKCk7XG4gICAgICB2YWxpZGF0ZUZpbmFsaXplZElucHV0KHBzYnQsIDAsIHAydHJNdXNpZzJVbnNwZW50WzBdLCAnc2NyaXB0UGF0aCcpO1xuICAgICAgdHggPSBwc2J0LmV4dHJhY3RUcmFuc2FjdGlvbigpIGFzIFV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+O1xuICAgICAgYXNzZXJ0Lm9rKHZlcmlmeUZ1bGx5U2lnbmVkU2lnbmF0dXJlcyh0eCwgcDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAnYml0Z28nLCAnYmFja3VwJykpO1xuICAgIH0pO1xuXG4gICAgaXQoYHBhcnNlIHR4YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiYWNrdXAnLCBvdXRwdXRUeXBlKTtcbiAgICAgIHZhbGlkYXRlUGFyc2VkVGFwcm9vdFNjcmlwdFBhdGhQc2J0KHBzYnQsIDAsICd1bnNpZ25lZCcpO1xuXG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHZhbGlkYXRlUGFyc2VkVGFwcm9vdFNjcmlwdFBhdGhQc2J0KHBzYnQsIDAsICdoYWxmc2lnbmVkJyk7XG5cbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLmJhY2t1cCk7XG4gICAgICB2YWxpZGF0ZVBhcnNlZFRhcHJvb3RTY3JpcHRQYXRoUHNidChwc2J0LCAwLCAnZnVsbHlzaWduZWQnKTtcblxuICAgICAgcHNidC5maW5hbGl6ZUFsbElucHV0cygpO1xuICAgICAgY29uc3QgdHggPSBwc2J0LmV4dHJhY3RUcmFuc2FjdGlvbigpIGFzIFV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+O1xuXG4gICAgICBjb25zdCBwc2J0RHVwbGljYXRlID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JhY2t1cCcsIG91dHB1dFR5cGUpO1xuICAgICAgdmFsaWRhdGVQYXJzZWRUYXByb290U2NyaXB0UGF0aFR4SW5wdXQocHNidER1cGxpY2F0ZSwgdHgsIDApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmFsaWRhdGUgcDJ0ciBNdXNpZzIgc2lnbmF0dXJlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdChgdmFsaWRhdGUgd2l0aCBwdWJrZXlgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRLZXlzID0gcm9vdFdhbGxldEtleXMuZGVyaXZlRm9yQ2hhaW5BbmRJbmRleChwMnRyTXVzaWcyVW5zcGVudFswXS5jaGFpbiwgcDJ0ck11c2lnMlVuc3BlbnRbMF0uaW5kZXgpO1xuICAgICAgbGV0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCBvdXRwdXRUeXBlKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2Uod2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2Uod2FsbGV0S2V5cy5iaXRnbyk7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIGFzc2VydC5vayhwc2J0LnZhbGlkYXRlVGFwcm9vdE11c2lnMlNpZ25hdHVyZXNPZklucHV0KDAsIHdhbGxldEtleXMudXNlci5wdWJsaWNLZXkpKTtcblxuICAgICAgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsIG91dHB1dFR5cGUpO1xuICAgICAgcHNidC5zZXRJbnB1dE11c2lnMk5vbmNlKDAsIHdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNldElucHV0TXVzaWcyTm9uY2VIRCgwLCByb290V2FsbGV0S2V5cy5iaXRnbyk7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIGFzc2VydC5vayhwc2J0LnZhbGlkYXRlVGFwcm9vdE11c2lnMlNpZ25hdHVyZXNPZklucHV0KDAsIHdhbGxldEtleXMudXNlci5wdWJsaWNLZXkpKTtcbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIGFzc2VydC5vayhwc2J0LnZhbGlkYXRlVGFwcm9vdE11c2lnMlNpZ25hdHVyZXNPZklucHV0KDAsIHdhbGxldEtleXMuYml0Z28ucHVibGljS2V5KSk7XG4gICAgfSk7XG5cbiAgICBpdChgZmFpbHMgaWYgbm8gc2lnYCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0S2V5cyA9IHJvb3RXYWxsZXRLZXlzLmRlcml2ZUZvckNoYWluQW5kSW5kZXgocDJ0ck11c2lnMlVuc3BlbnRbMF0uY2hhaW4sIHAydHJNdXNpZzJVbnNwZW50WzBdLmluZGV4KTtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCBvdXRwdXRUeXBlKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBzYnQudmFsaWRhdGVTaWduYXR1cmVzT2ZBbGxJbnB1dHMoKSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgTm8gc2lnbmF0dXJlcyB0byB2YWxpZGF0ZWBcbiAgICAgICk7XG5cbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG5cbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwc2J0LnZhbGlkYXRlVGFwcm9vdE11c2lnMlNpZ25hdHVyZXNPZklucHV0KDAsIHdhbGxldEtleXMuYml0Z28ucHVibGljS2V5KSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgTm8gc2lnbmF0dXJlcyBmb3IgdGhpcyBwdWJrZXlgXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoYGZhaWxzIGlmIG5vIHRhcEludGVybmFsS2V5IGFuZCB0YXBNZXJrbGVSb290YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0S2V5cyA9IHJvb3RXYWxsZXRLZXlzLmRlcml2ZUZvckNoYWluQW5kSW5kZXgocDJ0ck11c2lnMlVuc3BlbnRbMF0uY2hhaW4sIHAydHJNdXNpZzJVbnNwZW50WzBdLmluZGV4KTtcbiAgICAgIGNvbnN0IHBzYnQgPSBjb25zdHJ1Y3RQc2J0KHAydHJNdXNpZzJVbnNwZW50LCByb290V2FsbGV0S2V5cywgJ3VzZXInLCAnYml0Z28nLCBvdXRwdXRUeXBlKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHBzYnQuc2V0QWxsSW5wdXRzTXVzaWcyTm9uY2VIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy51c2VyKTtcbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcblxuICAgICAgY29uc3QgdGFwSW50ZXJuYWxLZXkgPSBwc2J0LmRhdGEuaW5wdXRzWzBdLnRhcEludGVybmFsS2V5O1xuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS50YXBJbnRlcm5hbEtleSA9IHVuZGVmaW5lZDtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHBzYnQudmFsaWRhdGVUYXByb290TXVzaWcyU2lnbmF0dXJlc09mSW5wdXQoMCksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYGJvdGggdGFwSW50ZXJuYWxLZXkgYW5kIHRhcE1lcmtsZVJvb3QgYXJlIHJlcXVpcmVkYFxuICAgICAgKTtcblxuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS50YXBJbnRlcm5hbEtleSA9IHRhcEludGVybmFsS2V5O1xuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS50YXBNZXJrbGVSb290ID0gdW5kZWZpbmVkO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gcHNidC52YWxpZGF0ZVRhcHJvb3RNdXNpZzJTaWduYXR1cmVzT2ZJbnB1dCgwLCB3YWxsZXRLZXlzLmJpdGdvLnB1YmxpY0tleSksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYGJvdGggdGFwSW50ZXJuYWxLZXkgYW5kIHRhcE1lcmtsZVJvb3QgYXJlIHJlcXVpcmVkYFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGBmYWlscyBpZiBubyBub25jZSBhbmQgc2lnIHB1YiBrZXkgbWF0Y2hgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsIG91dHB1dFR5cGUpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuXG4gICAgICBjb25zdCBwYXJ0aWFsU2lncyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BBUlRJQUxfU0lHLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG15Um9vdFdhbGxldEtleXMgPSBuZXcgUm9vdFdhbGxldEtleXMoZ2V0S2V5VHJpcGxlKCdkdW1teScpKTtcbiAgICAgIGNvbnN0IG15VW5zcGVudHMgPSBnZXRVbnNwZW50cyhbJ3AydHJNdXNpZzInXSwgbXlSb290V2FsbGV0S2V5cyk7XG4gICAgICBwc2J0ID0gY29uc3RydWN0UHNidChteVVuc3BlbnRzLCBteVJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsIG91dHB1dFR5cGUpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKG15Um9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQobXlSb290V2FsbGV0S2V5cy5iaXRnbyk7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChteVJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQobXlSb290V2FsbGV0S2V5cy5iaXRnbyk7XG5cbiAgICAgIGNvbnN0IHBhcnRpY2lwYW50cyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BBUlRJQ0lQQU5UX1BVQl9LRVlTLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG5vbmNlcyA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDAsIHtcbiAgICAgICAgaWRlbnRpZmllcjogUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSLFxuICAgICAgICBzdWJ0eXBlOiBQcm9wcmlldGFyeUtleVN1YnR5cGUuTVVTSUcyX1BVQl9OT05DRSxcbiAgICAgIH0pO1xuXG4gICAgICBwc2J0LmRhdGEuaW5wdXRzWzBdLnVua25vd25LZXlWYWxzID0gdW5kZWZpbmVkO1xuICAgICAgcHNidC5hZGRQcm9wcmlldGFyeUtleVZhbFRvSW5wdXQoMCwgcGFydGljaXBhbnRzWzBdKTtcbiAgICAgIHBzYnQuYWRkUHJvcHJpZXRhcnlLZXlWYWxUb0lucHV0KDAsIG5vbmNlc1swXSk7XG4gICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCBub25jZXNbMV0pO1xuICAgICAgcHNidC5hZGRQcm9wcmlldGFyeUtleVZhbFRvSW5wdXQoMCwgcGFydGlhbFNpZ3NbMF0pO1xuICAgICAgcHNidC5hZGRQcm9wcmlldGFyeUtleVZhbFRvSW5wdXQoMCwgcGFydGlhbFNpZ3NbMV0pO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mQWxsSW5wdXRzKCksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYEZvdW5kIG5vIHB1YiBub25jZSBmb3IgcHVia2V5YFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGBmYWlscyBpZiBubyB2YWxpZCBzaWdgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChwMnRyTXVzaWcyVW5zcGVudCwgcm9vdFdhbGxldEtleXMsICd1c2VyJywgJ2JpdGdvJywgb3V0cHV0VHlwZSk7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQocm9vdFdhbGxldEtleXMuYml0Z28pO1xuICAgICAgcHNidC5zaWduQWxsSW5wdXRzSEQocm9vdFdhbGxldEtleXMudXNlcik7XG4gICAgICBwc2J0LnNpZ25BbGxJbnB1dHNIRChyb290V2FsbGV0S2V5cy5iaXRnbyk7XG5cbiAgICAgIGNvbnN0IHBhcnRpYWxTaWdzID0gcHNidC5nZXRQcm9wcmlldGFyeUtleVZhbHMoMCwge1xuICAgICAgICBpZGVudGlmaWVyOiBQU0JUX1BST1BSSUVUQVJZX0lERU5USUZJRVIsXG4gICAgICAgIHN1YnR5cGU6IFByb3ByaWV0YXJ5S2V5U3VidHlwZS5NVVNJRzJfUEFSVElBTF9TSUcsXG4gICAgICB9KTtcblxuICAgICAgcGFydGlhbFNpZ3NbMV0udmFsdWUgPSBkdW1teVBhcnRpYWxTaWc7XG4gICAgICBwc2J0LmFkZE9yVXBkYXRlUHJvcHJpZXRhcnlLZXlWYWxUb0lucHV0KDAsIHBhcnRpYWxTaWdzWzFdKTtcblxuICAgICAgYXNzZXJ0Lm9rKCFwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mQWxsSW5wdXRzKCkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZmluYWxpemVUYXByb290TXVzaWcySW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2ZhaWxzIGlmIGludmFsaWQgbnVtYmVyIGZvciBzaWdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsIG91dHB1dFR5cGUpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIHBzYnQuc2lnbkFsbElucHV0c0hEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBwc2J0LmZpbmFsaXplQWxsSW5wdXRzKCksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYGludmFsaWQgbnVtYmVyIG9mIHBhcnRpYWwgc2lnbmF0dXJlcyAxIHRvIGZpbmFsaXplYFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1BzYnQgbXVzaWcyIGNvbW1vbiBmdW5jdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ291dHB1dCBzY3JpcHQgc2hvdWxkIG1hdGNoIHRoZSBzY3JpcHRQdWJLZXkgaW4gdGhlIHByZXZvdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBteVJvb3RXYWxsZXRLZXlzID0gbmV3IFJvb3RXYWxsZXRLZXlzKGdldEtleVRyaXBsZSgnZHVtbXknKSk7XG4gICAgICBjb25zdCB1bnNwZW50cyA9IGdldFVuc3BlbnRzKFxuICAgICAgICBzY3JpcHRUeXBlczJPZjMubWFwKCh0KSA9PiB0KSxcbiAgICAgICAgbXlSb290V2FsbGV0S2V5c1xuICAgICAgKTtcblxuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQodW5zcGVudHMsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsIG91dHB1dFR5cGUpO1xuICAgICAgdW5zcGVudHMuZm9yRWFjaCgodSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3Qgc2NyaXB0VHlwZSA9IHNjcmlwdFR5cGVGb3JDaGFpbih1LmNoYWluKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgc2NyaXB0VHlwZSA9PT0gJ3AydHJNdXNpZzInXG4gICAgICAgICAgICAgID8gcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpXG4gICAgICAgICAgICAgIDogc2NyaXB0VHlwZSA9PT0gJ3AydHInXG4gICAgICAgICAgICAgID8gcHNidC5zaWduVGFwcm9vdElucHV0SEQoaW5kZXgsIHJvb3RXYWxsZXRLZXlzLnVzZXIpXG4gICAgICAgICAgICAgIDogcHNidC5zaWduSW5wdXRIRChpbmRleCwgcm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgICAgKGU6IGFueSkgPT5cbiAgICAgICAgICAgIGlzU2Vnd2l0KHUuY2hhaW4pICYmIHNjcmlwdFR5cGUgIT09ICdwMnNoUDJ3c2gnXG4gICAgICAgICAgICAgID8gZS5tZXNzYWdlID09PSBgV2l0bmVzcyBzY3JpcHQgZm9yIGlucHV0ICMke2luZGV4fSBkb2Vzbid0IG1hdGNoIHRoZSBzY3JpcHRQdWJLZXkgaW4gdGhlIHByZXZvdXRgXG4gICAgICAgICAgICAgIDogZS5tZXNzYWdlID09PSBgUmVkZWVtIHNjcmlwdCBmb3IgaW5wdXQgIyR7aW5kZXh9IGRvZXNuJ3QgbWF0Y2ggdGhlIHNjcmlwdFB1YktleSBpbiB0aGUgcHJldm91dGBcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwMnRyTXVzaWcyU2NyaXB0UGF0aFBzYnQgPSBjb25zdHJ1Y3RQc2J0KFt1bnNwZW50c1s0XV0sIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiYWNrdXAnLCBvdXRwdXRUeXBlKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHAydHJNdXNpZzJTY3JpcHRQYXRoUHNidC5zaWduVGFwcm9vdElucHV0SEQoMCwgcm9vdFdhbGxldEtleXMudXNlciksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYFdpdG5lc3Mgc2NyaXB0IGZvciBpbnB1dCAjMCBkb2Vzbid0IG1hdGNoIHRoZSBzY3JpcHRQdWJLZXkgaW4gdGhlIHByZXZvdXRgXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoYGRlY29kZVBzYnRNdXNpZzJQYXJ0aWNpcGFudHNLZXlWYWxEYXRhIGZhaWxzIGlmIGludmFsaWQgc3VidHlwZSBvciBpZGVudGlmaWVyIGlzIHBhc3NlZGAsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGt2ID0ge1xuICAgICAgICBrZXk6IHtcbiAgICAgICAgICBpZGVudGlmaWVyOiAnZHVtbXknLFxuICAgICAgICAgIHN1YnR5cGU6IDB4MDUsXG4gICAgICAgICAga2V5ZGF0YTogQnVmZmVyLmFsbG9jVW5zYWZlKDEpLFxuICAgICAgICB9LFxuICAgICAgICB2YWx1ZTogQnVmZmVyLmFsbG9jVW5zYWZlKDEpLFxuICAgICAgfTtcblxuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gZGVjb2RlUHNidE11c2lnMlBhcnRpY2lwYW50cyhrdiksXG4gICAgICAgIChlOiBhbnkpID0+XG4gICAgICAgICAgZS5tZXNzYWdlID09PSBgSW52YWxpZCBpZGVudGlmaWVyICR7a3Yua2V5LmlkZW50aWZpZXJ9IG9yIHN1YnR5cGUgJHtrdi5rZXkuc3VidHlwZX0gZm9yIHBhcnRpY2lwYW50cyBwdWIga2V5c2BcbiAgICAgICk7XG5cbiAgICAgIGt2LmtleS5pZGVudGlmaWVyID0gUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gZGVjb2RlUHNidE11c2lnMlBhcnRpY2lwYW50cyhrdiksXG4gICAgICAgIChlOiBhbnkpID0+XG4gICAgICAgICAgZS5tZXNzYWdlID09PSBgSW52YWxpZCBpZGVudGlmaWVyICR7a3Yua2V5LmlkZW50aWZpZXJ9IG9yIHN1YnR5cGUgJHtrdi5rZXkuc3VidHlwZX0gZm9yIHBhcnRpY2lwYW50cyBwdWIga2V5c2BcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChgZGVjb2RlUHNidE11c2lnMk5vbmNlS2V5VmFsRGF0YSBmYWlscyBpZiBpbnZhbGlkIHN1YnR5cGUgb3IgaWRlbnRpZmllciBpcyBwYXNzZWRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrdiA9IHtcbiAgICAgICAga2V5OiB7XG4gICAgICAgICAgaWRlbnRpZmllcjogJ2R1bW15JyxcbiAgICAgICAgICBzdWJ0eXBlOiAweDA1LFxuICAgICAgICAgIGtleWRhdGE6IEJ1ZmZlci5hbGxvY1Vuc2FmZSgxKSxcbiAgICAgICAgfSxcbiAgICAgICAgdmFsdWU6IEJ1ZmZlci5hbGxvY1Vuc2FmZSgxKSxcbiAgICAgIH07XG5cbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IGRlY29kZVBzYnRNdXNpZzJOb25jZShrdiksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYEludmFsaWQgaWRlbnRpZmllciAke2t2LmtleS5pZGVudGlmaWVyfSBvciBzdWJ0eXBlICR7a3Yua2V5LnN1YnR5cGV9IGZvciBub25jZWBcbiAgICAgICk7XG5cbiAgICAgIGt2LmtleS5pZGVudGlmaWVyID0gUFNCVF9QUk9QUklFVEFSWV9JREVOVElGSUVSO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gZGVjb2RlUHNidE11c2lnMk5vbmNlKGt2KSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgSW52YWxpZCBpZGVudGlmaWVyICR7a3Yua2V5LmlkZW50aWZpZXJ9IG9yIHN1YnR5cGUgJHtrdi5rZXkuc3VidHlwZX0gZm9yIG5vbmNlYFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGB2YWxpZGF0ZVBzYnRNdXNpZzJOb25jZXNLZXlWYWxEYXRhIGZhaWxzIGlmIHBhcnRpY2lwYW50IHB1YiBrZXlzIGFyZSBkdXBsaWNhdGVgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub25jZUtleVZhbERhdGEgPSBbMCwgMV0ubWFwKChpKSA9PiAoe1xuICAgICAgICBwYXJ0aWNpcGFudFB1YktleTogZHVtbXlQYXJ0aWNpcGFudFB1YktleXNbaV0sXG4gICAgICAgIHRhcE91dHB1dEtleTogZHVtbXlUYXBPdXRwdXRLZXksXG4gICAgICAgIHB1Yk5vbmNlOiBkdW1teVB1Yk5vbmNlLFxuICAgICAgfSkpO1xuXG4gICAgICBsZXQgcGFydGljaXBhbnRLZXlWYWxEYXRhID0ge1xuICAgICAgICBwYXJ0aWNpcGFudFB1YktleXM6IGR1bW15UGFydGljaXBhbnRQdWJLZXlzLFxuICAgICAgICB0YXBJbnRlcm5hbEtleTogZHVtbXlUYXBJbnRlcm5hbEtleSxcbiAgICAgICAgdGFwT3V0cHV0S2V5OiBpbnZhbGlkVGFwT3V0cHV0S2V5LFxuICAgICAgfTtcblxuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gYXNzZXJ0UHNidE11c2lnMk5vbmNlcyhub25jZUtleVZhbERhdGEsIHBhcnRpY2lwYW50S2V5VmFsRGF0YSksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYGludmFsaWQgc2l6ZSAxLiBNdXN0IHVzZSB4LW9ubHkga2V5LmBcbiAgICAgICk7XG5cbiAgICAgIHBhcnRpY2lwYW50S2V5VmFsRGF0YSA9IHtcbiAgICAgICAgcGFydGljaXBhbnRQdWJLZXlzOiBbaW52YWxpZFBhcnRpY2lwYW50UHViS2V5c1swXSwgZHVtbXlQYXJ0aWNpcGFudFB1YktleXNbMF1dLFxuICAgICAgICB0YXBJbnRlcm5hbEtleTogZHVtbXlUYXBJbnRlcm5hbEtleSxcbiAgICAgICAgdGFwT3V0cHV0S2V5OiBkdW1teVRhcE91dHB1dEtleSxcbiAgICAgIH07XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBhc3NlcnRQc2J0TXVzaWcyTm9uY2VzKG5vbmNlS2V5VmFsRGF0YSwgcGFydGljaXBhbnRLZXlWYWxEYXRhKSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgaW52YWxpZCBzaXplIDEuIE11c3QgdXNlIHBsYWluIGtleS5gXG4gICAgICApO1xuXG4gICAgICBwYXJ0aWNpcGFudEtleVZhbERhdGEgPSB7XG4gICAgICAgIHBhcnRpY2lwYW50UHViS2V5czogW2R1bW15UGFydGljaXBhbnRQdWJLZXlzWzBdLCBkdW1teVBhcnRpY2lwYW50UHViS2V5c1swXV0sXG4gICAgICAgIHRhcEludGVybmFsS2V5OiBkdW1teVRhcEludGVybmFsS2V5LFxuICAgICAgICB0YXBPdXRwdXRLZXk6IGR1bW15VGFwT3V0cHV0S2V5LFxuICAgICAgfTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IGFzc2VydFBzYnRNdXNpZzJOb25jZXMobm9uY2VLZXlWYWxEYXRhLCBwYXJ0aWNpcGFudEtleVZhbERhdGEpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09IGBEdXBsaWNhdGUgcGFydGljaXBhbnQgcHViIGtleXMgZm91bmRgXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoYGNyZWF0ZVRhcFR3ZWFrIGZhaWxzIGlmIGludmFsaWQgdGFwSW50ZXJuYWxLZXkgb3IgdGFwTWVya2xlUm9vdCBpcyBwYXNzZWRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBjcmVhdGVUYXBUd2VhayhpbnZhbGlkVGFwSW5wdXRLZXksIGR1bW15VGFwT3V0cHV0S2V5KSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgaW52YWxpZCBzaXplIDEuIE11c3QgdXNlIHgtb25seSBrZXkuYFxuICAgICAgKTtcblxuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gY3JlYXRlVGFwVHdlYWsoZHVtbXlUYXBJbnRlcm5hbEtleSwgaW52YWxpZFRhcE91dHB1dEtleSksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYGludmFsaWQgc2l6ZSAxLiBNdXN0IHVzZSB0YXAgbWVya2xlIHJvb3QuYFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGBtdXNpZzJQYXJ0aWFsU2lnbiBmYWlscyBpZiBpbnZhbGlkIHR4SGFzaCBpcyBwYXNzZWRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG11c2lnMlBhcnRpYWxTaWduKFxuICAgICAgICAgICAgZHVtbXlQcml2YXRlS2V5LFxuICAgICAgICAgICAgZHVtbXlQdWJOb25jZSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcHVibGljS2V5OiBkdW1teVBhcnRpY2lwYW50UHViS2V5c1swXSxcbiAgICAgICAgICAgICAgYWdnTm9uY2U6IGR1bW15QWdnTm9uY2UsXG4gICAgICAgICAgICAgIG1zZzogaW52YWxpZFR4SGFzaCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuZXcgTXVzaWcyTm9uY2VTdG9yZSgpXG4gICAgICAgICAgKSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSBgaW52YWxpZCBzaXplIDEuIE11c3QgdXNlIHR4IGhhc2guYFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGBlbmNvZGVQc2J0TXVzaWcyUGFydGlhbFNpZ0tleUtleVZhbERhdGEgZmFpbHMgaWYgaW52YWxpZCB0eEhhc2ggaXMgcGFzc2VkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBlbmNvZGVQc2J0TXVzaWcyUGFydGlhbFNpZyh7XG4gICAgICAgICAgICBwYXJ0aWFsU2lnOiBpbnZhbGlkUGFydGlhbFNpZyxcbiAgICAgICAgICAgIHBhcnRpY2lwYW50UHViS2V5OiBkdW1teVBhcnRpY2lwYW50UHViS2V5c1swXSxcbiAgICAgICAgICAgIHRhcE91dHB1dEtleTogZHVtbXlUYXBPdXRwdXRLZXksXG4gICAgICAgICAgfSksXG4gICAgICAgIChlOiBhbnkpID0+IGUubWVzc2FnZSA9PT0gYEludmFsaWQgcGFydGlhbFNpZyBsZW5ndGggMWBcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChgZGVsZXRlUHJvcHJpZXRhcnlLZXlWYWxzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQocDJ0ck11c2lnMlVuc3BlbnQsIHJvb3RXYWxsZXRLZXlzLCAndXNlcicsICdiaXRnbycsIG91dHB1dFR5cGUpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLnVzZXIpO1xuICAgICAgcHNidC5zZXRBbGxJbnB1dHNNdXNpZzJOb25jZUhEKHJvb3RXYWxsZXRLZXlzLmJpdGdvKTtcbiAgICAgIGNvbnN0IGtleSA9IHtcbiAgICAgICAgaWRlbnRpZmllcjogJ0RVTU1ZJyxcbiAgICAgICAgc3VidHlwZTogMTAwLFxuICAgICAgICBrZXlkYXRhOiBkdW1teVRhcE91dHB1dEtleSxcbiAgICAgIH07XG4gICAgICBwc2J0LmFkZFByb3ByaWV0YXJ5S2V5VmFsVG9JbnB1dCgwLCB7IGtleSwgdmFsdWU6IGR1bW15VGFwSW50ZXJuYWxLZXkgfSk7XG4gICAgICBwc2J0LmRlbGV0ZVByb3ByaWV0YXJ5S2V5VmFscygwLCB7IGlkZW50aWZpZXI6IFBTQlRfUFJPUFJJRVRBUllfSURFTlRJRklFUiB9KTtcbiAgICAgIGNvbnN0IGtleVZhbCA9IHBzYnQuZ2V0UHJvcHJpZXRhcnlLZXlWYWxzKDApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleVZhbC5sZW5ndGgsIDEpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleVZhbFswXS5rZXkuaWRlbnRpZmllciwgJ0RVTU1ZJyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!