diff --git a/.gitignore b/.gitignore index ceec3e79..a70e738b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ npm-debug.log node_modules dist es +build diff --git a/build/bitsharesjs.js b/build/bitsharesjs.js deleted file mode 100644 index ca61adc2..00000000 --- a/build/bitsharesjs.js +++ /dev/null @@ -1,25117 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.bitshares_js = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i} [signer_pubkeys = null] - Optional ["GPHAbc9Def0...", ...]. These are additional signing keys. Some balance claims require propritary address formats, the witness node can't tell us which ones are needed so they must be passed in. If the witness node can figure out a signing key (mostly all other transactions), it should not be passed in here. - @arg {boolean} [broadcast = false] - */ - - - TransactionBuilder.prototype.process_transaction = function process_transaction(cwallet) { - var _this = this; - - var signer_pubkeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - var broadcast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - var wallet_object = cwallet.wallet.wallet_object; - if (_bitsharesjsWs.Apis.instance().chain_id !== wallet_object.get("chain_id")) return Promise.reject("Mismatched chain_id; expecting " + wallet_object.get("chain_id") + ", but got " + _bitsharesjsWs.Apis.instance().chain_id); - - return this.set_required_fees().then(function () { - var signer_pubkeys_added = {}; - if (signer_pubkeys) { - // Balance claims are by address, only the private - // key holder can know about these additional - // potential keys. - var pubkeys = cwallet.getPubkeys_having_PrivateKey(signer_pubkeys); - if (!pubkeys.length) throw new Error("Missing signing key"); - - for (var _iterator = pubkeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - var pubkey_string = _ref; - - var private_key = cwallet.getPrivateKey(pubkey_string); - _this.add_signer(private_key, pubkey_string); - signer_pubkeys_added[pubkey_string] = true; - } - } - - return _this.get_potential_signatures().then(function (_ref2) { - var pubkeys = _ref2.pubkeys, - addys = _ref2.addys; - - var my_pubkeys = cwallet.getPubkeys_having_PrivateKey(pubkeys, addys); - - //{//Testing only, don't send All public keys! - // var pubkeys_all = PrivateKeyStore.getPubkeys() // All public keys - // this.get_required_signatures(pubkeys_all).then( required_pubkey_strings => - // console.log('get_required_signatures all\t',required_pubkey_strings.sort(), pubkeys_all)) - // this.get_required_signatures(my_pubkeys).then( required_pubkey_strings => - // console.log('get_required_signatures normal\t',required_pubkey_strings.sort(), pubkeys)) - //} - - return _this.get_required_signatures(my_pubkeys).then(function (required_pubkeys) { - for (var _iterator2 = required_pubkeys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref3; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref3 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref3 = _i2.value; - } - - var _pubkey_string = _ref3; - - if (signer_pubkeys_added[_pubkey_string]) continue; - var private_key = cwallet.getPrivateKey(_pubkey_string); - if (!private_key) - // This should not happen, get_required_signatures will only - // returned keys from my_pubkeys - throw new Error("Missing signing key for " + _pubkey_string); - _this.add_signer(private_key, _pubkey_string); - } - }); - }).then(function () { - return broadcast ? _this.broadcast() : _this.serialize(); - }); - }); - }; - - /** Typically this is called automatically just prior to signing. Once finalized this transaction can not be changed. */ - - - TransactionBuilder.prototype.finalize = function finalize() { - var _this2 = this; - - return new Promise(function (resolve, reject) { - if (_this2.tr_buffer) { - throw new Error("already finalized"); - } - - resolve(_bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [["2.1.0"]]).then(function (r) { - head_block_time_string = r[0].time; - if (_this2.expiration === 0) _this2.expiration = base_expiration_sec() + _bitsharesjsWs.ChainConfig.expire_in_secs; - _this2.ref_block_num = r[0].head_block_number & 0xffff; - _this2.ref_block_prefix = new Buffer(r[0].head_block_id, "hex").readUInt32LE(4); - //DEBUG console.log("ref_block",@ref_block_num,@ref_block_prefix,r) - - var iterable = _this2.operations; - for (var i = 0, op; i < iterable.length; i++) { - op = iterable[i]; - if (op[1]["finalize"]) { - op[1].finalize(); - } - } - _this2.tr_buffer = _serializer.ops.transaction.toBuffer(_this2); - })); - }); - }; - - /** @return {string} hex transaction ID */ - - - TransactionBuilder.prototype.id = function id() { - if (!this.tr_buffer) { - throw new Error("not finalized"); - } - return _ecc.hash.sha256(this.tr_buffer).toString("hex").substring(0, 40); - }; - - /** - Typically one will use {@link this.add_type_operation} instead. - @arg {array} operation - [operation_id, operation] - */ - - - TransactionBuilder.prototype.add_operation = function add_operation(operation) { - if (this.tr_buffer) { - throw new Error("already finalized"); - } - (0, _assert2.default)(operation, "operation"); - if (!Array.isArray(operation)) { - throw new Error("Expecting array [operation_id, operation]"); - } - this.operations.push(operation); - return; - }; - - TransactionBuilder.prototype.get_type_operation = function get_type_operation(name, operation) { - if (this.tr_buffer) { - throw new Error("already finalized"); - } - (0, _assert2.default)(name, "name"); - (0, _assert2.default)(operation, "operation"); - var _type = _serializer.ops[name]; - (0, _assert2.default)(_type, "Unknown operation " + name); - var operation_id = _ChainTypes2.default.operations[_type.operation_name]; - if (operation_id === undefined) { - throw new Error("unknown operation: " + _type.operation_name); - } - if (!operation.fee) { - operation.fee = { amount: 0, asset_id: 0 }; - } - if (name === "proposal_create") { - /* - * Proposals involving the committee account require a review - * period to be set, look for them here - */ - var requiresReview = false, - extraReview = 0; - operation.proposed_ops.forEach(function (op) { - var COMMITTE_ACCOUNT = 0; - var key = void 0; - - switch (op.op[0]) { - case 0: - // transfer - key = "from"; - break; - - case 6: //account_update - case 17: - // asset_settle - key = "account"; - break; - - case 10: // asset_create - case 11: // asset_update - case 12: // asset_update_bitasset - case 13: // asset_update_feed_producers - case 14: // asset_issue - case 18: // asset_global_settle - case 43: - // asset_claim_fees - key = "issuer"; - break; - - case 15: - // asset_reserve - key = "payer"; - break; - - case 16: - // asset_fund_fee_pool - key = "from_account"; - break; - - case 22: // proposal_create - case 23: // proposal_update - case 24: - // proposal_delete - key = "fee_paying_account"; - break; - - case 31: - // committee_member_update_global_parameters - requiresReview = true; - extraReview = 60 * 60 * 24 * 13; // Make the review period 2 weeks total - break; - } - if (key in op.op[1] && op.op[1][key] === COMMITTE_ACCOUNT) { - requiresReview = true; - } - }); - operation.expiration_time || (operation.expiration_time = base_expiration_sec() + _bitsharesjsWs.ChainConfig.expire_in_secs_proposal); - if (requiresReview) { - operation.review_period_seconds = extraReview + Math.max(committee_min_review, 24 * 60 * 60 || _bitsharesjsWs.ChainConfig.review_in_secs_committee); - /* - * Expiration time must be at least equal to - * now + review_period_seconds, so we add one hour to make sure - */ - operation.expiration_time += 60 * 60 + extraReview; - } - } - var operation_instance = _type.fromObject(operation); - return [operation_id, operation_instance]; - }; - - /* optional: fetch the current head block */ - - TransactionBuilder.prototype.update_head_block = function update_head_block() { - return Promise.all([_bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [["2.0.0"]]), _bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [["2.1.0"]])]).then(function (res) { - var g = res[0], - r = res[1]; - - head_block_time_string = r[0].time; - committee_min_review = g[0].parameters.committee_proposal_review_period; - }); - }; - - /** optional: there is a deafult expiration */ - - - TransactionBuilder.prototype.set_expire_seconds = function set_expire_seconds(sec) { - if (this.tr_buffer) { - throw new Error("already finalized"); - } - return this.expiration = base_expiration_sec() + sec; - }; - - /* Wraps this transaction in a proposal_create transaction */ - - - TransactionBuilder.prototype.propose = function propose(proposal_create_options) { - if (this.tr_buffer) { - throw new Error("already finalized"); - } - if (!this.operations.length) { - throw new Error("add operation first"); - } - - (0, _assert2.default)(proposal_create_options, "proposal_create_options"); - (0, _assert2.default)(proposal_create_options.fee_paying_account, "proposal_create_options.fee_paying_account"); - - var proposed_ops = this.operations.map(function (op) { - return { op: op }; - }); - - this.operations = []; - this.signatures = []; - this.signer_private_keys = []; - proposal_create_options.proposed_ops = proposed_ops; - this.add_type_operation("proposal_create", proposal_create_options); - return this; - }; - - TransactionBuilder.prototype.has_proposed_operation = function has_proposed_operation() { - var hasProposed = false; - for (var i = 0; i < this.operations.length; i++) { - if ("proposed_ops" in this.operations[i][1]) { - hasProposed = true; - break; - } - } - - return hasProposed; - }; - - /** optional: the fees can be obtained from the witness node */ - - - TransactionBuilder.prototype.set_required_fees = function set_required_fees(asset_id, removeDuplicates) { - var _this3 = this; - - if (this.tr_buffer) { - throw new Error("already finalized"); - } - if (!this.operations.length) { - throw new Error("add operations first"); - } - - function isProposal(op) { - return op[0] === 22; - } - - var operations = []; - var proposed_ops = []; - var feeAssets = []; - var proposalFeeAssets = []; - var potentialDuplicates = {}; - function getDuplicateOriginalIndex(op, index) { - var key = getOperationKey(op); - var duplicate = potentialDuplicates[key]; - if (!!duplicate) { - if (duplicate.original === index) return index;else if (duplicate.duplicates.indexOf(index) !== -1) { - return duplicate.original; - } - } - } - function getOperationKey(op) { - var key = null; - switch (op[0]) { - case 0: - // transfer - var memoDummy = new Array(op[1].memo.message.length + 1).join("a"); - key = op[0] + "_" + op[1].amount.asset_id + "_" + memoDummy; - break; - default: - } - return key; - } - for (var i = 0, op; i < this.operations.length; i++) { - op = this.operations[i]; - var opObject = _serializer.ops.operation.toObject(op); - var isDuplicate = false; - if (removeDuplicates) { - var key = getOperationKey(opObject); - if (key) { - if (!potentialDuplicates[key]) potentialDuplicates[key] = { - original: i, - duplicates: [] - };else { - potentialDuplicates[key].duplicates.push(i); - isDuplicate = true; - } - } - } - /* - * If the operation creates a proposal, we should check the fee pool - * of the suggested proposal fee assets to prevent users from creating - * proposals that will most likely fail due to empty fee pools - */ - if (isProposal(op)) { - op[1].proposed_ops.forEach(function (proposal) { - // console.log("proposed op", proposal.op[1].fee); - proposed_ops.push(proposal); - if (proposalFeeAssets.indexOf(proposal.op[1].fee.asset_id) === -1) proposalFeeAssets.push("1.3." + proposal.op[1].fee.asset_id); - }); - } - if (!isDuplicate) { - operations.push(opObject); - if (feeAssets.indexOf(operations[i][1].fee.asset_id) === -1) feeAssets.push(operations[i][1].fee.asset_id); - } - } - - if (!asset_id) { - var op1_fee = operations[0][1].fee; - if (op1_fee && op1_fee.asset_id !== null) { - asset_id = op1_fee.asset_id; - } else { - asset_id = "1.3.0"; - } - } - - /* - * Add the proposal fee asset ids to feeAssets here to fetch their - * fees and dynamic objects - */ - if (proposalFeeAssets.length) { - proposalFeeAssets.forEach(function (id) { - if (feeAssets.indexOf(id) === -1) feeAssets.push(id); - }); - } - var promises = []; - promises.push(Promise.all(feeAssets.map(function (id) { - return _bitsharesjsWs.Apis.instance().db_api().exec("get_required_fees", [operations, id]); - })).catch(function (err) { - console.error("get_required_fees API error: ", err.message); - })); - - if (feeAssets.length > 1 || feeAssets[0] !== "1.3.0") { - /* - * If we're paying with any assets other than CORE, we need to fetch - * the dynamic asset object and check the fee pool of those assets. - * The dynamic asset object id is equal to the asset id but with - * 2.3.x instead of 1.3.x - */ - var dynamicObjectIds = feeAssets.map(function (a) { - return a.replace(/^1\./, "2."); - }); - promises.push(_bitsharesjsWs.Apis.instance().db_api().exec("get_required_fees", [operations, "1.3.0"])); - promises.push(_bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [dynamicObjectIds])); - } - - return Promise.all(promises).then(function (results) { - /* - * allFees and coreFees are arrays containg fee amounts grouped by - * asset and for each operation in operations - */ - var allFees = results[0], - coreFees = results[1], - dynamicObjects = results[2]; - /* - * If one of the desired fee assets has an invalid core exchange rate - * get_required_signatures will fail and the result for all assets - * will be undefined, if so we just default to coreFees - */ - - if (allFees === undefined) { - allFees = coreFees; - } - /* - * If the only desired fee asset is CORE, coreFees are not fetched - * but are equal to allFees - */ - if (!coreFees) { - coreFees = allFees[0]; - } - - /* Create a map of fees and proposal fees by asset id */ - var feesByAsset = {}; - var proposalFeesByAsset = {}; - allFees.forEach(function (feeSet) { - var filteredFeeSet = feeSet.map(function (f) { - if (Array.isArray(f)) { - // This operation includes a proposal - proposalFeesByAsset[f[1][0].asset_id] = f[1]; - return f[0]; - } - return f; - }); - var currentAssetId = filteredFeeSet[0].asset_id; - - feesByAsset[currentAssetId] = filteredFeeSet; - }, {}); - - /* Create a map of fee pools by asset id*/ - var feePoolMap = !!dynamicObjects ? dynamicObjects.reduce(function (map, object) { - map[object.id.replace(/^2\./, "1.")] = object; - return map; - }, {}) : {}; - - var feeMap = {}; - var proposalFeeMap = {}; - function updateFeeMap(map, asset_id, opIndex, core_fees) { - if (!map[asset_id]) map[asset_id] = { total: 0, ops: [] }; - if (map[asset_id].propIdx) map[asset_id].propIdx.push(opIndex);else map[asset_id].ops.push(opIndex); - - if (asset_id !== "1.3.0") { - map[asset_id].total += core_fees.length ? core_fees[opIndex].amount : core_fees.amount; - } - return map; - } - - var _loop = function _loop(_i3) { - var op = operations[_i3]; - var feeAssetId = op[1].fee.asset_id; - - if (isProposal(op)) { - feeMap = updateFeeMap(feeMap, feeAssetId, _i3, coreFees[_i3][0]); - - op[1].proposed_ops.forEach(function (prop, y) { - var propFeeAsset = prop.op[1].fee.asset_id; - if (!proposalFeeMap[_i3]) proposalFeeMap[_i3] = {}; - if (!proposalFeeMap[_i3][propFeeAsset]) proposalFeeMap[_i3][propFeeAsset] = { - total: 0, - ops: [_i3], - propIdx: [] - }; - - proposalFeeMap[_i3] = updateFeeMap(proposalFeeMap[_i3], propFeeAsset, y, coreFees[_i3][1]); - }); - } else { - feeMap = updateFeeMap(feeMap, feeAssetId, _i3, coreFees[_i3]); - } - }; - - for (var _i3 = 0; _i3 < operations.length; _i3++) { - _loop(_i3); - } - - /* Check fee pool balances for regular ops */ - function checkPoolBalance(feeMap) { - if (!Object.keys(feeMap).length) return []; - var final_fees = []; - - var _loop2 = function _loop2(asset) { - var feePoolBalance = feePoolMap[asset] ? parseInt(feePoolMap[asset].fee_pool, 10) : 0; - /* Fee pool balance insufficient, default to core*/ - if (feeMap[asset].total > feePoolBalance) { - feeMap[asset].ops.forEach(function (opIndex) { - if (coreFees[opIndex].length === 2 && "propIdx" in feeMap[asset]) { - /* Proposal op */ - feeMap[asset].propIdx.forEach(function (prop_idx) { - final_fees[prop_idx] = coreFees[opIndex][1][prop_idx]; - }); - } else if (coreFees[opIndex].length === 2) { - final_fees[opIndex] = coreFees[opIndex][0]; - } else { - final_fees[opIndex] = coreFees[opIndex]; - } - }); - /* Use the desired fee asset */ - } else { - feeMap[asset].ops.forEach(function (opIndex) { - if (coreFees[opIndex].length === 2 && "propIdx" in feeMap[asset]) { - feeMap[asset].propIdx.forEach(function (prop_idx) { - final_fees[prop_idx] = proposalFeesByAsset[asset][prop_idx]; - }); - } else { - final_fees[opIndex] = feesByAsset[asset][opIndex]; - } - }); - } - }; - - for (var asset in feeMap) { - _loop2(asset); - } - return final_fees; - } - - var finalFees = checkPoolBalance(feeMap); - - var finalProposalFees = {}; - for (var _key in proposalFeeMap) { - finalProposalFees[_key] = checkPoolBalance(proposalFeeMap[_key]); - } - - var set_fee = function set_fee(operation, opIndex) { - if (!operation.fee || operation.fee.amount === 0 || operation.fee.amount.toString && operation.fee.amount.toString() === "0" // Long - ) { - if (removeDuplicates) { - var _op = _serializer.ops.operation.toObject(_this3.operations[opIndex]); - var originalIndex = getDuplicateOriginalIndex(_op, opIndex); - if (originalIndex >= 0) { - // it's a duplicate - operation.fee = finalFees[originalIndex]; - } else { - operation.fee = finalFees[opIndex]; - } - } else { - operation.fee = finalFees[opIndex]; - } - } - if (operation.proposed_ops) { - var result = []; - /* - * Loop over proposed_ops and assign fee asset ids as - * determined by the fee pool balance check. If the balance - * is sufficient the asset_id is kept, if not it defaults to - * "1.3.0" - */ - for (var y = 0; y < operation.proposed_ops.length; y++) { - operation.proposed_ops[y].op[1].fee.asset_id = finalProposalFees[opIndex][y].asset_id; - } - - return result; - } - }; - /* We apply the final fees the the operations */ - for (var _i4 = 0; _i4 < _this3.operations.length; _i4++) { - set_fee(_this3.operations[_i4][1], _i4); - } - }); - //DEBUG console.log('... get_required_fees',operations,asset_id,flat_fees) - }; - - TransactionBuilder.prototype.get_potential_signatures = function get_potential_signatures() { - var tr_object = _serializer.ops.signed_transaction.toObject(this); - return Promise.all([_bitsharesjsWs.Apis.instance().db_api().exec("get_potential_signatures", [tr_object]), _bitsharesjsWs.Apis.instance().db_api().exec("get_potential_address_signatures", [tr_object])]).then(function (results) { - return { pubkeys: results[0], addys: results[1] }; - }); - }; - - TransactionBuilder.prototype.get_required_signatures = function get_required_signatures(available_keys) { - if (!available_keys.length) { - return Promise.resolve([]); - } - var tr_object = _serializer.ops.signed_transaction.toObject(this); - //DEBUG console.log('... tr_object',tr_object) - return _bitsharesjsWs.Apis.instance().db_api().exec("get_required_signatures", [tr_object, available_keys]).then(function (required_public_keys) { - //DEBUG console.log('... get_required_signatures',required_public_keys) - return required_public_keys; - }); - }; - - TransactionBuilder.prototype.add_signer = function add_signer(private_key) { - var public_key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : private_key.toPublicKey(); - - (0, _assert2.default)(private_key.d, "required PrivateKey object"); - - if (this.signed) { - throw new Error("already signed"); - } - if (!public_key.Q) { - public_key = _ecc.PublicKey.fromPublicKeyString(public_key); - } - // prevent duplicates - var spHex = private_key.toHex(); - for (var _iterator3 = this.signer_private_keys, _isArray3 = Array.isArray(_iterator3), _i5 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { - var _ref4; - - if (_isArray3) { - if (_i5 >= _iterator3.length) break; - _ref4 = _iterator3[_i5++]; - } else { - _i5 = _iterator3.next(); - if (_i5.done) break; - _ref4 = _i5.value; - } - - var sp = _ref4; - - if (sp[0].toHex() === spHex) return; - } - this.signer_private_keys.push([private_key, public_key]); - }; - - TransactionBuilder.prototype.sign = function sign() { - var chain_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.Apis.instance().chain_id; - - if (!this.tr_buffer) { - throw new Error("not finalized"); - } - if (this.signed) { - throw new Error("already signed"); - } - if (!this.signer_private_keys.length) { - throw new Error("Transaction was not signed. Do you have a private key? [no_signers]"); - } - var end = this.signer_private_keys.length; - for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) { - var _signer_private_keys$ = this.signer_private_keys[i], - private_key = _signer_private_keys$[0], - public_key = _signer_private_keys$[1]; - - var sig = _ecc.Signature.signBuffer(Buffer.concat([new Buffer(chain_id, "hex"), this.tr_buffer]), private_key, public_key); - this.signatures.push(sig.toBuffer()); - } - this.signer_private_keys = []; - this.signed = true; - return; - }; - - TransactionBuilder.prototype.serialize = function serialize() { - return _serializer.ops.signed_transaction.toObject(this); - }; - - TransactionBuilder.prototype.toObject = function toObject() { - return _serializer.ops.signed_transaction.toObject(this); - }; - - TransactionBuilder.prototype.broadcast = function broadcast(was_broadcast_callback) { - var _this4 = this; - - if (this.tr_buffer) { - return this._broadcast(was_broadcast_callback); - } else { - return this.finalize().then(function () { - return _this4._broadcast(was_broadcast_callback); - }); - } - }; - - return TransactionBuilder; -}(); - -var base_expiration_sec = function base_expiration_sec() { - var head_block_sec = Math.ceil(getHeadBlockDate().getTime() / 1000); - var now_sec = Math.ceil(Date.now() / 1000); - // The head block time should be updated every 3 seconds. If it isn't - // then help the transaction to expire (use head_block_sec) - if (now_sec - head_block_sec > 30) { - return head_block_sec; - } - // If the user's clock is very far behind, use the head block time. - return Math.max(now_sec, head_block_sec); -}; - -function _broadcast(was_broadcast_callback) { - var _this5 = this; - - return new Promise(function (resolve, reject) { - if (!_this5.signed) { - _this5.sign(); - } - if (!_this5.tr_buffer) { - throw new Error("not finalized"); - } - if (!_this5.signatures.length) { - throw new Error("not signed"); - } - if (!_this5.operations.length) { - throw new Error("no operations"); - } - - var tr_object = _serializer.ops.signed_transaction.toObject(_this5); - // console.log('... broadcast_transaction_with_callback !!!') - _bitsharesjsWs.Apis.instance().network_api().exec("broadcast_transaction_with_callback", [function (res) { - return resolve(res); - }, tr_object]).then(function () { - //console.log('... broadcast success, waiting for callback') - if (was_broadcast_callback) was_broadcast_callback(); - return; - }).catch(function (error) { - // console.log may be redundant for network errors, other errors could occur - console.log(error); - var message = error.message; - if (!message) { - message = ""; - } - reject(new Error(message + "\n" + "bitshares-crypto " + " digest " + _ecc.hash.sha256(_this5.tr_buffer).toString("hex") + " transaction " + _this5.tr_buffer.toString("hex") + " " + JSON.stringify(tr_object))); - return; - }); - return; - }); -} - -function getHeadBlockDate() { - return timeStringToDate(head_block_time_string); -} - -function timeStringToDate(time_string) { - if (!time_string) return new Date("1970-01-01T00:00:00.000Z"); - if (!/Z$/.test(time_string)) - //does not end in Z - // https://github.com/cryptonomex/graphene/issues/368 - time_string = time_string + "Z"; - return new Date(time_string); -} - -exports.default = TransactionBuilder; -module.exports = exports["default"]; -},{"../../ecc":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/index.js","../../serializer":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/index.js","./ChainTypes":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/chain/src/ChainTypes.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bitsharesjs-ws":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/chain/src/state.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -function get(state) { - return function (key) { - return state[key] || ""; - }; -} - -function set(state) { - return function (key, value) { - state[key] = value; - return this; - }; -} - -exports.get = get; -exports.set = set; -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/index.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.key = exports.hash = exports.brainKey = exports.Signature = exports.PublicKey = exports.PrivateKey = exports.Aes = exports.Address = undefined; - -var _address = require("./src/address"); - -var _address2 = _interopRequireDefault(_address); - -var _aes = require("./src/aes"); - -var _aes2 = _interopRequireDefault(_aes); - -var _PrivateKey = require("./src/PrivateKey"); - -var _PrivateKey2 = _interopRequireDefault(_PrivateKey); - -var _PublicKey = require("./src/PublicKey"); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -var _signature = require("./src/signature"); - -var _signature2 = _interopRequireDefault(_signature); - -var _BrainKey = require("./src/BrainKey"); - -var _BrainKey2 = _interopRequireDefault(_BrainKey); - -var _hash = require("./src/hash"); - -var hash = _interopRequireWildcard(_hash); - -var _KeyUtils = require("./src/KeyUtils"); - -var _KeyUtils2 = _interopRequireDefault(_KeyUtils); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.Address = _address2.default; -exports.Aes = _aes2.default; -exports.PrivateKey = _PrivateKey2.default; -exports.PublicKey = _PublicKey2.default; -exports.Signature = _signature2.default; -exports.brainKey = _BrainKey2.default; -exports.hash = hash; -exports.key = _KeyUtils2.default; -},{"./src/BrainKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/BrainKey.js","./src/KeyUtils":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/KeyUtils.js","./src/PrivateKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PrivateKey.js","./src/PublicKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js","./src/address":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/address.js","./src/aes":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/aes.js","./src/hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","./src/signature":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/signature.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/BrainKey.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.default = normalize; -function normalize(brainKey) { - if (typeof brainKey !== "string") { - throw new Error("string required for brainKey"); - } - brainKey = brainKey.trim(); - return brainKey.split(/[\t\n\v\f\r ]+/).join(" "); -} -module.exports = exports["default"]; -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/KeyUtils.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _PrivateKey = require("./PrivateKey"); - -var _PrivateKey2 = _interopRequireDefault(_PrivateKey); - -var _PublicKey = require("./PublicKey"); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -var _address = require("./address"); - -var _address2 = _interopRequireDefault(_address); - -var _aes = require("./aes"); - -var _aes2 = _interopRequireDefault(_aes); - -var _hash = require("./hash"); - -var _secureRandom = require("secure-random"); - -var _secureRandom2 = _interopRequireDefault(_secureRandom); - -var _bitsharesjsWs = require("bitsharesjs-ws"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// import dictionary from './dictionary_en'; -var Buffer = require("safe-buffer").Buffer; - -// hash for .25 second -var HASH_POWER_MILLS = 250; - -var key = { - /** Uses 1 second of hashing power to create a key/password checksum. An - implementation can re-call this method with the same password to re-match - the strength of the CPU (either after moving from a desktop to a mobile, - mobile to desktop, or N years from now when CPUs are presumably stronger). - A salt is used for all the normal reasons... - @return object { - aes_private: Aes, - checksum: "{hash_iteration_count},{salt},{checksum}" - } - */ - aes_checksum: function aes_checksum(password) { - if (!(typeof password === "string")) { - throw new "password string required"(); - } - var salt = _secureRandom2.default.randomBuffer(4).toString("hex"); - var iterations = 0; - var secret = salt + password; - // hash for .1 second - var start_t = Date.now(); - while (Date.now() - start_t < HASH_POWER_MILLS) { - secret = (0, _hash.sha256)(secret); - iterations += 1; - } - - var checksum = (0, _hash.sha256)(secret); - var checksum_string = [iterations, salt.toString("hex"), checksum.slice(0, 4).toString("hex")].join(","); - - return { - aes_private: _aes2.default.fromSeed(secret), - checksum: checksum_string - }; - }, - - - /** Provide a matching password and key_checksum. A "wrong password" - error is thrown if the password does not match. If this method takes - much more or less than 1 second to return, one should consider updating - all encyrpted fields using a new key.key_checksum. - */ - aes_private: function aes_private(password, key_checksum) { - var _key_checksum$split = key_checksum.split(","), - iterations = _key_checksum$split[0], - salt = _key_checksum$split[1], - checksum = _key_checksum$split[2]; - - var secret = salt + password; - for (var i = 0; 0 < iterations ? i < iterations : i > iterations; 0 < iterations ? i++ : i++) { - secret = (0, _hash.sha256)(secret); - } - var new_checksum = (0, _hash.sha256)(secret); - if (!(new_checksum.slice(0, 4).toString("hex") === checksum)) { - throw new Error("wrong password"); - } - return _aes2.default.fromSeed(secret); - }, - - - /** - A week random number generator can run out of entropy. This should ensure even the worst random number implementation will be reasonably safe. - @param1 string entropy of at least 32 bytes - */ - random32ByteBuffer: function random32ByteBuffer() { - var entropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.browserEntropy(); - - if (!(typeof entropy === "string")) { - throw new Error("string required for entropy"); - } - - if (entropy.length < 32) { - throw new Error("expecting at least 32 bytes of entropy"); - } - - var start_t = Date.now(); - - while (Date.now() - start_t < HASH_POWER_MILLS) { - entropy = (0, _hash.sha256)(entropy); - }var hash_array = []; - hash_array.push(entropy); - - // Hashing for 1 second may helps the computer is not low on entropy (this method may be called back-to-back). - hash_array.push(_secureRandom2.default.randomBuffer(32)); - - return (0, _hash.sha256)(Buffer.concat(hash_array)); - }, - - - suggest_brain_key: function suggest_brain_key() { - var dictionary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ","; - var entropy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.browserEntropy(); - - var randomBuffer = this.random32ByteBuffer(entropy); - - var word_count = 16; - var dictionary_lines = dictionary.split(","); - - if (!(dictionary_lines.length === 49744)) { - throw new Error("expecting " + 49744 + " but got " + dictionary_lines.length + " dictionary words"); - } - - var brainkey = []; - var end = word_count * 2; - - for (var i = 0; i < end; i += 2) { - // randomBuffer has 256 bits / 16 bits per word == 16 words - var num = (randomBuffer[i] << 8) + randomBuffer[i + 1]; - - // convert into a number between 0 and 1 (inclusive) - var rndMultiplier = num / Math.pow(2, 16); - var wordIndex = Math.round(dictionary_lines.length * rndMultiplier); - - brainkey.push(dictionary_lines[wordIndex]); - } - return this.normalize_brainKey(brainkey.join(" ")); - }, - - get_random_key: function get_random_key(entropy) { - return _PrivateKey2.default.fromBuffer(this.random32ByteBuffer(entropy)); - }, - get_brainPrivateKey: function get_brainPrivateKey(brainKey) { - var sequence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - if (sequence < 0) { - throw new Error("invalid sequence"); - } - if (brainKey.trim() === "") { - throw new Error("empty brain key"); - } - brainKey = key.normalize_brainKey(brainKey); - return _PrivateKey2.default.fromBuffer((0, _hash.sha256)((0, _hash.sha512)(brainKey + " " + sequence))); - }, - - - // Turn invisible space like characters into a single space - normalize_brainKey: function normalize_brainKey(brainKey) { - if (!(typeof brainKey === "string")) { - throw new Error("string required for brainKey"); - } - - brainKey = brainKey.trim(); - if (brainKey === "") { - throw new Error("empty brain key"); - } - return brainKey.split(/[\t\n\v\f\r ]+/).join(" "); - }, - browserEntropy: function browserEntropy() { - var entropyStr = ""; - try { - entropyStr = new Date().toString() + " " + window.screen.height + " " + window.screen.width + " " + window.screen.colorDepth + " " + " " + window.screen.availHeight + " " + window.screen.availWidth + " " + window.screen.pixelDepth + navigator.language + " " + window.location + " " + window.history.length; - - for (var i = 0, mimeType; i < navigator.mimeTypes.length; i++) { - mimeType = navigator.mimeTypes[i]; - entropyStr += mimeType.description + " " + mimeType.type + " " + mimeType.suffixes + " "; - } - console.log("INFO\tbrowserEntropy gathered"); - } catch (error) { - //nodejs:ReferenceError: window is not defined - entropyStr = (0, _hash.sha256)(new Date().toString()); - } - - var b = Buffer.from(entropyStr); - entropyStr += b.toString("binary") + " " + new Date().toString(); - return entropyStr; - }, - - - // @return array of 5 legacy addresses for a pubkey string parameter. - addresses: function addresses(pubkey) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix; - - var public_key = _PublicKey2.default.fromPublicKeyString(pubkey, address_prefix); - // S L O W - var address_string = [_address2.default.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed - _address2.default.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed - _address2.default.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed - _address2.default.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed - public_key.toAddressString(address_prefix) // bts_short, most recent format - ]; - return address_string; - } -}; - -exports.default = key; -module.exports = exports["default"]; -},{"./PrivateKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PrivateKey.js","./PublicKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js","./address":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/address.js","./aes":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/aes.js","./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","bitsharesjs-ws":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js","secure-random":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/secure-random/lib/secure-random.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PrivateKey.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _ecurve = require("ecurve"); - -var _bigi = require("bigi"); - -var _bigi2 = _interopRequireDefault(_bigi); - -var _bs = require("bs58"); - -var _hash = require("./hash"); - -var _PublicKey = require("./PublicKey"); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -var _deepEqual = require("deep-equal"); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var secp256k1 = (0, _ecurve.getCurveByName)("secp256k1"); -var n = secp256k1.n; - -var Buffer = require("safe-buffer").Buffer; - -var PrivateKey = function () { - /** - @private see static functions - @param {BigInteger} - */ - function PrivateKey(d) { - _classCallCheck(this, PrivateKey); - - this.d = d; - } - - PrivateKey.fromBuffer = function fromBuffer(buf) { - if (!Buffer.isBuffer(buf)) { - throw new Error("Expecting paramter to be a Buffer type"); - } - if (32 !== buf.length) { - console.log("WARN: Expecting 32 bytes, instead got " + buf.length + ", stack trace:", new Error().stack); - } - if (buf.length === 0) { - throw new Error("Empty buffer"); - } - return new PrivateKey(_bigi2.default.fromBuffer(buf)); - }; - - /** @arg {string} seed - any length string. This is private, the same seed produces the same private key every time. */ - - - PrivateKey.fromSeed = function fromSeed(seed) { - // generate_private_key - if (!(typeof seed === "string")) { - throw new Error("seed must be of type string"); - } - return PrivateKey.fromBuffer((0, _hash.sha256)(seed)); - }; - - /** @return {string} Wallet Import Format (still a secret, Not encrypted) */ - - - PrivateKey.fromWif = function fromWif(_private_wif) { - var private_wif = Buffer.from((0, _bs.decode)(_private_wif)); - var version = private_wif.readUInt8(0); - _assert2.default.equal(0x80, version, "Expected version " + 0x80 + ", instead got " + version); - // checksum includes the version - var private_key = private_wif.slice(0, -4); - var checksum = private_wif.slice(-4); - var new_checksum = (0, _hash.sha256)(private_key); - new_checksum = (0, _hash.sha256)(new_checksum); - new_checksum = new_checksum.slice(0, 4); - var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); //, 'Invalid checksum' - if (!isEqual) { - throw new Error("Checksum did not match"); - } - private_key = private_key.slice(1); - return PrivateKey.fromBuffer(private_key); - }; - - PrivateKey.prototype.toWif = function toWif() { - var private_key = this.toBuffer(); - // checksum includes the version - private_key = Buffer.concat([Buffer.from([0x80]), private_key]); - var checksum = (0, _hash.sha256)(private_key); - checksum = (0, _hash.sha256)(checksum); - checksum = checksum.slice(0, 4); - var private_wif = Buffer.concat([private_key, checksum]); - return (0, _bs.encode)(private_wif); - }; - - /** - @return {Point} - */ - - - PrivateKey.prototype.toPublicKeyPoint = function toPublicKeyPoint() { - return secp256k1.G.multiply(this.d); - }; - - PrivateKey.prototype.toPublicKey = function toPublicKey() { - if (this.public_key) { - return this.public_key; - } - return this.public_key = _PublicKey2.default.fromPoint(this.toPublicKeyPoint()); - }; - - PrivateKey.prototype.toBuffer = function toBuffer() { - return this.d.toBuffer(32); - }; - - /** ECIES */ - - - PrivateKey.prototype.get_shared_secret = function get_shared_secret(public_key) { - var legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - public_key = toPublic(public_key); - var KB = public_key.toUncompressed().toBuffer(); - var KBP = _ecurve.Point.fromAffine(secp256k1, _bigi2.default.fromBuffer(KB.slice(1, 33)), // x - _bigi2.default.fromBuffer(KB.slice(33, 65)) // y - ); - var r = this.toBuffer(); - var P = KBP.multiply(_bigi2.default.fromBuffer(r)); - var S = P.affineX.toBuffer({ size: 32 }); - /* - the input to sha512 must be exactly 32-bytes, to match the c++ implementation - of get_shared_secret. Right now S will be shorter if the most significant - byte(s) is zero. Pad it back to the full 32-bytes - */ - if (!legacy && S.length < 32) { - var pad = Buffer.alloc(32 - S.length).fill(0); - S = Buffer.concat([pad, S]); - } - - // SHA512 used in ECIES - return (0, _hash.sha512)(S); - }; - - // /** ECIES (does not always match the Point.fromAffine version above) */ - // get_shared_secret(public_key){ - // public_key = toPublic(public_key) - // var P = public_key.Q.multiply( this.d ); - // var S = P.affineX.toBuffer({size: 32}); - // // ECIES, adds an extra sha512 - // return sha512(S); - // } - - /** @throws {Error} - overflow of the key could not be derived */ - - - PrivateKey.prototype.child = function child(offset) { - offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]); - offset = (0, _hash.sha256)(offset); - var c = _bigi2.default.fromBuffer(offset); - - if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again"); - - var derived = this.d.add(c); //.mod(n) - - if (derived.signum() === 0) throw new Error("Child offset derived to an invalid key, try again"); - - return new PrivateKey(derived); - }; - - /* */ - - PrivateKey.prototype.toByteBuffer = function toByteBuffer() { - var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); - this.appendByteBuffer(b); - return b.copy(0, b.offset); - }; - - PrivateKey.fromHex = function fromHex(hex) { - return PrivateKey.fromBuffer(new Buffer(hex, "hex")); - }; - - PrivateKey.prototype.toHex = function toHex() { - return this.toBuffer().toString("hex"); - }; - - /* */ - - - return PrivateKey; -}(); - -exports.default = PrivateKey; - - -var toPublic = function toPublic(data) { - return data == null ? data : data.Q ? data : _PublicKey2.default.fromStringOrThrow(data); -}; -module.exports = exports["default"]; -},{"./PublicKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js","./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js","bs58":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bs58/index.js","deep-equal":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/index.js","ecurve":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _bigi = require("bigi"); - -var _bigi2 = _interopRequireDefault(_bigi); - -var _ecurve = require("ecurve"); - -var _bs = require("bs58"); - -var _hash = require("./hash"); - -var _bitsharesjsWs = require("bitsharesjs-ws"); - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -var _deepEqual = require("deep-equal"); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var secp256k1 = (0, _ecurve.getCurveByName)("secp256k1"); - -var Buffer = require("safe-buffer").Buffer; -var G = secp256k1.G, - n = secp256k1.n; - -var PublicKey = function () { - /** @param {Point} public key */ - function PublicKey(Q) { - _classCallCheck(this, PublicKey); - - this.Q = Q; - } - - PublicKey.fromBinary = function fromBinary(bin) { - return PublicKey.fromBuffer(Buffer.from(bin, "binary")); - }; - - PublicKey.fromBuffer = function fromBuffer(buffer) { - if (buffer.toString("hex") === "000000000000000000000000000000000000000000000000000000000000000000") return new PublicKey(null); - return new PublicKey(_ecurve.Point.decodeFrom(secp256k1, buffer)); - }; - - PublicKey.prototype.toBuffer = function toBuffer() { - var compressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.Q ? this.Q.compressed : null; - - if (this.Q === null) return Buffer.from("000000000000000000000000000000000000000000000000000000000000000000", "hex"); - return this.Q.getEncoded(compressed); - }; - - PublicKey.fromPoint = function fromPoint(point) { - return new PublicKey(point); - }; - - PublicKey.prototype.toUncompressed = function toUncompressed() { - var buf = this.Q.getEncoded(false); - var point = _ecurve.Point.decodeFrom(secp256k1, buf); - return PublicKey.fromPoint(point); - }; - - /** bts::blockchain::address (unique but not a full public key) */ - - - PublicKey.prototype.toBlockchainAddress = function toBlockchainAddress() { - var pub_buf = this.toBuffer(); - var pub_sha = (0, _hash.sha512)(pub_buf); - return (0, _hash.ripemd160)(pub_sha); - }; - - /** Alias for {@link toPublicKeyString} */ - - - PublicKey.prototype.toString = function toString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix; - - return this.toPublicKeyString(address_prefix); - }; - - /** - Full public key - {return} string - */ - - - PublicKey.prototype.toPublicKeyString = function toPublicKeyString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix; - - var pub_buf = this.toBuffer(); - var checksum = (0, _hash.ripemd160)(pub_buf); - var addy = Buffer.concat([pub_buf, checksum.slice(0, 4)]); - return address_prefix + (0, _bs.encode)(addy); - }; - - /** - @arg {string} public_key - like GPHXyz... - @arg {string} address_prefix - like GPH - @return PublicKey or `null` (if the public_key string is invalid) - */ - - - PublicKey.fromPublicKeyString = function fromPublicKeyString(public_key) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix; - - try { - return PublicKey.fromStringOrThrow(public_key, address_prefix); - } catch (e) { - return null; - } - }; - - /** - @arg {string} public_key - like GPHXyz... - @arg {string} address_prefix - like GPH - @throws {Error} if public key is invalid - @return PublicKey - */ - - - PublicKey.fromStringOrThrow = function fromStringOrThrow(public_key) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix; - - if (public_key.Q === null) public_key = address_prefix + "1111111111111111111111111111111114T1Anm"; // null key - var prefix = public_key.slice(0, address_prefix.length); - _assert2.default.equal(address_prefix, prefix, "Expecting key to begin with " + address_prefix + ", instead got " + prefix); - public_key = public_key.slice(address_prefix.length); - - public_key = Buffer.from((0, _bs.decode)(public_key), "binary"); - var checksum = public_key.slice(-4); - public_key = public_key.slice(0, -4); - var new_checksum = (0, _hash.ripemd160)(public_key); - new_checksum = new_checksum.slice(0, 4); - var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); //, 'Invalid checksum' - if (!isEqual) { - throw new Error("Checksum did not match"); - } - return PublicKey.fromBuffer(public_key); - }; - - PublicKey.prototype.toAddressString = function toAddressString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix; - - var pub_buf = this.toBuffer(); - var pub_sha = (0, _hash.sha512)(pub_buf); - var addy = (0, _hash.ripemd160)(pub_sha); - var checksum = (0, _hash.ripemd160)(addy); - addy = Buffer.concat([addy, checksum.slice(0, 4)]); - return address_prefix + (0, _bs.encode)(addy); - }; - - PublicKey.prototype.toPtsAddy = function toPtsAddy() { - var pub_buf = this.toBuffer(); - var pub_sha = (0, _hash.sha256)(pub_buf); - var addy = (0, _hash.ripemd160)(pub_sha); - addy = Buffer.concat([Buffer.from([0x38]), addy]); //version 56(decimal) - - var checksum = (0, _hash.sha256)(addy); - checksum = (0, _hash.sha256)(checksum); - - addy = Buffer.concat([addy, checksum.slice(0, 4)]); - return (0, _bs.encode)(addy); - }; - - PublicKey.prototype.child = function child(offset) { - (0, _assert2.default)(Buffer.isBuffer(offset), "Buffer required: offset"); - _assert2.default.equal(offset.length, 32, "offset length"); - - offset = Buffer.concat([this.toBuffer(), offset]); - offset = (0, _hash.sha256)(offset); - - var c = _bigi2.default.fromBuffer(offset); - - if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again"); - - var cG = G.multiply(c); - var Qprime = this.Q.add(cG); - - if (secp256k1.isInfinity(Qprime)) throw new Error("Child offset derived to an invalid key, try again"); - - return PublicKey.fromPoint(Qprime); - }; - - /* */ - - PublicKey.prototype.toByteBuffer = function toByteBuffer() { - var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); - this.appendByteBuffer(b); - return b.copy(0, b.offset); - }; - - PublicKey.fromHex = function fromHex(hex) { - return PublicKey.fromBuffer(Buffer.from(hex, "hex")); - }; - - PublicKey.prototype.toHex = function toHex() { - return this.toBuffer().toString("hex"); - }; - - PublicKey.fromPublicKeyStringHex = function fromPublicKeyStringHex(hex) { - return PublicKey.fromPublicKeyString(Buffer.from(hex, "hex")); - }; - - /* */ - - - return PublicKey; -}(); - -exports.default = PublicKey; -module.exports = exports["default"]; -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js","bitsharesjs-ws":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/index.js","bs58":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bs58/index.js","deep-equal":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/index.js","ecurve":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/address.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -var _bitsharesjsWs = require("bitsharesjs-ws"); - -var _hash2 = require("./hash"); - -var _bs = require("bs58"); - -var _deepEqual = require("deep-equal"); - -var _deepEqual2 = _interopRequireDefault(_deepEqual); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Buffer = require("safe-buffer").Buffer; - -/** Addresses are shortened non-reversable hashes of a public key. The full PublicKey is preferred. - */ - -var Address = function () { - function Address(addy) { - _classCallCheck(this, Address); - - this.addy = addy; - } - - Address.fromBuffer = function fromBuffer(buffer) { - var _hash = (0, _hash2.sha512)(buffer); - var addy = (0, _hash2.ripemd160)(_hash); - return new Address(addy); - }; - - Address.fromString = function fromString(string) { - var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix; - - var prefix = string.slice(0, address_prefix.length); - _assert2.default.equal(address_prefix, prefix, "Expecting key to begin with " + address_prefix + ", instead got " + prefix); - var addy = string.slice(address_prefix.length); - addy = new Buffer((0, _bs.decode)(addy), "binary"); - var checksum = addy.slice(-4); - addy = addy.slice(0, -4); - var new_checksum = (0, _hash2.ripemd160)(addy); - new_checksum = new_checksum.slice(0, 4); - var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); //, 'Invalid checksum' - if (!isEqual) { - throw new Error("Checksum did not match"); - } - return new Address(addy); - }; - - /** @return Address - Compressed PTS format (by default) */ - - - Address.fromPublic = function fromPublic(public_key) { - var compressed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 56; - - var sha2 = (0, _hash2.sha256)(public_key.toBuffer(compressed)); - var rep = (0, _hash2.ripemd160)(sha2); - var versionBuffer = Buffer.alloc(1); - versionBuffer.writeUInt8(0xff & version, 0); - var addr = Buffer.concat([versionBuffer, rep]); - var check = (0, _hash2.sha256)(addr); - check = (0, _hash2.sha256)(check); - var buffer = Buffer.concat([addr, check.slice(0, 4)]); - return new Address((0, _hash2.ripemd160)(buffer)); - }; - - Address.prototype.toBuffer = function toBuffer() { - return this.addy; - }; - - Address.prototype.toString = function toString() { - var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix; - - var checksum = (0, _hash2.ripemd160)(this.addy); - var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]); - return address_prefix + (0, _bs.encode)(addy); - }; - - return Address; -}(); - -exports.default = Address; -module.exports = exports["default"]; -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bitsharesjs-ws":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/index.js","bs58":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bs58/index.js","deep-equal":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/aes.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _aes = require("crypto-js/aes"); - -var _aes2 = _interopRequireDefault(_aes); - -var _encHex = require("crypto-js/enc-hex"); - -var _encHex2 = _interopRequireDefault(_encHex); - -var _encBase = require("crypto-js/enc-base64"); - -var _encBase2 = _interopRequireDefault(_encBase); - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -var _hash2 = require("./hash"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // https://code.google.com/p/crypto-js - - -var Buffer = require("safe-buffer").Buffer; - -/** Provides symetric encrypt and decrypt via AES. */ - -var Aes = function () { - /** @private */ - function Aes(iv, key) { - _classCallCheck(this, Aes); - - this.iv = iv, this.key = key; - } - - /** This is an excellent way to ensure that all references to Aes can not operate anymore (example: a wallet becomes locked). An application should ensure there is only one Aes object instance for a given secret `seed`. */ - - - Aes.prototype.clear = function clear() { - return this.iv = this.key = undefined; - }; - - /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */ - - - Aes.fromSeed = function fromSeed(seed) { - if (seed === undefined) { - throw new Error("seed is required"); - } - var _hash = (0, _hash2.sha512)(seed); - _hash = _hash.toString("hex"); - // DEBUG console.log('... fromSeed _hash',_hash) - return Aes.fromSha512(_hash); - }; - - /** @arg {string} hash - A 128 byte hex string, typically one would call {@link fromSeed} instead. */ - - - Aes.fromSha512 = function fromSha512(hash) { - _assert2.default.equal(hash.length, 128, "A Sha512 in HEX should be 128 characters long, instead got " + hash.length); - var iv = _encHex2.default.parse(hash.substring(64, 96)); - var key = _encHex2.default.parse(hash.substring(0, 64)); - return new Aes(iv, key); - }; - - Aes.fromBuffer = function fromBuffer(buf) { - (0, _assert2.default)(Buffer.isBuffer(buf), "Expecting Buffer"); - _assert2.default.equal(buf.length, 64, "A Sha512 Buffer should be 64 characters long, instead got " + buf.length); - return Aes.fromSha512(buf.toString("hex")); - }; - /** - @throws {Error} - "Invalid Key, ..." - @arg {PrivateKey} private_key - required and used for decryption - @arg {PublicKey} public_key - required and used to calcualte the shared secret - @arg {string} [nonce = ""] optional but should always be provided and be unique when re-using the same private/public keys more than once. This nonce is not a secret. - @arg {string|Buffer} message - Encrypted message containing a checksum - @return {Buffer} - */ - - - Aes.decrypt_with_checksum = function decrypt_with_checksum(private_key, public_key, nonce, message) { - var legacy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; - - // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string - if (nonce == null) - // null or undefined - nonce = ""; - - if (!Buffer.isBuffer(message)) { - message = new Buffer(message, "hex"); - } - - var S = private_key.get_shared_secret(public_key, legacy); - // D E B U G - // console.log('decrypt_with_checksum', { - // priv_to_pub: private_key.toPublicKey().toString(), - // pub: public_key.toPublicKeyString(), - // nonce: nonce, - // message: message.length, - // S: S.toString('hex') - // }) - - var aes = Aes.fromSeed(Buffer.concat([ - // A null or empty string nonce will not effect the hash - Buffer.from("" + nonce), Buffer.from(S.toString("hex"))])); - - var planebuffer = aes.decrypt(message); - if (!(planebuffer.length >= 4)) { - throw new Error("Invalid key, could not decrypt message(1)"); - } - - // DEBUG console.log('... planebuffer',planebuffer) - var checksum = planebuffer.slice(0, 4); - var plaintext = planebuffer.slice(4); - - // console.log('... checksum',checksum.toString('hex')) - // console.log('... plaintext',plaintext.toString()) - - var new_checksum = (0, _hash2.sha256)(plaintext); - new_checksum = new_checksum.slice(0, 4); - new_checksum = new_checksum.toString("hex"); - - if (!(checksum.toString("hex") === new_checksum)) { - throw new Error("Invalid key, could not decrypt message(2)"); - } - - return plaintext; - }; - - /** Identical to {@link decrypt_with_checksum} but used to encrypt. Should not throw an error. - @return {Buffer} message - Encrypted message which includes a checksum - */ - - - Aes.encrypt_with_checksum = function encrypt_with_checksum(private_key, public_key, nonce, message) { - // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string - - if (nonce == null) - // null or undefined - nonce = ""; - - if (!Buffer.isBuffer(message)) { - message = new Buffer(message, "binary"); - } - - var S = private_key.get_shared_secret(public_key); - - // D E B U G - // console.log('encrypt_with_checksum', { - // priv_to_pub: private_key.toPublicKey().toString() - // pub: public_key.toPublicKeyString() - // nonce: nonce - // message: message.length - // S: S.toString('hex') - // }) - - var aes = Aes.fromSeed(Buffer.concat([ - // A null or empty string nonce will not effect the hash - Buffer.from("" + nonce), Buffer.from(S.toString("hex"))])); - // DEBUG console.log('... S',S.toString('hex')) - var checksum = (0, _hash2.sha256)(message).slice(0, 4); - var payload = Buffer.concat([checksum, message]); - // DEBUG console.log('... payload',payload.toString()) - return aes.encrypt(payload); - }; - - /** @private */ - - - Aes.prototype._decrypt_word_array = function _decrypt_word_array(cipher) { - // https://code.google.com/p/crypto-js/#Custom_Key_and_IV - // see wallet_records.cpp master_key::decrypt_key - return _aes2.default.decrypt({ ciphertext: cipher, salt: null }, this.key, { - iv: this.iv - }); - }; - - /** @private */ - - - Aes.prototype._encrypt_word_array = function _encrypt_word_array(plaintext) { - //https://code.google.com/p/crypto-js/issues/detail?id=85 - var cipher = _aes2.default.encrypt(plaintext, this.key, { iv: this.iv }); - return _encBase2.default.parse(cipher.toString()); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} ciphertext - @return {Buffer} binary - */ - - - Aes.prototype.decrypt = function decrypt(ciphertext) { - if (typeof ciphertext === "string") { - ciphertext = new Buffer(ciphertext, "binary"); - } - if (!Buffer.isBuffer(ciphertext)) { - throw new Error("buffer required"); - } - (0, _assert2.default)(ciphertext, "Missing cipher text"); - // hex is the only common format - var hex = this.decryptHex(ciphertext.toString("hex")); - return new Buffer(hex, "hex"); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} plaintext - @return {Buffer} binary - */ - - - Aes.prototype.encrypt = function encrypt(plaintext) { - if (typeof plaintext === "string") { - plaintext = new Buffer(plaintext, "binary"); - } - if (!Buffer.isBuffer(plaintext)) { - throw new Error("buffer required"); - } - //assert plaintext, "Missing plain text" - // hex is the only common format - var hex = this.encryptHex(plaintext.toString("hex")); - return new Buffer(hex, "hex"); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string|Buffer} plaintext - @return {string} hex - */ - - - Aes.prototype.encryptToHex = function encryptToHex(plaintext) { - if (typeof plaintext === "string") { - plaintext = new Buffer(plaintext, "binary"); - } - if (!Buffer.isBuffer(plaintext)) { - throw new Error("buffer required"); - } - //assert plaintext, "Missing plain text" - // hex is the only common format - return this.encryptHex(plaintext.toString("hex")); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} cipher - hex - @return {string} binary (could easily be readable text) - */ - - - Aes.prototype.decryptHex = function decryptHex(cipher) { - (0, _assert2.default)(cipher, "Missing cipher text"); - // Convert data into word arrays (used by Crypto) - var cipher_array = _encHex2.default.parse(cipher); - var plainwords = this._decrypt_word_array(cipher_array); - return _encHex2.default.stringify(plainwords); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} cipher - hex - @return {Buffer} encoded as specified by the parameter - */ - - - Aes.prototype.decryptHexToBuffer = function decryptHexToBuffer(cipher) { - (0, _assert2.default)(cipher, "Missing cipher text"); - // Convert data into word arrays (used by Crypto) - var cipher_array = _encHex2.default.parse(cipher); - var plainwords = this._decrypt_word_array(cipher_array); - var plainhex = _encHex2.default.stringify(plainwords); - return new Buffer(plainhex, "hex"); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} cipher - hex - @arg {string} [encoding = 'binary'] - a valid Buffer encoding - @return {String} encoded as specified by the parameter - */ - - - Aes.prototype.decryptHexToText = function decryptHexToText(cipher) { - var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "binary"; - - return this.decryptHexToBuffer(cipher).toString(encoding); - }; - - /** This method does not use a checksum, the returned data must be validated some other way. - @arg {string} plainhex - hex format - @return {String} hex - */ - - - Aes.prototype.encryptHex = function encryptHex(plainhex) { - var plain_array = _encHex2.default.parse(plainhex); - var cipher_array = this._encrypt_word_array(plain_array); - return _encHex2.default.stringify(cipher_array); - }; - - return Aes; -}(); - -exports.default = Aes; -module.exports = exports["default"]; -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","crypto-js/aes":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/aes.js","crypto-js/enc-base64":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-base64.js","crypto-js/enc-hex":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-hex.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/ecdsa.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.verifyRaw = exports.verify = exports.sign = exports.recoverPubKey = exports.deterministicGenerateK = exports.calcPubKeyRecoveryParam = undefined; - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -var _hash = require("./hash"); - -var _enforce_types = require("./enforce_types"); - -var _enforce_types2 = _interopRequireDefault(_enforce_types); - -var _bigi = require("bigi"); - -var _bigi2 = _interopRequireDefault(_bigi); - -var _ecsignature = require("./ecsignature"); - -var _ecsignature2 = _interopRequireDefault(_ecsignature); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa -var Buffer = require("safe-buffer").Buffer; - -// https://tools.ietf.org/html/rfc6979#section-3.2 -function deterministicGenerateK(curve, hash, d, checkSig, nonce) { - (0, _enforce_types2.default)("Buffer", hash); - (0, _enforce_types2.default)(_bigi2.default, d); - - if (nonce) { - hash = (0, _hash.sha256)(Buffer.concat([hash, Buffer.alloc(nonce)])); - } - - // sanity check - _assert2.default.equal(hash.length, 32, "Hash must be 256 bit"); - - var x = d.toBuffer(32); - var k = Buffer.alloc(32); - var v = Buffer.alloc(32); - - // Step B - v.fill(1); - - // Step C - k.fill(0); - - // Step D - k = (0, _hash.HmacSHA256)(Buffer.concat([v, new Buffer([0]), x, hash]), k); - - // Step E - v = (0, _hash.HmacSHA256)(v, k); - - // Step F - k = (0, _hash.HmacSHA256)(Buffer.concat([v, new Buffer([1]), x, hash]), k); - - // Step G - v = (0, _hash.HmacSHA256)(v, k); - - // Step H1/H2a, ignored as tlen === qlen (256 bit) - // Step H2b - v = (0, _hash.HmacSHA256)(v, k); - - var T = _bigi2.default.fromBuffer(v); - - // Step H3, repeat until T is within the interval [1, n - 1] - while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) { - k = (0, _hash.HmacSHA256)(Buffer.concat([v, new Buffer([0])]), k); - v = (0, _hash.HmacSHA256)(v, k); - - // Step H1/H2a, again, ignored as tlen === qlen (256 bit) - // Step H2b again - v = (0, _hash.HmacSHA256)(v, k); - - T = _bigi2.default.fromBuffer(v); - } - - return T; -} - -function sign(curve, hash, d, nonce) { - var e = _bigi2.default.fromBuffer(hash); - var n = curve.n; - var G = curve.G; - - var r = void 0, - s = void 0; - - deterministicGenerateK(curve, hash, d, function (k) { - // find canonically valid signature - var Q = G.multiply(k); - - if (curve.isInfinity(Q)) return false; - - r = Q.affineX.mod(n); - if (r.signum() === 0) return false; - - s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n); - if (s.signum() === 0) return false; - - return true; - }, nonce); - - var N_OVER_TWO = n.shiftRight(1); - - // enforce low S values, see bip62: 'low s values in signatures' - if (s.compareTo(N_OVER_TWO) > 0) { - s = n.subtract(s); - } - - return new _ecsignature2.default(r, s); -} - -function verifyRaw(curve, e, signature, Q) { - var n = curve.n; - var G = curve.G; - - var r = signature.r; - var s = signature.s; - - // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] - if (r.signum() <= 0 || r.compareTo(n) >= 0) return false; - if (s.signum() <= 0 || s.compareTo(n) >= 0) return false; - - // c = s^-1 mod n - var c = s.modInverse(n); - - // 1.4.4 Compute u1 = es^−1 mod n - // u2 = rs^−1 mod n - var u1 = e.multiply(c).mod(n); - var u2 = r.multiply(c).mod(n); - - // 1.4.5 Compute R = (xR, yR) = u1G + u2Q - var R = G.multiplyTwo(u1, Q, u2); - - // 1.4.5 (cont.) Enforce R is not at infinity - if (curve.isInfinity(R)) return false; - - // 1.4.6 Convert the field element R.x to an integer - var xR = R.affineX; - - // 1.4.7 Set v = xR mod n - var v = xR.mod(n); - - // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" - return v.equals(r); -} - -function verify(curve, hash, signature, Q) { - // 1.4.2 H = Hash(M), already done by the user - // 1.4.3 e = H - var e = _bigi2.default.fromBuffer(hash); - return verifyRaw(curve, e, signature, Q); -} - -/** - * Recover a public key from a signature. - * - * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public - * Key Recovery Operation". - * - * http://www.secg.org/download/aid-780/sec1-v2.pdf - */ -function recoverPubKey(curve, e, signature, i) { - _assert2.default.strictEqual(i & 3, i, "Recovery param is more than two bits"); - - var n = curve.n; - var G = curve.G; - - var r = signature.r; - var s = signature.s; - - (0, _assert2.default)(r.signum() > 0 && r.compareTo(n) < 0, "Invalid r value"); - (0, _assert2.default)(s.signum() > 0 && s.compareTo(n) < 0, "Invalid s value"); - - // A set LSB signifies that the y-coordinate is odd - var isYOdd = i & 1; - - // The more significant bit specifies whether we should use the - // first or second candidate key. - var isSecondKey = i >> 1; - - // 1.1 Let x = r + jn - var x = isSecondKey ? r.add(n) : r; - var R = curve.pointFromX(isYOdd, x); - - // 1.4 Check that nR is at infinity - var nR = R.multiply(n); - (0, _assert2.default)(curve.isInfinity(nR), "nR is not a valid curve point"); - - // Compute -e from e - var eNeg = e.negate().mod(n); - - // 1.6.1 Compute Q = r^-1 (sR - eG) - // Q = r^-1 (sR + -eG) - var rInv = r.modInverse(n); - - var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); - curve.validate(Q); - - return Q; -} - -/** - * Calculate pubkey extraction parameter. - * - * When extracting a pubkey from a signature, we have to - * distinguish four different cases. Rather than putting this - * burden on the verifier, Bitcoin includes a 2-bit value with the - * signature. - * - * This function simply tries all four cases and returns the value - * that resulted in a successful pubkey recovery. - */ -function calcPubKeyRecoveryParam(curve, e, signature, Q) { - for (var i = 0; i < 4; i++) { - var Qprime = recoverPubKey(curve, e, signature, i); - - // 1.6.2 Verify Q - if (Qprime.equals(Q)) { - return i; - } - } - - throw new Error("Unable to find valid recovery factor"); -} - -exports.calcPubKeyRecoveryParam = calcPubKeyRecoveryParam; -exports.deterministicGenerateK = deterministicGenerateK; -exports.recoverPubKey = recoverPubKey; -exports.sign = sign; -exports.verify = verify; -exports.verifyRaw = verifyRaw; -},{"./ecsignature":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/ecsignature.js","./enforce_types":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/enforce_types.js","./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/ecsignature.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -var _enforce_types = require("./enforce_types"); - -var _enforce_types2 = _interopRequireDefault(_enforce_types); - -var _bigi = require("bigi"); - -var _bigi2 = _interopRequireDefault(_bigi); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// from https://github.com/bitcoinjs/bitcoinjs-lib -var Buffer = require("safe-buffer").Buffer; - -function ECSignature(r, s) { - (0, _enforce_types2.default)(_bigi2.default, r); - (0, _enforce_types2.default)(_bigi2.default, s); - - this.r = r; - this.s = s; -} - -// Import operations -ECSignature.parseCompact = function (buffer) { - _assert2.default.equal(buffer.length, 65, "Invalid signature length"); - var i = buffer.readUInt8(0) - 27; - - // At most 3 bits - _assert2.default.equal(i, i & 7, "Invalid signature parameter"); - var compressed = !!(i & 4); - - // Recovery param only - i = i & 3; - - var r = _bigi2.default.fromBuffer(buffer.slice(1, 33)); - var s = _bigi2.default.fromBuffer(buffer.slice(33)); - - return { - compressed: compressed, - i: i, - signature: new ECSignature(r, s) - }; -}; - -ECSignature.fromDER = function (buffer) { - _assert2.default.equal(buffer.readUInt8(0), 0x30, "Not a DER sequence"); - _assert2.default.equal(buffer.readUInt8(1), buffer.length - 2, "Invalid sequence length"); - _assert2.default.equal(buffer.readUInt8(2), 0x02, "Expected a DER integer"); - - var rLen = buffer.readUInt8(3); - (0, _assert2.default)(rLen > 0, "R length is zero"); - - var offset = 4 + rLen; - _assert2.default.equal(buffer.readUInt8(offset), 0x02, "Expected a DER integer (2)"); - - var sLen = buffer.readUInt8(offset + 1); - (0, _assert2.default)(sLen > 0, "S length is zero"); - - var rB = buffer.slice(4, offset); - var sB = buffer.slice(offset + 2); - offset += 2 + sLen; - - if (rLen > 1 && rB.readUInt8(0) === 0x00) { - (0, _assert2.default)(rB.readUInt8(1) & 0x80, "R value excessively padded"); - } - - if (sLen > 1 && sB.readUInt8(0) === 0x00) { - (0, _assert2.default)(sB.readUInt8(1) & 0x80, "S value excessively padded"); - } - - _assert2.default.equal(offset, buffer.length, "Invalid DER encoding"); - var r = _bigi2.default.fromDERInteger(rB); - var s = _bigi2.default.fromDERInteger(sB); - - (0, _assert2.default)(r.signum() >= 0, "R value is negative"); - (0, _assert2.default)(s.signum() >= 0, "S value is negative"); - - return new ECSignature(r, s); -}; - -// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, importing Transaction causes a circular dependency -ECSignature.parseScriptSignature = function (buffer) { - var hashType = buffer.readUInt8(buffer.length - 1); - var hashTypeMod = hashType & ~0x80; - - (0, _assert2.default)(hashTypeMod > 0x00 && hashTypeMod < 0x04, "Invalid hashType"); - - return { - signature: ECSignature.fromDER(buffer.slice(0, -1)), - hashType: hashType - }; -}; - -// Export operations -ECSignature.prototype.toCompact = function (i, compressed) { - if (compressed) i += 4; - i += 27; - - var buffer = Buffer.alloc(65); - buffer.writeUInt8(i, 0); - - this.r.toBuffer(32).copy(buffer, 1); - this.s.toBuffer(32).copy(buffer, 33); - - return buffer; -}; - -ECSignature.prototype.toDER = function () { - var rBa = this.r.toDERInteger(); - var sBa = this.s.toDERInteger(); - - var sequence = []; - - // INTEGER - sequence.push(0x02, rBa.length); - sequence = sequence.concat(rBa); - - // INTEGER - sequence.push(0x02, sBa.length); - sequence = sequence.concat(sBa); - - // SEQUENCE - sequence.unshift(0x30, sequence.length); - - return Buffer.from(sequence); -}; - -ECSignature.prototype.toScriptSignature = function (hashType) { - var hashTypeBuffer = Buffer.alloc(1); - hashTypeBuffer.writeUInt8(hashType, 0); - - return Buffer.concat([this.toDER(), hashTypeBuffer]); -}; - -exports.default = ECSignature; -module.exports = exports["default"]; -},{"./enforce_types":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/enforce_types.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/enforce_types.js":[function(require,module,exports){ -(function (Buffer){ -"use strict"; - -exports.__esModule = true; -exports.default = enforce; -function enforce(type, value) { - // Copied from https://github.com/bitcoinjs/bitcoinjs-lib - switch (type) { - case "Array": - { - if (Array.isArray(value)) return; - break; - } - - case "Boolean": - { - if (typeof value === "boolean") return; - break; - } - - case "Buffer": - { - if (Buffer.isBuffer(value)) return; - break; - } - - case "Number": - { - if (typeof value === "number") return; - break; - } - - case "String": - { - if (typeof value === "string") return; - break; - } - - default: - { - if (getName(value.constructor) === getName(type)) return; - } - } - - throw new TypeError("Expected " + (getName(type) || type) + ", got " + value); -} - -function getName(fn) { - // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property - var match = fn.toString().match(/function (.*?)\(/); - return match ? match[1] : null; -} -module.exports = exports["default"]; -}).call(this,{"isBuffer":require("../../../node_modules/is-buffer/index.js")}) - -},{"../../../node_modules/is-buffer/index.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/is-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.ripemd160 = exports.HmacSHA256 = exports.sha512 = exports.sha256 = exports.sha1 = undefined; - -var _createHash = require("create-hash"); - -var _createHash2 = _interopRequireDefault(_createHash); - -var _createHmac = require("create-hmac"); - -var _createHmac2 = _interopRequireDefault(_createHmac); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** @arg {string|Buffer} data - @arg {string} [digest = null] - 'hex', 'binary' or 'base64' - @return {string|Buffer} - Buffer when digest is null, or string -*/ -function sha1(data, encoding) { - return (0, _createHash2.default)("sha1").update(data).digest(encoding); -} - -/** @arg {string|Buffer} data - @arg {string} [digest = null] - 'hex', 'binary' or 'base64' - @return {string|Buffer} - Buffer when digest is null, or string -*/ -function sha256(data, encoding) { - return (0, _createHash2.default)("sha256").update(data).digest(encoding); -} - -/** @arg {string|Buffer} data - @arg {string} [digest = null] - 'hex', 'binary' or 'base64' - @return {string|Buffer} - Buffer when digest is null, or string -*/ -function sha512(data, encoding) { - return (0, _createHash2.default)("sha512").update(data).digest(encoding); -} - -function HmacSHA256(buffer, secret) { - return (0, _createHmac2.default)("sha256", secret).update(buffer).digest(); -} - -function ripemd160(data) { - return (0, _createHash2.default)("rmd160").update(data).digest(); -} - -// function hash160(buffer) { -// return ripemd160(sha256(buffer)) -// } -// -// function hash256(buffer) { -// return sha256(sha256(buffer)) -// } - -// -// function HmacSHA512(buffer, secret) { -// return crypto.createHmac('sha512', secret).update(buffer).digest() -// } - -exports.sha1 = sha1; -exports.sha256 = sha256; -exports.sha512 = sha512; -exports.HmacSHA256 = HmacSHA256; -exports.ripemd160 = ripemd160; -},{"create-hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hash/browser.js","create-hmac":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hmac/browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/signature.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _ecdsa = require("./ecdsa"); - -var _hash2 = require("./hash"); - -var _ecurve = require("ecurve"); - -var _assert = require("assert"); - -var _assert2 = _interopRequireDefault(_assert); - -var _bigi = require("bigi"); - -var _bigi2 = _interopRequireDefault(_bigi); - -var _PublicKey = require("./PublicKey"); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var secp256k1 = (0, _ecurve.getCurveByName)("secp256k1"); - -var Buffer = require("safe-buffer").Buffer; - -var Signature = function () { - function Signature(r1, s1, i1) { - _classCallCheck(this, Signature); - - this.r = r1; - this.s = s1; - this.i = i1; - _assert2.default.equal(this.r != null, true, "Missing parameter"); - _assert2.default.equal(this.s != null, true, "Missing parameter"); - _assert2.default.equal(this.i != null, true, "Missing parameter"); - } - - Signature.fromBuffer = function fromBuffer(buf) { - var i, r, s; - _assert2.default.equal(buf.length, 65, "Invalid signature length"); - i = buf.readUInt8(0); - _assert2.default.equal(i - 27, i - 27 & 7, "Invalid signature parameter"); - r = _bigi2.default.fromBuffer(buf.slice(1, 33)); - s = _bigi2.default.fromBuffer(buf.slice(33)); - return new Signature(r, s, i); - }; - - Signature.prototype.toBuffer = function toBuffer() { - var buf; - buf = Buffer.alloc(65); - buf.writeUInt8(this.i, 0); - this.r.toBuffer(32).copy(buf, 1); - this.s.toBuffer(32).copy(buf, 33); - return buf; - }; - - Signature.prototype.recoverPublicKeyFromBuffer = function recoverPublicKeyFromBuffer(buffer) { - return this.recoverPublicKey((0, _hash2.sha256)(buffer)); - }; - - /** - @return {PublicKey} - */ - - - Signature.prototype.recoverPublicKey = function recoverPublicKey(sha256_buffer) { - var Q = void 0, - e = void 0, - i = void 0; - e = _bigi2.default.fromBuffer(sha256_buffer); - i = this.i; - i -= 27; - i = i & 3; - Q = (0, _ecdsa.recoverPubKey)(secp256k1, e, this, i); - return _PublicKey2.default.fromPoint(Q); - }; - - /** - @param {Buffer} buf - @param {PrivateKey} private_key - @return {Signature} - */ - - - Signature.signBuffer = function signBuffer(buf, private_key) { - var _hash = (0, _hash2.sha256)(buf); - return Signature.signBufferSha256(_hash, private_key); - }; - - /** Sign a buffer of exactally 32 bytes in size (sha256(text)) - @param {Buffer} buf - 32 bytes binary - @param {PrivateKey} private_key - @return {Signature} - */ - - - Signature.signBufferSha256 = function signBufferSha256(buf_sha256, private_key) { - if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) throw new Error("buf_sha256: 32 byte buffer requred"); - var der, e, ecsignature, i, lenR, lenS, nonce; - i = null; - nonce = 0; - e = _bigi2.default.fromBuffer(buf_sha256); - while (true) { - ecsignature = (0, _ecdsa.sign)(secp256k1, buf_sha256, private_key.d, nonce++); - der = ecsignature.toDER(); - lenR = der[3]; - lenS = der[5 + lenR]; - if (lenR === 32 && lenS === 32) { - i = (0, _ecdsa.calcPubKeyRecoveryParam)(secp256k1, e, ecsignature, private_key.toPublicKey().Q); - i += 4; // compressed - i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) - break; - } - if (nonce % 10 === 0) { - console.log("WARN: " + nonce + " attempts to find canonical signature"); - } - } - return new Signature(ecsignature.r, ecsignature.s, i); - }; - - Signature.sign = function sign(string, private_key) { - return Signature.signBuffer(Buffer.from(string), private_key); - }; - - /** - @param {Buffer} un-hashed - @param {./PublicKey} - @return {boolean} - */ - - - Signature.prototype.verifyBuffer = function verifyBuffer(buf, public_key) { - var _hash = (0, _hash2.sha256)(buf); - return this.verifyHash(_hash, public_key); - }; - - Signature.prototype.verifyHash = function verifyHash(hash, public_key) { - _assert2.default.equal(hash.length, 32, "A SHA 256 should be 32 bytes long, instead got " + hash.length); - return (0, _ecdsa.verify)(secp256k1, hash, { - r: this.r, - s: this.s - }, public_key.Q); - }; - - /* */ - - Signature.prototype.toByteBuffer = function toByteBuffer() { - var b; - b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); - this.appendByteBuffer(b); - return b.copy(0, b.offset); - }; - - Signature.fromHex = function fromHex(hex) { - return Signature.fromBuffer(Buffer.from(hex, "hex")); - }; - - Signature.prototype.toHex = function toHex() { - return this.toBuffer().toString("hex"); - }; - - Signature.signHex = function signHex(hex, private_key) { - var buf; - buf = Buffer.from(hex, "hex"); - return Signature.signBuffer(buf, private_key); - }; - - Signature.prototype.verifyHex = function verifyHex(hex, public_key) { - var buf; - buf = Buffer.from(hex, "hex"); - return this.verifyBuffer(buf, public_key); - }; - - return Signature; -}(); - -exports.default = Signature; -module.exports = exports["default"]; -},{"./PublicKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js","./ecdsa":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/ecdsa.js","./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/hash.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js","ecurve":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/index.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.SerializerValidation = exports.template = exports.ops = exports.types = exports.fp = exports.Serializer = undefined; - -var _serializer = require("./src/serializer"); - -var _serializer2 = _interopRequireDefault(_serializer); - -var _FastParser = require("./src/FastParser"); - -var _FastParser2 = _interopRequireDefault(_FastParser); - -var _types = require("./src/types"); - -var _types2 = _interopRequireDefault(_types); - -var _operations = require("./src/operations"); - -var ops = _interopRequireWildcard(_operations); - -var _template = require("./src/template"); - -var _template2 = _interopRequireDefault(_template); - -var _SerializerValidation = require("./src/SerializerValidation"); - -var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.Serializer = _serializer2.default; -exports.fp = _FastParser2.default; -exports.types = _types2.default; -exports.ops = ops; -exports.template = _template2.default; -exports.SerializerValidation = _SerializerValidation2.default; -},{"./src/FastParser":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/FastParser.js","./src/SerializerValidation":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/SerializerValidation.js","./src/operations":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/operations.js","./src/serializer":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/serializer.js","./src/template":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/template.js","./src/types":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/types.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/FastParser.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _PublicKey = require("../../ecc/src/PublicKey"); - -var _PublicKey2 = _interopRequireDefault(_PublicKey); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Buffer = require("safe-buffer").Buffer; - -var FastParser = function () { - function FastParser() { - _classCallCheck(this, FastParser); - } - - FastParser.fixed_data = function fixed_data(b, len, buffer) { - if (!b) { - return; - } - if (buffer) { - var data = buffer.slice(0, len).toString("binary"); - b.append(data, "binary"); - while (len-- > data.length) { - b.writeUint8(0); - } - } else { - var b_copy = b.copy(b.offset, b.offset + len); - b.skip(len); - return Buffer.from(b_copy.toBinary(), "binary"); - } - }; - - FastParser.public_key = function public_key(b, _public_key) { - if (!b) { - return; - } - if (_public_key) { - var buffer = _public_key.toBuffer(); - b.append(buffer.toString("binary"), "binary"); - return; - } else { - buffer = FastParser.fixed_data(b, 33); - return _PublicKey2.default.fromBuffer(buffer); - } - }; - - FastParser.ripemd160 = function ripemd160(b, _ripemd) { - if (!b) { - return; - } - if (_ripemd) { - FastParser.fixed_data(b, 20, _ripemd); - return; - } else { - return FastParser.fixed_data(b, 20); - } - }; - - FastParser.time_point_sec = function time_point_sec(b, epoch) { - if (epoch) { - epoch = Math.ceil(epoch / 1000); - b.writeInt32(epoch); - return; - } else { - epoch = b.readInt32(); // fc::time_point_sec - return new Date(epoch * 1000); - } - }; - - return FastParser; -}(); - -exports.default = FastParser; -module.exports = exports["default"]; -},{"../../ecc/src/PublicKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/SerializerValidation.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -var _bytebuffer = require("bytebuffer"); - -var _ChainTypes = require("../../chain/src/ChainTypes"); - -var _ChainTypes2 = _interopRequireDefault(_ChainTypes); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var MAX_SAFE_INT = 9007199254740991; -var MIN_SAFE_INT = -9007199254740991; - -/** - Most validations are skipped and the value returned unchanged when an empty string, null, or undefined is encountered (except "required"). - - Validations support a string format for dealing with large numbers. -*/ -var _my = { - is_empty: function is_empty(value) { - return value === null || value === undefined; - }, - - required: function required(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (this.is_empty(value)) { - throw new Error("value required " + field_name + " " + value); - } - return value; - }, - - require_array: function require_array(value, instance_require) { - if (!(value instanceof Array)) { - throw new Error("array required"); - } - if (instance_require) { - value.forEach(function (i) { - instance_require(i); - }); - } - return value; - }, - require_long: function require_long(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (!_bytebuffer.Long.isLong(value)) { - throw new Error("Long value required " + field_name + " " + value); - } - return value; - }, - string: function string(value) { - if (this.is_empty(value)) { - return value; - } - if (typeof value !== "string") { - throw new Error("string required: " + value); - } - return value; - }, - number: function number(value) { - if (this.is_empty(value)) { - return value; - } - if (typeof value !== "number") { - throw new Error("number required: " + value); - } - return value; - }, - whole_number: function whole_number(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (this.is_empty(value)) { - return value; - } - if (/\./.test(value)) { - throw new Error("whole number required " + field_name + " " + value); - } - return value; - }, - unsigned: function unsigned(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (this.is_empty(value)) { - return value; - } - if (/-/.test(value)) { - throw new Error("unsigned required " + field_name + " " + value); - } - return value; - }, - - - is_digits: function is_digits(value) { - if (typeof value === "numeric") { - return true; - } - return (/^[0-9]+$/.test(value) - ); - }, - - to_number: function to_number(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (this.is_empty(value)) { - return value; - } - this.no_overflow53(value, field_name); - var int_value = function () { - if (typeof value === "number") { - return value; - } else { - return parseInt(value); - } - }(); - return int_value; - }, - - to_long: function to_long(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - var unsigned = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - if (this.is_empty(value)) { - return value; - } - if (_bytebuffer.Long.isLong(value)) { - return value; - } - - this.no_overflow64(value, field_name, unsigned); - if (typeof value === "number") { - value = "" + value; - } - return _bytebuffer.Long.fromString(value, unsigned); - }, - to_string: function to_string(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (this.is_empty(value)) { - return value; - } - if (typeof value === "string") { - return value; - } - if (typeof value === "number") { - this.no_overflow53(value, field_name); - return "" + value; - } - if (_bytebuffer.Long.isLong(value)) { - return value.toString(); - } - throw "unsupported type " + field_name + ": (" + (typeof value === "undefined" ? "undefined" : _typeof(value)) + ") " + value; - }, - require_test: function require_test(regex, value) { - var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; - - if (this.is_empty(value)) { - return value; - } - if (!regex.test(value)) { - throw new Error("unmatched " + regex + " " + field_name + " " + value); - } - return value; - }, - - - require_match: function require_match(regex, value) { - var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ""; - - if (this.is_empty(value)) { - return value; - } - var match = value.match(regex); - if (match === null) { - throw new Error("unmatched " + regex + " " + field_name + " " + value); - } - return match; - }, - - require_object_id: function require_object_id(value, field_name) { - return require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, value, field_name); - }, - - // Does not support over 53 bits - require_range: function require_range(min, max, value) { - var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ""; - - if (this.is_empty(value)) { - return value; - } - var number = this.to_number(value); - if (value < min || value > max) { - throw new Error("out of range " + value + " " + field_name + " " + value); - } - return value; - }, - - - require_object_type: function require_object_type() { - var reserved_spaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; - var type = arguments[1]; - var value = arguments[2]; - var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ""; - - if (this.is_empty(value)) { - return value; - } - var object_type = _ChainTypes2.default.object_type[type]; - if (!object_type) { - throw new Error("Unknown object type " + type + " " + field_name + " " + value); - } - var re = new RegExp(reserved_spaces + "." + object_type + ".[0-9]+$"); - if (!re.test(value)) { - throw new Error("Expecting " + type + " in format " + (reserved_spaces + "." + object_type + ".[0-9]+ ") + ("instead of " + value + " " + field_name + " " + value)); - } - return value; - }, - - get_instance: function get_instance(reserve_spaces, type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - this.require_object_type(reserve_spaces, type, value, field_name); - return this.to_number(value.split(".")[2]); - }, - - require_relative_type: function require_relative_type(type, value, field_name) { - this.require_object_type(0, type, value, field_name); - return value; - }, - - get_relative_instance: function get_relative_instance(type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - this.require_object_type(0, type, value, field_name); - return this.to_number(value.split(".")[2]); - }, - - require_protocol_type: function require_protocol_type(type, value, field_name) { - this.require_object_type(1, type, value, field_name); - return value; - }, - - get_protocol_instance: function get_protocol_instance(type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - this.require_object_type(1, type, value, field_name); - return this.to_number(value.split(".")[2]); - }, - - get_protocol_type: function get_protocol_type(value, field_name) { - if (this.is_empty(value)) { - return value; - } - this.require_object_id(value, field_name); - var values = value.split("."); - return this.to_number(values[1]); - }, - - get_protocol_type_name: function get_protocol_type_name(value, field_name) { - if (this.is_empty(value)) { - return value; - } - var type_id = this.get_protocol_type(value, field_name); - return Object.keys(_ChainTypes2.default.object_type)[type_id]; - }, - - - require_implementation_type: function require_implementation_type(type, value, field_name) { - this.require_object_type(2, type, value, field_name); - return value; - }, - - get_implementation_instance: function get_implementation_instance(type, value, field_name) { - if (this.is_empty(value)) { - return value; - } - this.require_object_type(2, type, value, field_name); - return this.to_number(value.split(".")[2]); - }, - - // signed / unsigned decimal - no_overflow53: function no_overflow53(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - if (typeof value === "number") { - if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { - throw new Error("overflow " + field_name + " " + value); - } - return; - } - if (typeof value === "string") { - var int = parseInt(value); - if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { - throw new Error("overflow " + field_name + " " + value); - } - return; - } - if (_bytebuffer.Long.isLong(value)) { - // typeof value.toInt() is 'number' - this.no_overflow53(value.toInt(), field_name); - return; - } - throw "unsupported type " + field_name + ": (" + (typeof value === "undefined" ? "undefined" : _typeof(value)) + ") " + value; - }, - - - // signed / unsigned whole numbers only - no_overflow64: function no_overflow64(value) { - var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - var unsigned = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - // https://github.com/dcodeIO/Long.js/issues/20 - if (_bytebuffer.Long.isLong(value)) { - return; - } - - // BigInteger#isBigInteger https://github.com/cryptocoinjs/bigi/issues/20 - if (value.t !== undefined && value.s !== undefined) { - this.no_overflow64(value.toString(), field_name, unsigned); - return; - } - - if (typeof value === "string") { - // remove leading zeros, will cause a false positive - value = value.replace(/^0+/, ""); - // remove trailing zeros - while (/0$/.test(value)) { - value = value.substring(0, value.length - 1); - } - if (/\.$/.test(value)) { - // remove trailing dot - value = value.substring(0, value.length - 1); - } - if (value === "") { - value = "0"; - } - var long_string = _bytebuffer.Long.fromString(value, unsigned).toString(); - if (long_string !== value.trim()) { - throw new Error("overflow " + field_name + " " + value); - } - return; - } - if (typeof value === "number") { - if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) { - throw new Error("overflow " + field_name + " " + value); - } - return; - } - - throw "unsupported type " + field_name + ": (" + (typeof value === "undefined" ? "undefined" : _typeof(value)) + ") " + value; - } -}; - -exports.default = _my; -module.exports = exports["default"]; -},{"../../chain/src/ChainTypes":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/chain/src/ChainTypes.js","bytebuffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bytebuffer/dist/bytebuffer.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/error_with_cause.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -/** Exception nesting. */ -var ErrorWithCause = function () { - function ErrorWithCause(message, cause) { - _classCallCheck(this, ErrorWithCause); - - this.message = message; - if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) { - this.message = "cause\t" + cause.message + "\t" + this.message; - } - - var stack = ""; //(new Error).stack - if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) { - stack = "caused by\n\t" + cause.stack + "\t" + stack; - } - - this.stack = this.message + "\n" + stack; - } - - ErrorWithCause.throw = function _throw(message, cause) { - var msg = message; - if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) { - msg += "\t cause: " + cause.message + " "; - } - if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) { - msg += "\n stack: " + cause.stack + " "; - } - throw new Error(msg); - }; - - return ErrorWithCause; -}(); - -exports.default = ErrorWithCause; -module.exports = exports["default"]; -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/operations.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.stealth_memo_data = exports.signed_transaction = exports.transaction = exports.asset_update_issuer = exports.asset_claim_pool = exports.execute_bid = exports.bid_collateral = exports.fba_distribute = exports.asset_claim_fees = exports.asset_settle_cancel = exports.transfer_from_blind = exports.blind_transfer = exports.blind_input = exports.transfer_to_blind = exports.blind_output = exports.stealth_confirmation = exports.override_transfer = exports.balance_claim = exports.assert = exports.block_id_predicate = exports.asset_symbol_eq_lit_predicate = exports.account_name_eq_lit_predicate = exports.custom = exports.worker_create = exports.burn_worker_initializer = exports.vesting_balance_worker_initializer = exports.refund_worker_initializer = exports.vesting_balance_withdraw = exports.vesting_balance_create = undefined; -exports.cdd_vesting_policy_initializer = exports.linear_vesting_policy_initializer = exports.committee_member_update_global_parameters = exports.chain_parameters = exports.committee_member_update = exports.committee_member_create = exports.withdraw_permission_delete = exports.withdraw_permission_claim = exports.withdraw_permission_update = exports.withdraw_permission_create = exports.proposal_delete = exports.proposal_update = exports.proposal_create = exports.op_wrapper = exports.witness_update = exports.witness_create = exports.asset_publish_feed = exports.price_feed = exports.asset_global_settle = exports.asset_settle = exports.asset_fund_fee_pool = exports.asset_reserve = exports.asset_issue = exports.asset_update_feed_producers = exports.asset_update_bitasset = exports.asset_update = exports.asset_create = exports.bitasset_options = exports.asset_options = exports.price = exports.account_transfer = exports.account_upgrade = exports.account_whitelist = exports.account_update = exports.account_create = exports.account_options = exports.authority = exports.fill_order = exports.call_order_update = exports.limit_order_cancel = exports.limit_order_create = exports.transfer = exports.memo_data = exports.signed_block_header = exports.block_header = exports.signed_block = exports.processed_transaction = exports.asset = exports.void_result = exports.fee_schedule = exports.asset_update_issuer_operation_fee_parameters = exports.asset_claim_pool_operation_fee_parameters = exports.execute_bid_operation_fee_parameters = exports.bid_collateral_operation_fee_parameters = exports.fba_distribute_operation_fee_parameters = exports.asset_claim_fees_operation_fee_parameters = exports.asset_settle_cancel_operation_fee_parameters = exports.transfer_from_blind_operation_fee_parameters = exports.blind_transfer_operation_fee_parameters = exports.transfer_to_blind_operation_fee_parameters = exports.override_transfer_operation_fee_parameters = exports.balance_claim_operation_fee_parameters = exports.assert_operation_fee_parameters = exports.custom_operation_fee_parameters = exports.worker_create_operation_fee_parameters = exports.vesting_balance_withdraw_operation_fee_parameters = exports.vesting_balance_create_operation_fee_parameters = exports.committee_member_update_global_parameters_operation_fee_parameters = exports.committee_member_update_operation_fee_parameters = exports.committee_member_create_operation_fee_parameters = exports.withdraw_permission_delete_operation_fee_parameters = exports.withdraw_permission_claim_operation_fee_parameters = exports.withdraw_permission_update_operation_fee_parameters = exports.withdraw_permission_create_operation_fee_parameters = exports.proposal_delete_operation_fee_parameters = exports.proposal_update_operation_fee_parameters = exports.proposal_create_operation_fee_parameters = exports.witness_update_operation_fee_parameters = exports.witness_create_operation_fee_parameters = exports.asset_publish_feed_operation_fee_parameters = exports.asset_global_settle_operation_fee_parameters = exports.asset_settle_operation_fee_parameters = exports.asset_fund_fee_pool_operation_fee_parameters = exports.asset_reserve_operation_fee_parameters = exports.asset_issue_operation_fee_parameters = exports.asset_update_feed_producers_operation_fee_parameters = exports.asset_update_bitasset_operation_fee_parameters = exports.asset_update_operation_fee_parameters = exports.asset_create_operation_fee_parameters = exports.account_transfer_operation_fee_parameters = exports.account_upgrade_operation_fee_parameters = exports.account_whitelist_operation_fee_parameters = exports.account_update_operation_fee_parameters = exports.account_create_operation_fee_parameters = exports.fill_order_operation_fee_parameters = exports.call_order_update_operation_fee_parameters = exports.limit_order_cancel_operation_fee_parameters = exports.limit_order_create_operation_fee_parameters = exports.transfer_operation_fee_parameters = exports.operation = undefined; - -var _types = require("./types"); - -var _types2 = _interopRequireDefault(_types); - -var _serializer = require("./serializer"); - -var _serializer2 = _interopRequireDefault(_serializer); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var uint8 = _types2.default.uint8, - uint16 = _types2.default.uint16, - uint32 = _types2.default.uint32, - int64 = _types2.default.int64, - uint64 = _types2.default.uint64, - string = _types2.default.string, - bytes = _types2.default.bytes, - bool = _types2.default.bool, - array = _types2.default.array, - protocol_id_type = _types2.default.protocol_id_type, - object_id_type = _types2.default.object_id_type, - vote_id = _types2.default.vote_id, - future_extensions = _types2.default.future_extensions, - static_variant = _types2.default.static_variant, - map = _types2.default.map, - set = _types2.default.set, - public_key = _types2.default.public_key, - address = _types2.default.address, - time_point_sec = _types2.default.time_point_sec, - optional = _types2.default.optional, - extension = _types2.default.extension; - - -future_extensions = _types2.default.void; - -/* -When updating generated code -Replace: operation = static_variant [ -with: operation.st_operations = [ - -Delete: -public_key = new Serializer( - "public_key" - key_data: bytes 33 -) - -*/ -// Place-holder, their are dependencies on "operation" .. The final list of -// operations is not avialble until the very end of the generated code. -// See: operation.st_operations = ... -var operation = static_variant(); -// module.exports["operation"] = operation; - -exports.operation = operation; -// For module.exports - -var Serializer = function Serializer(operation_name, serilization_types_object) { - return new _serializer2.default(operation_name, serilization_types_object); - // return module.exports[operation_name] = s; -}; - -// Custom-types follow Generated code: - -// ## Generated code follows -// # programs/js_operation_serializer > npm i -g decaffeinate -// ## ------------------------------- -var transfer_operation_fee_parameters = exports.transfer_operation_fee_parameters = new Serializer("transfer_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var limit_order_create_operation_fee_parameters = exports.limit_order_create_operation_fee_parameters = new Serializer("limit_order_create_operation_fee_parameters", { fee: uint64 }); - -var limit_order_cancel_operation_fee_parameters = exports.limit_order_cancel_operation_fee_parameters = new Serializer("limit_order_cancel_operation_fee_parameters", { fee: uint64 }); - -var call_order_update_operation_fee_parameters = exports.call_order_update_operation_fee_parameters = new Serializer("call_order_update_operation_fee_parameters", { fee: uint64 }); - -var fill_order_operation_fee_parameters = exports.fill_order_operation_fee_parameters = new Serializer("fill_order_operation_fee_parameters"); - -var account_create_operation_fee_parameters = exports.account_create_operation_fee_parameters = new Serializer("account_create_operation_fee_parameters", { - basic_fee: uint64, - premium_fee: uint64, - price_per_kbyte: uint32 -}); - -var account_update_operation_fee_parameters = exports.account_update_operation_fee_parameters = new Serializer("account_update_operation_fee_parameters", { - fee: int64, - price_per_kbyte: uint32 -}); - -var account_whitelist_operation_fee_parameters = exports.account_whitelist_operation_fee_parameters = new Serializer("account_whitelist_operation_fee_parameters", { fee: int64 }); - -var account_upgrade_operation_fee_parameters = exports.account_upgrade_operation_fee_parameters = new Serializer("account_upgrade_operation_fee_parameters", { - membership_annual_fee: uint64, - membership_lifetime_fee: uint64 -}); - -var account_transfer_operation_fee_parameters = exports.account_transfer_operation_fee_parameters = new Serializer("account_transfer_operation_fee_parameters", { fee: uint64 }); - -var asset_create_operation_fee_parameters = exports.asset_create_operation_fee_parameters = new Serializer("asset_create_operation_fee_parameters", { - symbol3: uint64, - symbol4: uint64, - long_symbol: uint64, - price_per_kbyte: uint32 -}); - -var asset_update_operation_fee_parameters = exports.asset_update_operation_fee_parameters = new Serializer("asset_update_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var asset_update_bitasset_operation_fee_parameters = exports.asset_update_bitasset_operation_fee_parameters = new Serializer("asset_update_bitasset_operation_fee_parameters", { fee: uint64 }); - -var asset_update_feed_producers_operation_fee_parameters = exports.asset_update_feed_producers_operation_fee_parameters = new Serializer("asset_update_feed_producers_operation_fee_parameters", { fee: uint64 }); - -var asset_issue_operation_fee_parameters = exports.asset_issue_operation_fee_parameters = new Serializer("asset_issue_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var asset_reserve_operation_fee_parameters = exports.asset_reserve_operation_fee_parameters = new Serializer("asset_reserve_operation_fee_parameters", { fee: uint64 }); - -var asset_fund_fee_pool_operation_fee_parameters = exports.asset_fund_fee_pool_operation_fee_parameters = new Serializer("asset_fund_fee_pool_operation_fee_parameters", { fee: uint64 }); - -var asset_settle_operation_fee_parameters = exports.asset_settle_operation_fee_parameters = new Serializer("asset_settle_operation_fee_parameters", { fee: uint64 }); - -var asset_global_settle_operation_fee_parameters = exports.asset_global_settle_operation_fee_parameters = new Serializer("asset_global_settle_operation_fee_parameters", { fee: uint64 }); - -var asset_publish_feed_operation_fee_parameters = exports.asset_publish_feed_operation_fee_parameters = new Serializer("asset_publish_feed_operation_fee_parameters", { fee: uint64 }); - -var witness_create_operation_fee_parameters = exports.witness_create_operation_fee_parameters = new Serializer("witness_create_operation_fee_parameters", { fee: uint64 }); - -var witness_update_operation_fee_parameters = exports.witness_update_operation_fee_parameters = new Serializer("witness_update_operation_fee_parameters", { fee: int64 }); - -var proposal_create_operation_fee_parameters = exports.proposal_create_operation_fee_parameters = new Serializer("proposal_create_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var proposal_update_operation_fee_parameters = exports.proposal_update_operation_fee_parameters = new Serializer("proposal_update_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var proposal_delete_operation_fee_parameters = exports.proposal_delete_operation_fee_parameters = new Serializer("proposal_delete_operation_fee_parameters", { fee: uint64 }); - -var withdraw_permission_create_operation_fee_parameters = exports.withdraw_permission_create_operation_fee_parameters = new Serializer("withdraw_permission_create_operation_fee_parameters", { fee: uint64 }); - -var withdraw_permission_update_operation_fee_parameters = exports.withdraw_permission_update_operation_fee_parameters = new Serializer("withdraw_permission_update_operation_fee_parameters", { fee: uint64 }); - -var withdraw_permission_claim_operation_fee_parameters = exports.withdraw_permission_claim_operation_fee_parameters = new Serializer("withdraw_permission_claim_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var withdraw_permission_delete_operation_fee_parameters = exports.withdraw_permission_delete_operation_fee_parameters = new Serializer("withdraw_permission_delete_operation_fee_parameters", { fee: uint64 }); - -var committee_member_create_operation_fee_parameters = exports.committee_member_create_operation_fee_parameters = new Serializer("committee_member_create_operation_fee_parameters", { fee: uint64 }); - -var committee_member_update_operation_fee_parameters = exports.committee_member_update_operation_fee_parameters = new Serializer("committee_member_update_operation_fee_parameters", { fee: uint64 }); - -var committee_member_update_global_parameters_operation_fee_parameters = exports.committee_member_update_global_parameters_operation_fee_parameters = new Serializer("committee_member_update_global_parameters_operation_fee_parameters", { fee: uint64 }); - -var vesting_balance_create_operation_fee_parameters = exports.vesting_balance_create_operation_fee_parameters = new Serializer("vesting_balance_create_operation_fee_parameters", { fee: uint64 }); - -var vesting_balance_withdraw_operation_fee_parameters = exports.vesting_balance_withdraw_operation_fee_parameters = new Serializer("vesting_balance_withdraw_operation_fee_parameters", { fee: uint64 }); - -var worker_create_operation_fee_parameters = exports.worker_create_operation_fee_parameters = new Serializer("worker_create_operation_fee_parameters", { fee: uint64 }); - -var custom_operation_fee_parameters = exports.custom_operation_fee_parameters = new Serializer("custom_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var assert_operation_fee_parameters = exports.assert_operation_fee_parameters = new Serializer("assert_operation_fee_parameters", { fee: uint64 }); - -var balance_claim_operation_fee_parameters = exports.balance_claim_operation_fee_parameters = new Serializer("balance_claim_operation_fee_parameters"); - -var override_transfer_operation_fee_parameters = exports.override_transfer_operation_fee_parameters = new Serializer("override_transfer_operation_fee_parameters", { - fee: uint64, - price_per_kbyte: uint32 -}); - -var transfer_to_blind_operation_fee_parameters = exports.transfer_to_blind_operation_fee_parameters = new Serializer("transfer_to_blind_operation_fee_parameters", { - fee: uint64, - price_per_output: uint32 -}); - -var blind_transfer_operation_fee_parameters = exports.blind_transfer_operation_fee_parameters = new Serializer("blind_transfer_operation_fee_parameters", { - fee: uint64, - price_per_output: uint32 -}); - -var transfer_from_blind_operation_fee_parameters = exports.transfer_from_blind_operation_fee_parameters = new Serializer("transfer_from_blind_operation_fee_parameters", { fee: uint64 }); - -var asset_settle_cancel_operation_fee_parameters = exports.asset_settle_cancel_operation_fee_parameters = new Serializer("asset_settle_cancel_operation_fee_parameters"); - -var asset_claim_fees_operation_fee_parameters = exports.asset_claim_fees_operation_fee_parameters = new Serializer("asset_claim_fees_operation_fee_parameters", { fee: uint64 }); - -var fba_distribute_operation_fee_parameters = exports.fba_distribute_operation_fee_parameters = new Serializer("fba_distribute_operation_fee_parameters"); - -var bid_collateral_operation_fee_parameters = exports.bid_collateral_operation_fee_parameters = new Serializer("bid_collateral_operation_fee_parameters", { - fee: uint64 -}); - -var execute_bid_operation_fee_parameters = exports.execute_bid_operation_fee_parameters = new Serializer("execute_bid_operation_fee_parameters"); - -var asset_claim_pool_operation_fee_parameters = exports.asset_claim_pool_operation_fee_parameters = new Serializer("asset_claim_pool_operation_fee_parameters", { - fee: uint64 -}); - -var asset_update_issuer_operation_fee_parameters = exports.asset_update_issuer_operation_fee_parameters = new Serializer("asset_update_issuer_operation_fee_parameters", { - fee: uint64 -}); - -var fee_parameters = static_variant([transfer_operation_fee_parameters, limit_order_create_operation_fee_parameters, limit_order_cancel_operation_fee_parameters, call_order_update_operation_fee_parameters, fill_order_operation_fee_parameters, account_create_operation_fee_parameters, account_update_operation_fee_parameters, account_whitelist_operation_fee_parameters, account_upgrade_operation_fee_parameters, account_transfer_operation_fee_parameters, asset_create_operation_fee_parameters, asset_update_operation_fee_parameters, asset_update_bitasset_operation_fee_parameters, asset_update_feed_producers_operation_fee_parameters, asset_issue_operation_fee_parameters, asset_reserve_operation_fee_parameters, asset_fund_fee_pool_operation_fee_parameters, asset_settle_operation_fee_parameters, asset_global_settle_operation_fee_parameters, asset_publish_feed_operation_fee_parameters, witness_create_operation_fee_parameters, witness_update_operation_fee_parameters, proposal_create_operation_fee_parameters, proposal_update_operation_fee_parameters, proposal_delete_operation_fee_parameters, withdraw_permission_create_operation_fee_parameters, withdraw_permission_update_operation_fee_parameters, withdraw_permission_claim_operation_fee_parameters, withdraw_permission_delete_operation_fee_parameters, committee_member_create_operation_fee_parameters, committee_member_update_operation_fee_parameters, committee_member_update_global_parameters_operation_fee_parameters, vesting_balance_create_operation_fee_parameters, vesting_balance_withdraw_operation_fee_parameters, worker_create_operation_fee_parameters, custom_operation_fee_parameters, assert_operation_fee_parameters, balance_claim_operation_fee_parameters, override_transfer_operation_fee_parameters, transfer_to_blind_operation_fee_parameters, blind_transfer_operation_fee_parameters, transfer_from_blind_operation_fee_parameters, asset_settle_cancel_operation_fee_parameters, asset_claim_fees_operation_fee_parameters, fba_distribute_operation_fee_parameters, bid_collateral_operation_fee_parameters, execute_bid_operation_fee_parameters, asset_claim_pool_operation_fee_parameters, asset_update_issuer_operation_fee_parameters]); - -var fee_schedule = exports.fee_schedule = new Serializer("fee_schedule", { - parameters: set(fee_parameters), - scale: uint32 -}); - -var void_result = exports.void_result = new Serializer("void_result"); - -var asset = exports.asset = new Serializer("asset", { - amount: int64, - asset_id: protocol_id_type("asset") -}); - -var operation_result = static_variant([void_result, object_id_type, asset]); - -var processed_transaction = exports.processed_transaction = new Serializer("processed_transaction", { - ref_block_num: uint16, - ref_block_prefix: uint32, - expiration: time_point_sec, - operations: array(operation), - extensions: set(future_extensions), - signatures: array(bytes(65)), - operation_results: array(operation_result) -}); - -var signed_block = exports.signed_block = new Serializer("signed_block", { - previous: bytes(20), - timestamp: time_point_sec, - witness: protocol_id_type("witness"), - transaction_merkle_root: bytes(20), - extensions: set(future_extensions), - witness_signature: bytes(65), - transactions: array(processed_transaction) -}); - -var block_header = exports.block_header = new Serializer("block_header", { - previous: bytes(20), - timestamp: time_point_sec, - witness: protocol_id_type("witness"), - transaction_merkle_root: bytes(20), - extensions: set(future_extensions) -}); - -var signed_block_header = exports.signed_block_header = new Serializer("signed_block_header", { - previous: bytes(20), - timestamp: time_point_sec, - witness: protocol_id_type("witness"), - transaction_merkle_root: bytes(20), - extensions: set(future_extensions), - witness_signature: bytes(65) -}); - -var memo_data = exports.memo_data = new Serializer("memo_data", { - from: public_key, - to: public_key, - nonce: uint64, - message: bytes() -}); - -var transfer = exports.transfer = new Serializer("transfer", { - fee: asset, - from: protocol_id_type("account"), - to: protocol_id_type("account"), - amount: asset, - memo: optional(memo_data), - extensions: set(future_extensions) -}); - -var limit_order_create = exports.limit_order_create = new Serializer("limit_order_create", { - fee: asset, - seller: protocol_id_type("account"), - amount_to_sell: asset, - min_to_receive: asset, - expiration: time_point_sec, - fill_or_kill: bool, - extensions: set(future_extensions) -}); - -var limit_order_cancel = exports.limit_order_cancel = new Serializer("limit_order_cancel", { - fee: asset, - fee_paying_account: protocol_id_type("account"), - order: protocol_id_type("limit_order"), - extensions: set(future_extensions) -}); - -var call_order_update = exports.call_order_update = new Serializer("call_order_update", { - fee: asset, - funding_account: protocol_id_type("account"), - delta_collateral: asset, - delta_debt: asset, - extensions: extension([{ - name: "target_collateral_ratio", - type: uint16 - }]) -}); - -var fill_order = exports.fill_order = new Serializer("fill_order", { - fee: asset, - order_id: object_id_type, - account_id: protocol_id_type("account"), - pays: asset, - receives: asset -}); - -var authority = exports.authority = new Serializer("authority", { - weight_threshold: uint32, - account_auths: map(protocol_id_type("account"), uint16), - key_auths: map(public_key, uint16), - address_auths: map(address, uint16) -}); - -var account_options = exports.account_options = new Serializer("account_options", { - memo_key: public_key, - voting_account: protocol_id_type("account"), - num_witness: uint16, - num_committee: uint16, - votes: set(vote_id), - extensions: set(future_extensions) -}); - -var account_create = exports.account_create = new Serializer("account_create", { - fee: asset, - registrar: protocol_id_type("account"), - referrer: protocol_id_type("account"), - referrer_percent: uint16, - name: string, - owner: authority, - active: authority, - options: account_options, - extensions: set(future_extensions) -}); - -var account_update = exports.account_update = new Serializer("account_update", { - fee: asset, - account: protocol_id_type("account"), - owner: optional(authority), - active: optional(authority), - new_options: optional(account_options), - extensions: set(future_extensions) -}); - -var account_whitelist = exports.account_whitelist = new Serializer("account_whitelist", { - fee: asset, - authorizing_account: protocol_id_type("account"), - account_to_list: protocol_id_type("account"), - new_listing: uint8, - extensions: set(future_extensions) -}); - -var account_upgrade = exports.account_upgrade = new Serializer("account_upgrade", { - fee: asset, - account_to_upgrade: protocol_id_type("account"), - upgrade_to_lifetime_member: bool, - extensions: set(future_extensions) -}); - -var account_transfer = exports.account_transfer = new Serializer("account_transfer", { - fee: asset, - account_id: protocol_id_type("account"), - new_owner: protocol_id_type("account"), - extensions: set(future_extensions) -}); - -var price = exports.price = new Serializer("price", { - base: asset, - quote: asset -}); - -var asset_options = exports.asset_options = new Serializer("asset_options", { - max_supply: int64, - market_fee_percent: uint16, - max_market_fee: int64, - issuer_permissions: uint16, - flags: uint16, - core_exchange_rate: price, - whitelist_authorities: set(protocol_id_type("account")), - blacklist_authorities: set(protocol_id_type("account")), - whitelist_markets: set(protocol_id_type("asset")), - blacklist_markets: set(protocol_id_type("asset")), - description: string, - extensions: set(future_extensions) -}); - -var bitasset_options = exports.bitasset_options = new Serializer("bitasset_options", { - feed_lifetime_sec: uint32, - minimum_feeds: uint8, - force_settlement_delay_sec: uint32, - force_settlement_offset_percent: uint16, - maximum_force_settlement_volume: uint16, - short_backing_asset: protocol_id_type("asset"), - extensions: set(future_extensions) -}); - -var asset_create = exports.asset_create = new Serializer("asset_create", { - fee: asset, - issuer: protocol_id_type("account"), - symbol: string, - precision: uint8, - common_options: asset_options, - bitasset_opts: optional(bitasset_options), - is_prediction_market: bool, - extensions: set(future_extensions) -}); - -var asset_update = exports.asset_update = new Serializer("asset_update", { - fee: asset, - issuer: protocol_id_type("account"), - asset_to_update: protocol_id_type("asset"), - new_issuer: optional(protocol_id_type("account")), - new_options: asset_options, - extensions: set(future_extensions) -}); - -var asset_update_bitasset = exports.asset_update_bitasset = new Serializer("asset_update_bitasset", { - fee: asset, - issuer: protocol_id_type("account"), - asset_to_update: protocol_id_type("asset"), - new_options: bitasset_options, - extensions: set(future_extensions) -}); - -var asset_update_feed_producers = exports.asset_update_feed_producers = new Serializer("asset_update_feed_producers", { - fee: asset, - issuer: protocol_id_type("account"), - asset_to_update: protocol_id_type("asset"), - new_feed_producers: set(protocol_id_type("account")), - extensions: set(future_extensions) -}); - -var asset_issue = exports.asset_issue = new Serializer("asset_issue", { - fee: asset, - issuer: protocol_id_type("account"), - asset_to_issue: asset, - issue_to_account: protocol_id_type("account"), - memo: optional(memo_data), - extensions: set(future_extensions) -}); - -var asset_reserve = exports.asset_reserve = new Serializer("asset_reserve", { - fee: asset, - payer: protocol_id_type("account"), - amount_to_reserve: asset, - extensions: set(future_extensions) -}); - -var asset_fund_fee_pool = exports.asset_fund_fee_pool = new Serializer("asset_fund_fee_pool", { - fee: asset, - from_account: protocol_id_type("account"), - asset_id: protocol_id_type("asset"), - amount: int64, - extensions: set(future_extensions) -}); - -var asset_settle = exports.asset_settle = new Serializer("asset_settle", { - fee: asset, - account: protocol_id_type("account"), - amount: asset, - extensions: set(future_extensions) -}); - -var asset_global_settle = exports.asset_global_settle = new Serializer("asset_global_settle", { - fee: asset, - issuer: protocol_id_type("account"), - asset_to_settle: protocol_id_type("asset"), - settle_price: price, - extensions: set(future_extensions) -}); - -var price_feed = exports.price_feed = new Serializer("price_feed", { - settlement_price: price, - maintenance_collateral_ratio: uint16, - maximum_short_squeeze_ratio: uint16, - core_exchange_rate: price -}); - -var asset_publish_feed = exports.asset_publish_feed = new Serializer("asset_publish_feed", { - fee: asset, - publisher: protocol_id_type("account"), - asset_id: protocol_id_type("asset"), - feed: price_feed, - extensions: set(future_extensions) -}); - -var witness_create = exports.witness_create = new Serializer("witness_create", { - fee: asset, - witness_account: protocol_id_type("account"), - url: string, - block_signing_key: public_key -}); - -var witness_update = exports.witness_update = new Serializer("witness_update", { - fee: asset, - witness: protocol_id_type("witness"), - witness_account: protocol_id_type("account"), - new_url: optional(string), - new_signing_key: optional(public_key) -}); - -var op_wrapper = exports.op_wrapper = new Serializer("op_wrapper", { op: operation }); - -var proposal_create = exports.proposal_create = new Serializer("proposal_create", { - fee: asset, - fee_paying_account: protocol_id_type("account"), - expiration_time: time_point_sec, - proposed_ops: array(op_wrapper), - review_period_seconds: optional(uint32), - extensions: set(future_extensions) -}); - -var proposal_update = exports.proposal_update = new Serializer("proposal_update", { - fee: asset, - fee_paying_account: protocol_id_type("account"), - proposal: protocol_id_type("proposal"), - active_approvals_to_add: set(protocol_id_type("account")), - active_approvals_to_remove: set(protocol_id_type("account")), - owner_approvals_to_add: set(protocol_id_type("account")), - owner_approvals_to_remove: set(protocol_id_type("account")), - key_approvals_to_add: set(public_key), - key_approvals_to_remove: set(public_key), - extensions: set(future_extensions) -}); - -var proposal_delete = exports.proposal_delete = new Serializer("proposal_delete", { - fee: asset, - fee_paying_account: protocol_id_type("account"), - using_owner_authority: bool, - proposal: protocol_id_type("proposal"), - extensions: set(future_extensions) -}); - -var withdraw_permission_create = exports.withdraw_permission_create = new Serializer("withdraw_permission_create", { - fee: asset, - withdraw_from_account: protocol_id_type("account"), - authorized_account: protocol_id_type("account"), - withdrawal_limit: asset, - withdrawal_period_sec: uint32, - periods_until_expiration: uint32, - period_start_time: time_point_sec -}); - -var withdraw_permission_update = exports.withdraw_permission_update = new Serializer("withdraw_permission_update", { - fee: asset, - withdraw_from_account: protocol_id_type("account"), - authorized_account: protocol_id_type("account"), - permission_to_update: protocol_id_type("withdraw_permission"), - withdrawal_limit: asset, - withdrawal_period_sec: uint32, - period_start_time: time_point_sec, - periods_until_expiration: uint32 -}); - -var withdraw_permission_claim = exports.withdraw_permission_claim = new Serializer("withdraw_permission_claim", { - fee: asset, - withdraw_permission: protocol_id_type("withdraw_permission"), - withdraw_from_account: protocol_id_type("account"), - withdraw_to_account: protocol_id_type("account"), - amount_to_withdraw: asset, - memo: optional(memo_data) -}); - -var withdraw_permission_delete = exports.withdraw_permission_delete = new Serializer("withdraw_permission_delete", { - fee: asset, - withdraw_from_account: protocol_id_type("account"), - authorized_account: protocol_id_type("account"), - withdrawal_permission: protocol_id_type("withdraw_permission") -}); - -var committee_member_create = exports.committee_member_create = new Serializer("committee_member_create", { - fee: asset, - committee_member_account: protocol_id_type("account"), - url: string -}); - -var committee_member_update = exports.committee_member_update = new Serializer("committee_member_update", { - fee: asset, - committee_member: protocol_id_type("committee_member"), - committee_member_account: protocol_id_type("account"), - new_url: optional(string) -}); - -var chain_parameters = exports.chain_parameters = new Serializer("chain_parameters", { - current_fees: fee_schedule, - block_interval: uint8, - maintenance_interval: uint32, - maintenance_skip_slots: uint8, - committee_proposal_review_period: uint32, - maximum_transaction_size: uint32, - maximum_block_size: uint32, - maximum_time_until_expiration: uint32, - maximum_proposal_lifetime: uint32, - maximum_asset_whitelist_authorities: uint8, - maximum_asset_feed_publishers: uint8, - maximum_witness_count: uint16, - maximum_committee_count: uint16, - maximum_authority_membership: uint16, - reserve_percent_of_fee: uint16, - network_percent_of_fee: uint16, - lifetime_referrer_percent_of_fee: uint16, - cashback_vesting_period_seconds: uint32, - cashback_vesting_threshold: int64, - count_non_member_votes: bool, - allow_non_member_whitelists: bool, - witness_pay_per_block: int64, - worker_budget_per_day: int64, - max_predicate_opcode: uint16, - fee_liquidation_threshold: int64, - accounts_per_fee_scale: uint16, - account_fee_scale_bitshifts: uint8, - max_authority_depth: uint8, - extensions: set(future_extensions) -}); - -var committee_member_update_global_parameters = exports.committee_member_update_global_parameters = new Serializer("committee_member_update_global_parameters", { - fee: asset, - new_parameters: chain_parameters -}); - -var linear_vesting_policy_initializer = exports.linear_vesting_policy_initializer = new Serializer("linear_vesting_policy_initializer", { - begin_timestamp: time_point_sec, - vesting_cliff_seconds: uint32, - vesting_duration_seconds: uint32 -}); - -var cdd_vesting_policy_initializer = exports.cdd_vesting_policy_initializer = new Serializer("cdd_vesting_policy_initializer", { - start_claim: time_point_sec, - vesting_seconds: uint32 -}); - -var vesting_policy_initializer = static_variant([linear_vesting_policy_initializer, cdd_vesting_policy_initializer]); - -var vesting_balance_create = exports.vesting_balance_create = new Serializer("vesting_balance_create", { - fee: asset, - creator: protocol_id_type("account"), - owner: protocol_id_type("account"), - amount: asset, - policy: vesting_policy_initializer -}); - -var vesting_balance_withdraw = exports.vesting_balance_withdraw = new Serializer("vesting_balance_withdraw", { - fee: asset, - vesting_balance: protocol_id_type("vesting_balance"), - owner: protocol_id_type("account"), - amount: asset -}); - -var refund_worker_initializer = exports.refund_worker_initializer = new Serializer("refund_worker_initializer"); - -var vesting_balance_worker_initializer = exports.vesting_balance_worker_initializer = new Serializer("vesting_balance_worker_initializer", { pay_vesting_period_days: uint16 }); - -var burn_worker_initializer = exports.burn_worker_initializer = new Serializer("burn_worker_initializer"); - -var worker_initializer = static_variant([refund_worker_initializer, vesting_balance_worker_initializer, burn_worker_initializer]); - -var worker_create = exports.worker_create = new Serializer("worker_create", { - fee: asset, - owner: protocol_id_type("account"), - work_begin_date: time_point_sec, - work_end_date: time_point_sec, - daily_pay: int64, - name: string, - url: string, - initializer: worker_initializer -}); - -var custom = exports.custom = new Serializer("custom", { - fee: asset, - payer: protocol_id_type("account"), - required_auths: set(protocol_id_type("account")), - id: uint16, - data: bytes() -}); - -var account_name_eq_lit_predicate = exports.account_name_eq_lit_predicate = new Serializer("account_name_eq_lit_predicate", { - account_id: protocol_id_type("account"), - name: string -}); - -var asset_symbol_eq_lit_predicate = exports.asset_symbol_eq_lit_predicate = new Serializer("asset_symbol_eq_lit_predicate", { - asset_id: protocol_id_type("asset"), - symbol: string -}); - -var block_id_predicate = exports.block_id_predicate = new Serializer("block_id_predicate", { - id: bytes(20) -}); - -var predicate = static_variant([account_name_eq_lit_predicate, asset_symbol_eq_lit_predicate, block_id_predicate]); - -var assert = exports.assert = new Serializer("assert", { - fee: asset, - fee_paying_account: protocol_id_type("account"), - predicates: array(predicate), - required_auths: set(protocol_id_type("account")), - extensions: set(future_extensions) -}); - -var balance_claim = exports.balance_claim = new Serializer("balance_claim", { - fee: asset, - deposit_to_account: protocol_id_type("account"), - balance_to_claim: protocol_id_type("balance"), - balance_owner_key: public_key, - total_claimed: asset -}); - -var override_transfer = exports.override_transfer = new Serializer("override_transfer", { - fee: asset, - issuer: protocol_id_type("account"), - from: protocol_id_type("account"), - to: protocol_id_type("account"), - amount: asset, - memo: optional(memo_data), - extensions: set(future_extensions) -}); - -var stealth_confirmation = exports.stealth_confirmation = new Serializer("stealth_confirmation", { - one_time_key: public_key, - to: optional(public_key), - encrypted_memo: bytes() -}); - -var blind_output = exports.blind_output = new Serializer("blind_output", { - commitment: bytes(33), - range_proof: bytes(), - owner: authority, - stealth_memo: optional(stealth_confirmation) -}); - -var transfer_to_blind = exports.transfer_to_blind = new Serializer("transfer_to_blind", { - fee: asset, - amount: asset, - from: protocol_id_type("account"), - blinding_factor: bytes(32), - outputs: array(blind_output) -}); - -var blind_input = exports.blind_input = new Serializer("blind_input", { - commitment: bytes(33), - owner: authority -}); - -var blind_transfer = exports.blind_transfer = new Serializer("blind_transfer", { - fee: asset, - inputs: array(blind_input), - outputs: array(blind_output) -}); - -var transfer_from_blind = exports.transfer_from_blind = new Serializer("transfer_from_blind", { - fee: asset, - amount: asset, - to: protocol_id_type("account"), - blinding_factor: bytes(32), - inputs: array(blind_input) -}); - -var asset_settle_cancel = exports.asset_settle_cancel = new Serializer("asset_settle_cancel", { - fee: asset, - settlement: protocol_id_type("force_settlement"), - account: protocol_id_type("account"), - amount: asset, - extensions: set(future_extensions) -}); - -var asset_claim_fees = exports.asset_claim_fees = new Serializer("asset_claim_fees", { - fee: asset, - issuer: protocol_id_type("account"), - amount_to_claim: asset, - extensions: set(future_extensions) -}); - -var fba_distribute = exports.fba_distribute = new Serializer("fba_distribute", { - fee: asset, - account_id: protocol_id_type("account"), - fba_id: protocol_id_type("fba_accumulator"), - amount: int64 -}); - -var bid_collateral = exports.bid_collateral = new Serializer("bid_collateral", { - fee: asset, - bidder: protocol_id_type("account"), - additional_collateral: asset, - debt_covered: asset, - extensions: set(future_extensions) -}); - -var execute_bid = exports.execute_bid = new Serializer("execute_bid", { - fee: asset, - bidder: protocol_id_type("account"), - debt: asset, - collateral: asset -}); - -var asset_claim_pool = exports.asset_claim_pool = new Serializer("asset_claim_pool", { - fee: asset, - issuer: protocol_id_type("account"), - asset_id: protocol_id_type("asset"), - amount_to_claim: asset, - extensions: set(future_extensions) -}); - -var asset_update_issuer = exports.asset_update_issuer = new Serializer("asset_update_issuer", { - fee: asset, - issuer: protocol_id_type("account"), - asset_to_update: protocol_id_type("asset"), - new_issuer: protocol_id_type("account"), - extensions: set(future_extensions) -}); - -operation.st_operations = [transfer, limit_order_create, limit_order_cancel, call_order_update, fill_order, account_create, account_update, account_whitelist, account_upgrade, account_transfer, asset_create, asset_update, asset_update_bitasset, asset_update_feed_producers, asset_issue, asset_reserve, asset_fund_fee_pool, asset_settle, asset_global_settle, asset_publish_feed, witness_create, witness_update, proposal_create, proposal_update, proposal_delete, withdraw_permission_create, withdraw_permission_update, withdraw_permission_claim, withdraw_permission_delete, committee_member_create, committee_member_update, committee_member_update_global_parameters, vesting_balance_create, vesting_balance_withdraw, worker_create, custom, assert, balance_claim, override_transfer, transfer_to_blind, blind_transfer, transfer_from_blind, asset_settle_cancel, asset_claim_fees, fba_distribute, bid_collateral, execute_bid, asset_claim_pool, asset_update_issuer]; - -var transaction = exports.transaction = new Serializer("transaction", { - ref_block_num: uint16, - ref_block_prefix: uint32, - expiration: time_point_sec, - operations: array(operation), - extensions: set(future_extensions) -}); - -var signed_transaction = exports.signed_transaction = new Serializer("signed_transaction", { - ref_block_num: uint16, - ref_block_prefix: uint32, - expiration: time_point_sec, - operations: array(operation), - extensions: set(future_extensions), - signatures: array(bytes(65)) -}); -//# ------------------------------- -//# Generated code end -//# ------------------------------- - -// Custom Types - -var stealth_memo_data = exports.stealth_memo_data = new Serializer("stealth_memo_data", { - from: optional(public_key), - amount: asset, - blinding_factor: bytes(32), - commitment: bytes(33), - check: uint32 -}); -// var stealth_confirmation = new Serializer( -// "stealth_confirmation", { -// one_time_key: public_key, -// to: optional( public_key ), -// encrypted_memo: stealth_memo_data -// }) -},{"./serializer":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/serializer.js","./types":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/types.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/serializer.js":[function(require,module,exports){ -(function (process){ -"use strict"; - -exports.__esModule = true; - -var _bytebuffer = require("bytebuffer"); - -var _bytebuffer2 = _interopRequireDefault(_bytebuffer); - -var _error_with_cause = require("./error_with_cause"); - -var _error_with_cause2 = _interopRequireDefault(_error_with_cause); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Buffer = require("safe-buffer").Buffer; - -var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; - -var Serializer = function () { - function Serializer(operation_name, types) { - _classCallCheck(this, Serializer); - - this.operation_name = operation_name; - this.types = types; - if (this.types) this.keys = Object.keys(this.types); - - Serializer.printDebug = true; - } - - Serializer.prototype.fromByteBuffer = function fromByteBuffer(b) { - var object = {}; - var field = null; - try { - var iterable = this.keys; - for (var i = 0, field; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - try { - if (HEX_DUMP) { - if (type.operation_name) { - console.error(type.operation_name); - } else { - var o1 = b.offset; - type.fromByteBuffer(b); - var o2 = b.offset; - b.offset = o1; - //b.reset() - var _b = b.copy(o1, o2); - console.error(this.operation_name + "." + field + "\t", _b.toHex()); - } - } - object[field] = type.fromByteBuffer(b); - } catch (e) { - if (Serializer.printDebug) { - console.error("Error reading " + this.operation_name + "." + field + " in data:"); - b.printDebug(); - } - throw e; - } - } - } catch (error) { - _error_with_cause2.default.throw(this.operation_name + "." + field, error); - } - - return object; - }; - - Serializer.prototype.appendByteBuffer = function appendByteBuffer(b, object) { - var field = null; - try { - var iterable = this.keys; - for (var i = 0, field; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - type.appendByteBuffer(b, object[field]); - } - } catch (error) { - try { - _error_with_cause2.default.throw(this.operation_name + "." + field + " = " + JSON.stringify(object[field]), error); - } catch (e) { - // circular ref - _error_with_cause2.default.throw(this.operation_name + "." + field + " = " + object[field], error); - } - } - return; - }; - - Serializer.prototype.fromObject = function fromObject(serialized_object) { - var result = {}; - var field = null; - try { - var iterable = this.keys; - for (var i = 0, field; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - var value = serialized_object[field]; - //DEBUG value = value.resolve if value.resolve - //DEBUG console.log('... value',field,value) - var object = type.fromObject(value); - result[field] = object; - } - } catch (error) { - _error_with_cause2.default.throw(this.operation_name + "." + field, error); - } - - return result; - }; - - /** - @arg {boolean} [debug.use_default = false] - more template friendly - @arg {boolean} [debug.annotate = false] - add user-friendly information - */ - - - Serializer.prototype.toObject = function toObject() { - var serialized_object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: false, annotate: false }; - - var result = {}; - var field = null; - try { - if (!this.types) return result; - - var iterable = this.keys; - for (var i = 0, field; i < iterable.length; i++) { - field = iterable[i]; - var type = this.types[field]; - var object = type.toObject(typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined, debug); - result[field] = object; - if (HEX_DUMP) { - var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); - type.appendByteBuffer(b, typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined); - b = b.copy(0, b.offset); - console.error(this.operation_name + "." + field, b.toHex()); - } - } - } catch (error) { - _error_with_cause2.default.throw(this.operation_name + "." + field, error); - } - - return result; - }; - - /** Sort by the first element in a operation */ - - - Serializer.prototype.compare = function compare(a, b) { - var first_key = this.keys[0]; - var first_type = this.types[first_key]; - - var valA = a[first_key]; - var valB = b[first_key]; - - if (first_type.compare) return first_type.compare(valA, valB); - - if (typeof valA === "number" && typeof valB === "number") return valA - valB; - - var encoding = void 0; - if (Buffer.isBuffer(valA) && Buffer.isBuffer(valB)) { - // A binary string compare does not work. If localeCompare is well supported that could replace HEX. Performanance is very good so comparing HEX works. - encoding = "hex"; - } - - var strA = valA.toString(encoding); - var strB = valB.toString(encoding); - return strA > strB ? 1 : strA < strB ? -1 : 0; - }; - - // - - Serializer.prototype.fromHex = function fromHex(hex) { - var b = _bytebuffer2.default.fromHex(hex, _bytebuffer2.default.LITTLE_ENDIAN); - return this.fromByteBuffer(b); - }; - - Serializer.prototype.fromBuffer = function fromBuffer(buffer) { - var b = _bytebuffer2.default.fromBinary(buffer.toString("binary"), _bytebuffer2.default.LITTLE_ENDIAN); - return this.fromByteBuffer(b); - }; - - Serializer.prototype.toHex = function toHex(object) { - // return this.toBuffer(object).toString("hex") - var b = this.toByteBuffer(object); - return b.toHex(); - }; - - Serializer.prototype.toByteBuffer = function toByteBuffer(object) { - var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); - this.appendByteBuffer(b, object); - return b.copy(0, b.offset); - }; - - Serializer.prototype.toBuffer = function toBuffer(object) { - return Buffer.from(this.toByteBuffer(object).toBinary(), "binary"); - }; - - return Serializer; -}(); - -exports.default = Serializer; -module.exports = exports["default"]; -}).call(this,require('_process')) - -},{"./error_with_cause":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/error_with_cause.js","_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","bytebuffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bytebuffer/dist/bytebuffer.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/template.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.default = template; -/** Console print any transaction object with zero default values. */ -function template(op) { - var object = op.toObject(void 0, { use_default: true, annotate: true }); - - // visual (with descriptions) - console.error(JSON.stringify(object, null, 4)); - - // usable in a copy-paste - - object = op.toObject(void 0, { use_default: true, annotate: false }); - - // copy-paste one-lineer - console.error(JSON.stringify(object)); -} -module.exports = exports["default"]; -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/types.js":[function(require,module,exports){ -(function (process){ -"use strict"; - -exports.__esModule = true; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // Low-level types that make up operations - -var _SerializerValidation = require("./SerializerValidation"); - -var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation); - -var _FastParser = require("./FastParser"); - -var _FastParser2 = _interopRequireDefault(_FastParser); - -var _ChainTypes = require("../../chain/src/ChainTypes"); - -var _ChainTypes2 = _interopRequireDefault(_ChainTypes); - -var _ObjectId = require("../../chain/src/ObjectId"); - -var _ObjectId2 = _interopRequireDefault(_ObjectId); - -var _ecc = require("../../ecc"); - -var _bitsharesjsWs = require("bitsharesjs-ws"); - -var _bytebuffer = require("bytebuffer"); - -var _bytebuffer2 = _interopRequireDefault(_bytebuffer); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var Buffer = require("safe-buffer").Buffer; - -var Types = {}; - -var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump; - -Types.uint8 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint8(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(0, 0xff, object, "uint8 " + object); - b.writeUint8(object); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(0, 0xff, object, "uint8 " + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - _SerializerValidation2.default.require_range(0, 0xff, object, "uint8 " + object); - return parseInt(object); - } -}; - -Types.uint16 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint16(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(0, 0xffff, object, "uint16 " + object); - b.writeUint16(object); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(0, 0xffff, object, "uint16 " + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - _SerializerValidation2.default.require_range(0, 0xffff, object, "uint16 " + object); - return parseInt(object); - } -}; - -Types.uint32 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(0, 0xffffffff, object, "uint32 " + object); - b.writeUint32(object); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(0, 0xffffffff, object, "uint32 " + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - _SerializerValidation2.default.require_range(0, 0xffffffff, object, "uint32 " + object); - return parseInt(object); - } -}; - -var MIN_SIGNED_32 = -1 * Math.pow(2, 31); -var MAX_SIGNED_32 = Math.pow(2, 31) - 1; - -Types.varint32 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readVarint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, "uint32 " + object); - b.writeVarint32(object); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, "uint32 " + object); - return object; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return 0; - } - _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, "uint32 " + object); - return parseInt(object); - } -}; - -Types.int64 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readInt64(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - b.writeInt64(_SerializerValidation2.default.to_long(object)); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - return _SerializerValidation2.default.to_long(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return "0"; - } - _SerializerValidation2.default.required(object); - return _SerializerValidation2.default.to_long(object).toString(); - } -}; - -Types.uint64 = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint64(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - b.writeUint64(_SerializerValidation2.default.to_long(_SerializerValidation2.default.unsigned(object), undefined, true)); - return; - }, - fromObject: function fromObject(object) { - return _SerializerValidation2.default.to_long(_SerializerValidation2.default.unsigned(object), undefined, true); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return "0"; - } - return _SerializerValidation2.default.to_long(object, undefined, true).toString(); - } -}; - -Types.string = { - fromByteBuffer: function fromByteBuffer(b) { - var b_copy; - var len = b.readVarint32(); - b_copy = b.copy(b.offset, b.offset + len), b.skip(len); - return Buffer.from(b_copy.toBinary(), "binary"); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - b.writeVarint32(object.length); - b.append(object.toString("binary"), "binary"); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - return Buffer.from(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return ""; - } - return object.toString(); - } -}; - -Types.bytes = function (size) { - return { - fromByteBuffer: function fromByteBuffer(b) { - if (size === undefined) { - var b_copy; - var len = b.readVarint32(); - b_copy = b.copy(b.offset, b.offset + len), b.skip(len); - return Buffer.from(b_copy.toBinary(), "binary"); - } else { - b_copy = b.copy(b.offset, b.offset + size), b.skip(size); - return Buffer.from(b_copy.toBinary(), "binary"); - } - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - if (typeof object === "string") object = Buffer.from(object, "hex"); - - if (size === undefined) { - b.writeVarint32(object.length); - } - b.append(object.toString("binary"), "binary"); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - if (Buffer.isBuffer(object)) return object; - - return Buffer.from(object, "hex"); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - var zeros = function zeros(num) { - return new Array(num).join("00"); - }; - return zeros(size); - } - _SerializerValidation2.default.required(object); - return object.toString("hex"); - } - }; -}; - -Types.bool = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint8() === 1; - }, - appendByteBuffer: function appendByteBuffer(b, object) { - // supports boolean or integer - b.writeUint8(JSON.parse(object) ? 1 : 0); - return; - }, - fromObject: function fromObject(object) { - return JSON.parse(object) ? true : false; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return false; - } - return JSON.parse(object) ? true : false; - } -}; - -Types.void = { - fromByteBuffer: function fromByteBuffer(b) { - throw new Error("(void) undefined type"); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - throw new Error("(void) undefined type"); - }, - fromObject: function fromObject(object) { - throw new Error("(void) undefined type"); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return undefined; - } - throw new Error("(void) undefined type"); - } -}; - -Types.array = function (st_operation) { - return { - fromByteBuffer: function fromByteBuffer(b) { - var size = b.readVarint32(); - if (HEX_DUMP) { - console.log("varint32 size = " + size.toString(16)); - } - var result = []; - for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) { - result.push(st_operation.fromByteBuffer(b)); - } - return sortOperation(result, st_operation); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - b.writeVarint32(object.length); - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - st_operation.appendByteBuffer(b, o); - } - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - var result = []; - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - result.push(st_operation.fromObject(o)); - } - return result; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [st_operation.toObject(object, debug)]; - } - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - - var result = []; - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - result.push(st_operation.toObject(o, debug)); - } - return result; - } - }; -}; - -Types.time_point_sec = { - fromByteBuffer: function fromByteBuffer(b) { - return b.readUint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - if (typeof object !== "number") object = Types.time_point_sec.fromObject(object); - - b.writeUint32(object); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - - if (typeof object === "number") return object; - - if (object.getTime) return Math.floor(object.getTime() / 1000); - - if (typeof object !== "string") throw new Error("Unknown date type: " + object); - - if (/T[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$/.test(object)) object = object + "Z"; - - return Math.floor(new Date(object).getTime() / 1000); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) return new Date(0).toISOString().split(".")[0]; - - _SerializerValidation2.default.required(object); - - if (typeof object === "string") return object; - - if (object.getTime) return object.toISOString().split(".")[0]; - - var int = parseInt(object); - _SerializerValidation2.default.require_range(0, 0xffffffff, int, "uint32 " + object); - return new Date(int * 1000).toISOString().split(".")[0]; - } -}; - -Types.set = function (st_operation) { - return { - validate: function validate(array) { - var dup_map = {}; - for (var i = 0, o; i < array.length; i++) { - o = array[i]; - var ref; - if (ref = typeof o === "undefined" ? "undefined" : _typeof(o), ["string", "number"].indexOf(ref) >= 0) { - if (dup_map[o] !== undefined) { - throw new Error("duplicate (set)"); - } - dup_map[o] = true; - } - } - return sortOperation(array, st_operation); - }, - fromByteBuffer: function fromByteBuffer(b) { - var size = b.readVarint32(); - if (HEX_DUMP) { - console.log("varint32 size = " + size.toString(16)); - } - return this.validate(function () { - var result = []; - for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) { - result.push(st_operation.fromByteBuffer(b)); - } - return result; - }()); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - if (!object) { - object = []; - } - b.writeVarint32(object.length); - var iterable = this.validate(object); - for (var i = 0, o; i < iterable.length; i++) { - o = iterable[i]; - st_operation.appendByteBuffer(b, o); - } - return; - }, - fromObject: function fromObject(object) { - if (!object) { - object = []; - } - return this.validate(function () { - var result = []; - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - result.push(st_operation.fromObject(o)); - } - return result; - }()); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [st_operation.toObject(object, debug)]; - } - if (!object) { - object = []; - } - return this.validate(function () { - var result = []; - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - result.push(st_operation.toObject(o, debug)); - } - return result; - }()); - } - }; -}; - -// global_parameters_update_operation current_fees -Types.fixed_array = function (count, st_operation) { - return { - fromByteBuffer: function fromByteBuffer(b) { - var i, j, ref, results; - results = []; - for (i = j = 0, ref = count; j < ref; i = j += 1) { - results.push(st_operation.fromByteBuffer(b)); - } - return sortOperation(results, st_operation); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - var i, j, ref; - if (count !== 0) { - _SerializerValidation2.default.required(object); - object = sortOperation(object, st_operation); - } - for (i = j = 0, ref = count; j < ref; i = j += 1) { - st_operation.appendByteBuffer(b, object[i]); - } - }, - fromObject: function fromObject(object) { - var i, j, ref, results; - if (count !== 0) { - _SerializerValidation2.default.required(object); - } - results = []; - for (i = j = 0, ref = count; j < ref; i = j += 1) { - results.push(st_operation.fromObject(object[i])); - } - return results; - }, - toObject: function toObject(object, debug) { - var i, j, k, ref, ref1, results, results1; - if (debug == null) { - debug = {}; - } - if (debug.use_default && object === void 0) { - results = []; - for (i = j = 0, ref = count; j < ref; i = j += 1) { - results.push(st_operation.toObject(void 0, debug)); - } - return results; - } - if (count !== 0) { - _SerializerValidation2.default.required(object); - } - results1 = []; - for (i = k = 0, ref1 = count; k < ref1; i = k += 1) { - results1.push(st_operation.toObject(object[i], debug)); - } - return results1; - } - }; -}; - -/* Supports instance numbers (11) or object types (1.2.11). Object type -Validation is enforced when an object type is used. */ -var id_type = function id_type(reserved_spaces, object_type) { - _SerializerValidation2.default.required(reserved_spaces, "reserved_spaces"); - _SerializerValidation2.default.required(object_type, "object_type"); - return { - fromByteBuffer: function fromByteBuffer(b) { - return b.readVarint32(); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } - // convert 1.2.n into just n - if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { - object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); - } - b.writeVarint32(_SerializerValidation2.default.to_number(object)); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } - if (_SerializerValidation2.default.is_digits(object)) { - return _SerializerValidation2.default.to_number(object); - } - return _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - var object_type_id = _ChainTypes2.default.object_type[object_type]; - if (debug.use_default && object === undefined) { - return reserved_spaces + "." + object_type_id + ".0"; - } - _SerializerValidation2.default.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } - if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) { - object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object); - } - - return reserved_spaces + "." + object_type_id + "." + object; - } - }; -}; - -Types.protocol_id_type = function (name) { - _SerializerValidation2.default.required(name, "name"); - return id_type(_ChainTypes2.default.reserved_spaces.protocol_ids, name); -}; - -Types.object_id_type = { - fromByteBuffer: function fromByteBuffer(b) { - return _ObjectId2.default.fromByteBuffer(b); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } - object = _ObjectId2.default.fromString(object); - object.appendByteBuffer(b); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } - return _ObjectId2.default.fromString(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return "0.0.0"; - } - _SerializerValidation2.default.required(object); - if (object.resolve !== undefined) { - object = object.resolve; - } - object = _ObjectId2.default.fromString(object); - return object.toString(); - } -}; - -Types.vote_id = { - TYPE: 0x000000ff, - ID: 0xffffff00, - fromByteBuffer: function fromByteBuffer(b) { - var value = b.readUint32(); - return { - type: value & this.TYPE, - id: value & this.ID - }; - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - if (object === "string") object = Types.vote_id.fromObject(object); - - var value = object.id << 8 | object.type; - b.writeUint32(value); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object, "(type vote_id)"); - if ((typeof object === "undefined" ? "undefined" : _typeof(object)) === "object") { - _SerializerValidation2.default.required(object.type, "type"); - _SerializerValidation2.default.required(object.id, "id"); - return object; - } - _SerializerValidation2.default.require_test(/^[0-9]+:[0-9]+$/, object, "vote_id format " + object); - - var _object$split = object.split(":"), - type = _object$split[0], - id = _object$split[1]; - - _SerializerValidation2.default.require_range(0, 0xff, type, "vote type " + object); - _SerializerValidation2.default.require_range(0, 0xffffff, id, "vote id " + object); - return { type: type, id: id }; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return "0:0"; - } - _SerializerValidation2.default.required(object); - if (typeof object === "string") object = Types.vote_id.fromObject(object); - - return object.type + ":" + object.id; - }, - compare: function compare(a, b) { - if ((typeof a === "undefined" ? "undefined" : _typeof(a)) !== "object") a = Types.vote_id.fromObject(a); - if ((typeof b === "undefined" ? "undefined" : _typeof(b)) !== "object") b = Types.vote_id.fromObject(b); - return parseInt(a.id) - parseInt(b.id); - } -}; - -Types.optional = function (st_operation) { - _SerializerValidation2.default.required(st_operation, "st_operation"); - return { - fromByteBuffer: function fromByteBuffer(b) { - if (!(b.readUint8() === 1)) { - return undefined; - } - return st_operation.fromByteBuffer(b); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - if (object !== null && object !== undefined) { - b.writeUint8(1); - st_operation.appendByteBuffer(b, object); - } else { - b.writeUint8(0); - } - return; - }, - fromObject: function fromObject(object) { - if (object === undefined) { - return undefined; - } - return st_operation.fromObject(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - // toObject is only null save if use_default is true - var result_object = function () { - if (!debug.use_default && object === undefined) { - return undefined; - } else { - return st_operation.toObject(object, debug); - } - }(); - - if (debug.annotate) { - if ((typeof result_object === "undefined" ? "undefined" : _typeof(result_object)) === "object") { - result_object.__optional = "parent is optional"; - } else { - result_object = { __optional: result_object }; - } - } - return result_object; - } - }; -}; - -Types.extension = function (fields_def) { - // fields_def is an array - _SerializerValidation2.default.require_array(fields_def, function (r) { - _SerializerValidation2.default.string(r.name); - _SerializerValidation2.default.required(r.type, "st_operation"); - }); - //v.required(st_operation, "st_operation"); - return { - fromByteBuffer: function fromByteBuffer(b) { - var count = b.readVarint32(); - if (count === 0) { - return undefined; - } - var o = {}; - if (count > fields_def.length) { - throw new Error('two many fields'); - } - while (count > 0) { - var index = b.readVarint32(); - if (index >= fields_def.length) { - throw new Error('index out of range'); - } - var operation = fields_def[index]; - o[operation.name] = operation.type.fromByteBuffer(b); - count--; - } - return o; - // return st_operation.fromByteBuffer(b); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - //let tempBuffer = new Buffer([]); - var tempBuffer = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN); - var count = 0; - if (object) { - fields_def.forEach(function (f, i) { - if (object[f.name] !== undefined && object[f.name] !== null) { - tempBuffer.writeVarint32(i); - f.type.appendByteBuffer(tempBuffer, object[f.name]); - count++; - } - }); - } - b.writeVarint32(count); - tempBuffer.flip(); - b.append(tempBuffer); - - return; - }, - fromObject: function fromObject(object) { - if (object === undefined) { - return undefined; - } - /* - return st_operation.fromObject(object); - */ - var result = {}; - fields_def.forEach(function (f) { - if (object[f.name] !== undefined && object[f.name] !== null) { - result[f.name] = f.type.fromObject(object[f.name]); - } - }); - return result; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - // toObject is only null save if use_default is true - var result_object = function () { - if (object === undefined) { - return undefined; - } else { - // return st_operation.toObject(object, debug); - var result = {}; - fields_def.forEach(function (f) { - if (object[f.name] !== undefined && object[f.name] !== null) { - result[f.name] = f.type.toObject(object[f.name], debug); - } - }); - return result; - } - }(); - - if (debug.annotate) { - if ((typeof result_object === "undefined" ? "undefined" : _typeof(result_object)) === "object") { - result_object.__optional = "parent is optional"; - } else { - result_object = { __optional: result_object }; - } - } - return result_object; - } - }; -}; - -Types.static_variant = function (_st_operations) { - return { - nosort: true, - st_operations: _st_operations, - fromByteBuffer: function fromByteBuffer(b) { - var type_id = b.readVarint32(); - var st_operation = this.st_operations[type_id]; - if (HEX_DUMP) { - console.error("static_variant id 0x" + type_id.toString(16) + " (" + type_id + ")"); - } - _SerializerValidation2.default.required(st_operation, "operation " + type_id); - return [type_id, st_operation.fromByteBuffer(b)]; - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - var type_id = object[0]; - var st_operation = this.st_operations[type_id]; - _SerializerValidation2.default.required(st_operation, "operation " + type_id); - b.writeVarint32(type_id); - st_operation.appendByteBuffer(b, object[1]); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - var type_id = object[0]; - var st_operation = this.st_operations[type_id]; - _SerializerValidation2.default.required(st_operation, "operation " + type_id); - return [type_id, st_operation.fromObject(object[1])]; - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [0, this.st_operations[0].toObject(undefined, debug)]; - } - _SerializerValidation2.default.required(object); - var type_id = object[0]; - var st_operation = this.st_operations[type_id]; - _SerializerValidation2.default.required(st_operation, "operation " + type_id); - return [type_id, st_operation.toObject(object[1], debug)]; - } - }; -}; - -Types.map = function (key_st_operation, value_st_operation) { - return { - validate: function validate(array) { - if (!Array.isArray(array)) { - throw new Error("expecting array"); - } - var dup_map = {}; - for (var i = 0, o; i < array.length; i++) { - o = array[i]; - var ref; - if (!(o.length === 2)) { - throw new Error("expecting two elements"); - } - if (ref = _typeof(o[0]), ["number", "string"].indexOf(ref) >= 0) { - if (dup_map[o[0]] !== undefined) { - throw new Error("duplicate (map)"); - } - dup_map[o[0]] = true; - } - } - return sortOperation(array, key_st_operation); - }, - fromByteBuffer: function fromByteBuffer(b) { - var result = []; - var end = b.readVarint32(); - for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) { - result.push([key_st_operation.fromByteBuffer(b), value_st_operation.fromByteBuffer(b)]); - } - return this.validate(result); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - this.validate(object); - b.writeVarint32(object.length); - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - key_st_operation.appendByteBuffer(b, o[0]); - value_st_operation.appendByteBuffer(b, o[1]); - } - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - var result = []; - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - result.push([key_st_operation.fromObject(o[0]), value_st_operation.fromObject(o[1])]); - } - return this.validate(result); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return [[key_st_operation.toObject(undefined, debug), value_st_operation.toObject(undefined, debug)]]; - } - _SerializerValidation2.default.required(object); - object = this.validate(object); - var result = []; - for (var i = 0, o; i < object.length; i++) { - o = object[i]; - result.push([key_st_operation.toObject(o[0], debug), value_st_operation.toObject(o[1], debug)]); - } - return result; - } - }; -}; - -Types.public_key = { - toPublic: function toPublic(object) { - if (object.resolve !== undefined) { - object = object.resolve; - } - return object == null ? object : object.Q ? object : _ecc.PublicKey.fromStringOrThrow(object); - }, - fromByteBuffer: function fromByteBuffer(b) { - return _FastParser2.default.public_key(b); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _SerializerValidation2.default.required(object); - _FastParser2.default.public_key(b, Types.public_key.toPublic(object)); - return; - }, - fromObject: function fromObject(object) { - _SerializerValidation2.default.required(object); - if (object.Q) { - return object; - } - return Types.public_key.toPublic(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return _bitsharesjsWs.ChainConfig.address_prefix + "859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM"; - } - _SerializerValidation2.default.required(object); - return object.toString(); - }, - compare: function compare(a, b) { - return Types.public_key.fromObject(a).toBlockchainAddress().compare(Types.public_key.fromObject(b).toBlockchainAddress()); - } -}; - -Types.address = { - _to_address: function _to_address(object) { - _SerializerValidation2.default.required(object); - if (object.addy) { - return object; - } - return _ecc.Address.fromString(object); - }, - fromByteBuffer: function fromByteBuffer(b) { - return new _ecc.Address(_FastParser2.default.ripemd160(b)); - }, - appendByteBuffer: function appendByteBuffer(b, object) { - _FastParser2.default.ripemd160(b, Types.address._to_address(object).toBuffer()); - return; - }, - fromObject: function fromObject(object) { - return Types.address._to_address(object); - }, - toObject: function toObject(object) { - var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (debug.use_default && object === undefined) { - return _bitsharesjsWs.ChainConfig.address_prefix + "664KmHxSuQyDsfwo4WEJvWpzg1QKdg67S"; - } - return Types.address._to_address(object).toString(); - }, - compare: function compare(a, b) { - return strCmp(a.toString(), b.toString()); - } -}; - -var strCmp = function strCmp(a, b) { - return a > b ? 1 : a < b ? -1 : 0; -}; -var firstEl = function firstEl(el) { - return Array.isArray(el) ? el[0] : el; -}; -var sortOperation = function sortOperation(array, st_operation) { - return st_operation.nosort ? array : st_operation.compare ? array.sort(function (a, b) { - return st_operation.compare(firstEl(a), firstEl(b)); - }) // custom compare operation - : array.sort(function (a, b) { - return typeof firstEl(a) === "number" && typeof firstEl(b) === "number" ? firstEl(a) - firstEl(b) : // A binary string compare does not work. Performanance is very good so HEX is used.. localeCompare is another option. - Buffer.isBuffer(firstEl(a)) && Buffer.isBuffer(firstEl(b)) ? strCmp(firstEl(a).toString("hex"), firstEl(b).toString("hex")) : strCmp(firstEl(a).toString(), firstEl(b).toString()); - }); -}; - -exports.default = Types; -module.exports = exports["default"]; -}).call(this,require('_process')) - -},{"../../chain/src/ChainTypes":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/chain/src/ChainTypes.js","../../chain/src/ObjectId":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/chain/src/ObjectId.js","../../ecc":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/index.js","./FastParser":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/FastParser.js","./SerializerValidation":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/SerializerValidation.js","_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","bitsharesjs-ws":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/index.js","bytebuffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bytebuffer/dist/bytebuffer.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js":[function(require,module,exports){ -(function (global){ -'use strict'; - -// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js -// original notice: - -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -function compare(a, b) { - if (a === b) { - return 0; - } - - var x = a.length; - var y = b.length; - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i]; - y = b[i]; - break; - } - } - - if (x < y) { - return -1; - } - if (y < x) { - return 1; - } - return 0; -} -function isBuffer(b) { - if (global.Buffer && typeof global.Buffer.isBuffer === 'function') { - return global.Buffer.isBuffer(b); - } - return !!(b != null && b._isBuffer); -} - -// based on node assert, original notice: - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -var util = require('util/'); -var hasOwn = Object.prototype.hasOwnProperty; -var pSlice = Array.prototype.slice; -var functionsHaveNames = (function () { - return function foo() {}.name === 'foo'; -}()); -function pToString (obj) { - return Object.prototype.toString.call(obj); -} -function isView(arrbuf) { - if (isBuffer(arrbuf)) { - return false; - } - if (typeof global.ArrayBuffer !== 'function') { - return false; - } - if (typeof ArrayBuffer.isView === 'function') { - return ArrayBuffer.isView(arrbuf); - } - if (!arrbuf) { - return false; - } - if (arrbuf instanceof DataView) { - return true; - } - if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) { - return true; - } - return false; -} -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -var regex = /\s*function\s+([^\(\s]*)\s*/; -// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js -function getName(func) { - if (!util.isFunction(func)) { - return; - } - if (functionsHaveNames) { - return func.name; - } - var str = func.toString(); - var match = str.match(regex); - return match && match[1]; -} -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = getName(stackStartFunction); - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function truncate(s, n) { - if (typeof s === 'string') { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} -function inspect(something) { - if (functionsHaveNames || !util.isFunction(something)) { - return util.inspect(something); - } - var rawname = getName(something); - var name = rawname ? ': ' + rawname : ''; - return '[Function' + name + ']'; -} -function getMessage(self) { - return truncate(inspect(self.actual), 128) + ' ' + - self.operator + ' ' + - truncate(inspect(self.expected), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); - } -}; - -function _deepEqual(actual, expected, strict, memos) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - } else if (isBuffer(actual) && isBuffer(expected)) { - return compare(actual, expected) === 0; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if ((actual === null || typeof actual !== 'object') && - (expected === null || typeof expected !== 'object')) { - return strict ? actual === expected : actual == expected; - - // If both values are instances of typed arrays, wrap their underlying - // ArrayBuffers in a Buffer each to increase performance - // This optimization requires the arrays to have the same type as checked by - // Object.prototype.toString (aka pToString). Never perform binary - // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their - // bit patterns are not identical. - } else if (isView(actual) && isView(expected) && - pToString(actual) === pToString(expected) && - !(actual instanceof Float32Array || - actual instanceof Float64Array)) { - return compare(new Uint8Array(actual.buffer), - new Uint8Array(expected.buffer)) === 0; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else if (isBuffer(actual) !== isBuffer(expected)) { - return false; - } else { - memos = memos || {actual: [], expected: []}; - - var actualIndex = memos.actual.indexOf(actual); - if (actualIndex !== -1) { - if (actualIndex === memos.expected.indexOf(expected)) { - return true; - } - } - - memos.actual.push(actual); - memos.expected.push(expected); - - return objEquiv(actual, expected, strict, memos); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b, strict, actualVisitedObjects) { - if (a === null || a === undefined || b === null || b === undefined) - return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) - return a === b; - if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) - return false; - var aIsArgs = isArguments(a); - var bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b, strict); - } - var ka = objectKeys(a); - var kb = objectKeys(b); - var key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length !== kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] !== kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) - return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -assert.notDeepStrictEqual = notDeepStrictEqual; -function notDeepStrictEqual(actual, expected, message) { - if (_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); - } -} - - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } - - try { - if (actual instanceof expected) { - return true; - } - } catch (e) { - // Ignore. The instanceof check doesn't work for arrow functions. - } - - if (Error.isPrototypeOf(expected)) { - return false; - } - - return expected.call({}, actual) === true; -} - -function _tryBlock(block) { - var error; - try { - block(); - } catch (e) { - error = e; - } - return error; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (typeof block !== 'function') { - throw new TypeError('"block" argument must be a function'); - } - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - actual = _tryBlock(block); - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - var userProvidedMessage = typeof message === 'string'; - var isUnwantedException = !shouldThrow && util.isError(actual); - var isUnexpectedException = !shouldThrow && actual && !expected; - - if ((isUnwantedException && - userProvidedMessage && - expectedException(actual, expected)) || - isUnexpectedException) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws(true, block, error, message); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws(false, block, error, message); -}; - -assert.ifError = function(err) { if (err) throw err; }; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"util/":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util/util.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/base-x/index.js":[function(require,module,exports){ -// base-x encoding -// Forked from https://github.com/cryptocoinjs/bs58 -// Originally written by Mike Hearn for BitcoinJ -// Copyright (c) 2011 Google Inc -// Ported to JavaScript by Stefan Thomas -// Merged Buffer refactorings from base58-native by Stephen Pair -// Copyright (c) 2013 BitPay Inc - -var Buffer = require('safe-buffer').Buffer - -module.exports = function base (ALPHABET) { - var ALPHABET_MAP = {} - var BASE = ALPHABET.length - var LEADER = ALPHABET.charAt(0) - - // pre-compute lookup table - for (var z = 0; z < ALPHABET.length; z++) { - var x = ALPHABET.charAt(z) - - if (ALPHABET_MAP[x] !== undefined) throw new TypeError(x + ' is ambiguous') - ALPHABET_MAP[x] = z - } - - function encode (source) { - if (source.length === 0) return '' - - var digits = [0] - for (var i = 0; i < source.length; ++i) { - for (var j = 0, carry = source[i]; j < digits.length; ++j) { - carry += digits[j] << 8 - digits[j] = carry % BASE - carry = (carry / BASE) | 0 - } - - while (carry > 0) { - digits.push(carry % BASE) - carry = (carry / BASE) | 0 - } - } - - var string = '' - - // deal with leading zeros - for (var k = 0; source[k] === 0 && k < source.length - 1; ++k) string += ALPHABET[0] - // convert digits to a string - for (var q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]] - - return string - } - - function decodeUnsafe (string) { - if (string.length === 0) return Buffer.allocUnsafe(0) - - var bytes = [0] - for (var i = 0; i < string.length; i++) { - var value = ALPHABET_MAP[string[i]] - if (value === undefined) return - - for (var j = 0, carry = value; j < bytes.length; ++j) { - carry += bytes[j] * BASE - bytes[j] = carry & 0xff - carry >>= 8 - } - - while (carry > 0) { - bytes.push(carry & 0xff) - carry >>= 8 - } - } - - // deal with leading zeros - for (var k = 0; string[k] === LEADER && k < string.length - 1; ++k) { - bytes.push(0) - } - - return Buffer.from(bytes.reverse()) - } - - function decode (string) { - var buffer = decodeUnsafe(string) - if (buffer) return buffer - - throw new Error('Non-base' + BASE + ' character') - } - - return { - encode: encode, - decodeUnsafe: decodeUnsafe, - decode: decode - } -} - -},{"safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/base64-js/index.js":[function(require,module,exports){ -'use strict' - -exports.byteLength = byteLength -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i -} - -// Support decoding URL-safe base64 strings, as Node.js does. -// See: https://en.wikipedia.org/wiki/Base64#URL_applications -revLookup['-'.charCodeAt(0)] = 62 -revLookup['_'.charCodeAt(0)] = 63 - -function getLens (b64) { - var len = b64.length - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // Trim off extra bytes after placeholder bytes are found - // See: https://github.com/beatgammit/base64-js/issues/42 - var validLen = b64.indexOf('=') - if (validLen === -1) validLen = len - - var placeHoldersLen = validLen === len - ? 0 - : 4 - (validLen % 4) - - return [validLen, placeHoldersLen] -} - -// base64 is 4/3 + up to two characters of the original data -function byteLength (b64) { - var lens = getLens(b64) - var validLen = lens[0] - var placeHoldersLen = lens[1] - return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen -} - -function _byteLength (b64, validLen, placeHoldersLen) { - return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen -} - -function toByteArray (b64) { - var tmp - var lens = getLens(b64) - var validLen = lens[0] - var placeHoldersLen = lens[1] - - var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) - - var curByte = 0 - - // if there are placeholders, only get up to the last complete 4 chars - var len = placeHoldersLen > 0 - ? validLen - 4 - : validLen - - for (var i = 0; i < len; i += 4) { - tmp = - (revLookup[b64.charCodeAt(i)] << 18) | - (revLookup[b64.charCodeAt(i + 1)] << 12) | - (revLookup[b64.charCodeAt(i + 2)] << 6) | - revLookup[b64.charCodeAt(i + 3)] - arr[curByte++] = (tmp >> 16) & 0xFF - arr[curByte++] = (tmp >> 8) & 0xFF - arr[curByte++] = tmp & 0xFF - } - - if (placeHoldersLen === 2) { - tmp = - (revLookup[b64.charCodeAt(i)] << 2) | - (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[curByte++] = tmp & 0xFF - } - - if (placeHoldersLen === 1) { - tmp = - (revLookup[b64.charCodeAt(i)] << 10) | - (revLookup[b64.charCodeAt(i + 1)] << 4) | - (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[curByte++] = (tmp >> 8) & 0xFF - arr[curByte++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + - lookup[num >> 12 & 0x3F] + - lookup[num >> 6 & 0x3F] + - lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = - ((uint8[i] << 16) & 0xFF0000) + - ((uint8[i + 1] << 8) & 0xFF00) + - (uint8[i + 2] & 0xFF) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk( - uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) - )) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - parts.push( - lookup[tmp >> 2] + - lookup[(tmp << 4) & 0x3F] + - '==' - ) - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + uint8[len - 1] - parts.push( - lookup[tmp >> 10] + - lookup[(tmp >> 4) & 0x3F] + - lookup[(tmp << 2) & 0x3F] + - '=' - ) - } - - return parts.join('') -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/bigi.js":[function(require,module,exports){ -// (public) Constructor -function BigInteger(a, b, c) { - if (!(this instanceof BigInteger)) - return new BigInteger(a, b, c) - - if (a != null) { - if ("number" == typeof a) this.fromNumber(a, b, c) - else if (b == null && "string" != typeof a) this.fromString(a, 256) - else this.fromString(a, b) - } -} - -var proto = BigInteger.prototype - -// duck-typed isBigInteger -proto.__bigi = require('../package.json').version -BigInteger.isBigInteger = function (obj, check_ver) { - return obj && obj.__bigi && (!check_ver || obj.__bigi === proto.__bigi) -} - -// Bits per digit -var dbits - -// am: Compute w_j += (x*this_i), propagate carries, -// c is initial carry, returns final carry. -// c < 3*dvalue, x < 2*dvalue, this_i < dvalue -// We need to select the fastest one that works in this environment. - -// am1: use a single mult and divide to get the high bits, -// max digit bits should be 26 because -// max internal value = 2*dvalue^2-2*dvalue (< 2^53) -function am1(i, x, w, j, c, n) { - while (--n >= 0) { - var v = x * this[i++] + w[j] + c - c = Math.floor(v / 0x4000000) - w[j++] = v & 0x3ffffff - } - return c -} -// am2 avoids a big mult-and-extract completely. -// Max digit bits should be <= 30 because we do bitwise ops -// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) -function am2(i, x, w, j, c, n) { - var xl = x & 0x7fff, - xh = x >> 15 - while (--n >= 0) { - var l = this[i] & 0x7fff - var h = this[i++] >> 15 - var m = xh * l + h * xl - l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff) - c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30) - w[j++] = l & 0x3fffffff - } - return c -} -// Alternately, set max digit bits to 28 since some -// browsers slow down when dealing with 32-bit numbers. -function am3(i, x, w, j, c, n) { - var xl = x & 0x3fff, - xh = x >> 14 - while (--n >= 0) { - var l = this[i] & 0x3fff - var h = this[i++] >> 14 - var m = xh * l + h * xl - l = xl * l + ((m & 0x3fff) << 14) + w[j] + c - c = (l >> 28) + (m >> 14) + xh * h - w[j++] = l & 0xfffffff - } - return c -} - -// wtf? -BigInteger.prototype.am = am1 -dbits = 26 - -BigInteger.prototype.DB = dbits -BigInteger.prototype.DM = ((1 << dbits) - 1) -var DV = BigInteger.prototype.DV = (1 << dbits) - -var BI_FP = 52 -BigInteger.prototype.FV = Math.pow(2, BI_FP) -BigInteger.prototype.F1 = BI_FP - dbits -BigInteger.prototype.F2 = 2 * dbits - BI_FP - -// Digit conversions -var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz" -var BI_RC = new Array() -var rr, vv -rr = "0".charCodeAt(0) -for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv -rr = "a".charCodeAt(0) -for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv -rr = "A".charCodeAt(0) -for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv - -function int2char(n) { - return BI_RM.charAt(n) -} - -function intAt(s, i) { - var c = BI_RC[s.charCodeAt(i)] - return (c == null) ? -1 : c -} - -// (protected) copy this to r -function bnpCopyTo(r) { - for (var i = this.t - 1; i >= 0; --i) r[i] = this[i] - r.t = this.t - r.s = this.s -} - -// (protected) set from integer value x, -DV <= x < DV -function bnpFromInt(x) { - this.t = 1 - this.s = (x < 0) ? -1 : 0 - if (x > 0) this[0] = x - else if (x < -1) this[0] = x + DV - else this.t = 0 -} - -// return bigint initialized to value -function nbv(i) { - var r = new BigInteger() - r.fromInt(i) - return r -} - -// (protected) set from string and radix -function bnpFromString(s, b) { - var self = this - - var k - if (b == 16) k = 4 - else if (b == 8) k = 3 - else if (b == 256) k = 8; // byte array - else if (b == 2) k = 1 - else if (b == 32) k = 5 - else if (b == 4) k = 2 - else { - self.fromRadix(s, b) - return - } - self.t = 0 - self.s = 0 - var i = s.length, - mi = false, - sh = 0 - while (--i >= 0) { - var x = (k == 8) ? s[i] & 0xff : intAt(s, i) - if (x < 0) { - if (s.charAt(i) == "-") mi = true - continue - } - mi = false - if (sh == 0) - self[self.t++] = x - else if (sh + k > self.DB) { - self[self.t - 1] |= (x & ((1 << (self.DB - sh)) - 1)) << sh - self[self.t++] = (x >> (self.DB - sh)) - } else - self[self.t - 1] |= x << sh - sh += k - if (sh >= self.DB) sh -= self.DB - } - if (k == 8 && (s[0] & 0x80) != 0) { - self.s = -1 - if (sh > 0) self[self.t - 1] |= ((1 << (self.DB - sh)) - 1) << sh - } - self.clamp() - if (mi) BigInteger.ZERO.subTo(self, self) -} - -// (protected) clamp off excess high words -function bnpClamp() { - var c = this.s & this.DM - while (this.t > 0 && this[this.t - 1] == c)--this.t -} - -// (public) return string representation in given radix -function bnToString(b) { - var self = this - if (self.s < 0) return "-" + self.negate() - .toString(b) - var k - if (b == 16) k = 4 - else if (b == 8) k = 3 - else if (b == 2) k = 1 - else if (b == 32) k = 5 - else if (b == 4) k = 2 - else return self.toRadix(b) - var km = (1 << k) - 1, - d, m = false, - r = "", - i = self.t - var p = self.DB - (i * self.DB) % k - if (i-- > 0) { - if (p < self.DB && (d = self[i] >> p) > 0) { - m = true - r = int2char(d) - } - while (i >= 0) { - if (p < k) { - d = (self[i] & ((1 << p) - 1)) << (k - p) - d |= self[--i] >> (p += self.DB - k) - } else { - d = (self[i] >> (p -= k)) & km - if (p <= 0) { - p += self.DB - --i - } - } - if (d > 0) m = true - if (m) r += int2char(d) - } - } - return m ? r : "0" -} - -// (public) -this -function bnNegate() { - var r = new BigInteger() - BigInteger.ZERO.subTo(this, r) - return r -} - -// (public) |this| -function bnAbs() { - return (this.s < 0) ? this.negate() : this -} - -// (public) return + if this > a, - if this < a, 0 if equal -function bnCompareTo(a) { - var r = this.s - a.s - if (r != 0) return r - var i = this.t - r = i - a.t - if (r != 0) return (this.s < 0) ? -r : r - while (--i >= 0) - if ((r = this[i] - a[i]) != 0) return r - return 0 -} - -// returns bit length of the integer x -function nbits(x) { - var r = 1, - t - if ((t = x >>> 16) != 0) { - x = t - r += 16 - } - if ((t = x >> 8) != 0) { - x = t - r += 8 - } - if ((t = x >> 4) != 0) { - x = t - r += 4 - } - if ((t = x >> 2) != 0) { - x = t - r += 2 - } - if ((t = x >> 1) != 0) { - x = t - r += 1 - } - return r -} - -// (public) return the number of bits in "this" -function bnBitLength() { - if (this.t <= 0) return 0 - return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM)) -} - -// (public) return the number of bytes in "this" -function bnByteLength() { - return this.bitLength() >> 3 -} - -// (protected) r = this << n*DB -function bnpDLShiftTo(n, r) { - var i - for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i] - for (i = n - 1; i >= 0; --i) r[i] = 0 - r.t = this.t + n - r.s = this.s -} - -// (protected) r = this >> n*DB -function bnpDRShiftTo(n, r) { - for (var i = n; i < this.t; ++i) r[i - n] = this[i] - r.t = Math.max(this.t - n, 0) - r.s = this.s -} - -// (protected) r = this << n -function bnpLShiftTo(n, r) { - var self = this - var bs = n % self.DB - var cbs = self.DB - bs - var bm = (1 << cbs) - 1 - var ds = Math.floor(n / self.DB), - c = (self.s << bs) & self.DM, - i - for (i = self.t - 1; i >= 0; --i) { - r[i + ds + 1] = (self[i] >> cbs) | c - c = (self[i] & bm) << bs - } - for (i = ds - 1; i >= 0; --i) r[i] = 0 - r[ds] = c - r.t = self.t + ds + 1 - r.s = self.s - r.clamp() -} - -// (protected) r = this >> n -function bnpRShiftTo(n, r) { - var self = this - r.s = self.s - var ds = Math.floor(n / self.DB) - if (ds >= self.t) { - r.t = 0 - return - } - var bs = n % self.DB - var cbs = self.DB - bs - var bm = (1 << bs) - 1 - r[0] = self[ds] >> bs - for (var i = ds + 1; i < self.t; ++i) { - r[i - ds - 1] |= (self[i] & bm) << cbs - r[i - ds] = self[i] >> bs - } - if (bs > 0) r[self.t - ds - 1] |= (self.s & bm) << cbs - r.t = self.t - ds - r.clamp() -} - -// (protected) r = this - a -function bnpSubTo(a, r) { - var self = this - var i = 0, - c = 0, - m = Math.min(a.t, self.t) - while (i < m) { - c += self[i] - a[i] - r[i++] = c & self.DM - c >>= self.DB - } - if (a.t < self.t) { - c -= a.s - while (i < self.t) { - c += self[i] - r[i++] = c & self.DM - c >>= self.DB - } - c += self.s - } else { - c += self.s - while (i < a.t) { - c -= a[i] - r[i++] = c & self.DM - c >>= self.DB - } - c -= a.s - } - r.s = (c < 0) ? -1 : 0 - if (c < -1) r[i++] = self.DV + c - else if (c > 0) r[i++] = c - r.t = i - r.clamp() -} - -// (protected) r = this * a, r != this,a (HAC 14.12) -// "this" should be the larger one if appropriate. -function bnpMultiplyTo(a, r) { - var x = this.abs(), - y = a.abs() - var i = x.t - r.t = i + y.t - while (--i >= 0) r[i] = 0 - for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t) - r.s = 0 - r.clamp() - if (this.s != a.s) BigInteger.ZERO.subTo(r, r) -} - -// (protected) r = this^2, r != this (HAC 14.16) -function bnpSquareTo(r) { - var x = this.abs() - var i = r.t = 2 * x.t - while (--i >= 0) r[i] = 0 - for (i = 0; i < x.t - 1; ++i) { - var c = x.am(i, x[i], r, 2 * i, 0, 1) - if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) { - r[i + x.t] -= x.DV - r[i + x.t + 1] = 1 - } - } - if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1) - r.s = 0 - r.clamp() -} - -// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) -// r != q, this != m. q or r may be null. -function bnpDivRemTo(m, q, r) { - var self = this - var pm = m.abs() - if (pm.t <= 0) return - var pt = self.abs() - if (pt.t < pm.t) { - if (q != null) q.fromInt(0) - if (r != null) self.copyTo(r) - return - } - if (r == null) r = new BigInteger() - var y = new BigInteger(), - ts = self.s, - ms = m.s - var nsh = self.DB - nbits(pm[pm.t - 1]); // normalize modulus - if (nsh > 0) { - pm.lShiftTo(nsh, y) - pt.lShiftTo(nsh, r) - } else { - pm.copyTo(y) - pt.copyTo(r) - } - var ys = y.t - var y0 = y[ys - 1] - if (y0 == 0) return - var yt = y0 * (1 << self.F1) + ((ys > 1) ? y[ys - 2] >> self.F2 : 0) - var d1 = self.FV / yt, - d2 = (1 << self.F1) / yt, - e = 1 << self.F2 - var i = r.t, - j = i - ys, - t = (q == null) ? new BigInteger() : q - y.dlShiftTo(j, t) - if (r.compareTo(t) >= 0) { - r[r.t++] = 1 - r.subTo(t, r) - } - BigInteger.ONE.dlShiftTo(ys, t) - t.subTo(y, y); // "negative" y so we can replace sub with am later - while (y.t < ys) y[y.t++] = 0 - while (--j >= 0) { - // Estimate quotient digit - var qd = (r[--i] == y0) ? self.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2) - if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out - y.dlShiftTo(j, t) - r.subTo(t, r) - while (r[i] < --qd) r.subTo(t, r) - } - } - if (q != null) { - r.drShiftTo(ys, q) - if (ts != ms) BigInteger.ZERO.subTo(q, q) - } - r.t = ys - r.clamp() - if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder - if (ts < 0) BigInteger.ZERO.subTo(r, r) -} - -// (public) this mod a -function bnMod(a) { - var r = new BigInteger() - this.abs() - .divRemTo(a, null, r) - if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r) - return r -} - -// Modular reduction using "classic" algorithm -function Classic(m) { - this.m = m -} - -function cConvert(x) { - if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m) - else return x -} - -function cRevert(x) { - return x -} - -function cReduce(x) { - x.divRemTo(this.m, null, x) -} - -function cMulTo(x, y, r) { - x.multiplyTo(y, r) - this.reduce(r) -} - -function cSqrTo(x, r) { - x.squareTo(r) - this.reduce(r) -} - -Classic.prototype.convert = cConvert -Classic.prototype.revert = cRevert -Classic.prototype.reduce = cReduce -Classic.prototype.mulTo = cMulTo -Classic.prototype.sqrTo = cSqrTo - -// (protected) return "-1/this % 2^DB"; useful for Mont. reduction -// justification: -// xy == 1 (mod m) -// xy = 1+km -// xy(2-xy) = (1+km)(1-km) -// x[y(2-xy)] = 1-k^2m^2 -// x[y(2-xy)] == 1 (mod m^2) -// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 -// should reduce x and y(2-xy) by m^2 at each step to keep size bounded. -// JS multiply "overflows" differently from C/C++, so care is needed here. -function bnpInvDigit() { - if (this.t < 1) return 0 - var x = this[0] - if ((x & 1) == 0) return 0 - var y = x & 3; // y == 1/x mod 2^2 - y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 - y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 - y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y > 0) ? this.DV - y : -y -} - -// Montgomery reduction -function Montgomery(m) { - this.m = m - this.mp = m.invDigit() - this.mpl = this.mp & 0x7fff - this.mph = this.mp >> 15 - this.um = (1 << (m.DB - 15)) - 1 - this.mt2 = 2 * m.t -} - -// xR mod m -function montConvert(x) { - var r = new BigInteger() - x.abs() - .dlShiftTo(this.m.t, r) - r.divRemTo(this.m, null, r) - if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r) - return r -} - -// x/R mod m -function montRevert(x) { - var r = new BigInteger() - x.copyTo(r) - this.reduce(r) - return r -} - -// x = x/R mod m (HAC 14.32) -function montReduce(x) { - while (x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0 - for (var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i] & 0x7fff - var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM - // use am to combine the multiply-shift-add into one call - j = i + this.m.t - x[j] += this.m.am(0, u0, x, i, 0, this.m.t) - // propagate carry - while (x[j] >= x.DV) { - x[j] -= x.DV - x[++j]++ - } - } - x.clamp() - x.drShiftTo(this.m.t, x) - if (x.compareTo(this.m) >= 0) x.subTo(this.m, x) -} - -// r = "x^2/R mod m"; x != r -function montSqrTo(x, r) { - x.squareTo(r) - this.reduce(r) -} - -// r = "xy/R mod m"; x,y != r -function montMulTo(x, y, r) { - x.multiplyTo(y, r) - this.reduce(r) -} - -Montgomery.prototype.convert = montConvert -Montgomery.prototype.revert = montRevert -Montgomery.prototype.reduce = montReduce -Montgomery.prototype.mulTo = montMulTo -Montgomery.prototype.sqrTo = montSqrTo - -// (protected) true iff this is even -function bnpIsEven() { - return ((this.t > 0) ? (this[0] & 1) : this.s) == 0 -} - -// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) -function bnpExp(e, z) { - if (e > 0xffffffff || e < 1) return BigInteger.ONE - var r = new BigInteger(), - r2 = new BigInteger(), - g = z.convert(this), - i = nbits(e) - 1 - g.copyTo(r) - while (--i >= 0) { - z.sqrTo(r, r2) - if ((e & (1 << i)) > 0) z.mulTo(r2, g, r) - else { - var t = r - r = r2 - r2 = t - } - } - return z.revert(r) -} - -// (public) this^e % m, 0 <= e < 2^32 -function bnModPowInt(e, m) { - var z - if (e < 256 || m.isEven()) z = new Classic(m) - else z = new Montgomery(m) - return this.exp(e, z) -} - -// protected -proto.copyTo = bnpCopyTo -proto.fromInt = bnpFromInt -proto.fromString = bnpFromString -proto.clamp = bnpClamp -proto.dlShiftTo = bnpDLShiftTo -proto.drShiftTo = bnpDRShiftTo -proto.lShiftTo = bnpLShiftTo -proto.rShiftTo = bnpRShiftTo -proto.subTo = bnpSubTo -proto.multiplyTo = bnpMultiplyTo -proto.squareTo = bnpSquareTo -proto.divRemTo = bnpDivRemTo -proto.invDigit = bnpInvDigit -proto.isEven = bnpIsEven -proto.exp = bnpExp - -// public -proto.toString = bnToString -proto.negate = bnNegate -proto.abs = bnAbs -proto.compareTo = bnCompareTo -proto.bitLength = bnBitLength -proto.byteLength = bnByteLength -proto.mod = bnMod -proto.modPowInt = bnModPowInt - -// (public) -function bnClone() { - var r = new BigInteger() - this.copyTo(r) - return r -} - -// (public) return value as integer -function bnIntValue() { - if (this.s < 0) { - if (this.t == 1) return this[0] - this.DV - else if (this.t == 0) return -1 - } else if (this.t == 1) return this[0] - else if (this.t == 0) return 0 - // assumes 16 < DB < 32 - return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0] -} - -// (public) return value as byte -function bnByteValue() { - return (this.t == 0) ? this.s : (this[0] << 24) >> 24 -} - -// (public) return value as short (assumes DB>=16) -function bnShortValue() { - return (this.t == 0) ? this.s : (this[0] << 16) >> 16 -} - -// (protected) return x s.t. r^x < DV -function bnpChunkSize(r) { - return Math.floor(Math.LN2 * this.DB / Math.log(r)) -} - -// (public) 0 if this == 0, 1 if this > 0 -function bnSigNum() { - if (this.s < 0) return -1 - else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0 - else return 1 -} - -// (protected) convert to radix string -function bnpToRadix(b) { - if (b == null) b = 10 - if (this.signum() == 0 || b < 2 || b > 36) return "0" - var cs = this.chunkSize(b) - var a = Math.pow(b, cs) - var d = nbv(a), - y = new BigInteger(), - z = new BigInteger(), - r = "" - this.divRemTo(d, y, z) - while (y.signum() > 0) { - r = (a + z.intValue()) - .toString(b) - .substr(1) + r - y.divRemTo(d, y, z) - } - return z.intValue() - .toString(b) + r -} - -// (protected) convert from radix string -function bnpFromRadix(s, b) { - var self = this - self.fromInt(0) - if (b == null) b = 10 - var cs = self.chunkSize(b) - var d = Math.pow(b, cs), - mi = false, - j = 0, - w = 0 - for (var i = 0; i < s.length; ++i) { - var x = intAt(s, i) - if (x < 0) { - if (s.charAt(i) == "-" && self.signum() == 0) mi = true - continue - } - w = b * w + x - if (++j >= cs) { - self.dMultiply(d) - self.dAddOffset(w, 0) - j = 0 - w = 0 - } - } - if (j > 0) { - self.dMultiply(Math.pow(b, j)) - self.dAddOffset(w, 0) - } - if (mi) BigInteger.ZERO.subTo(self, self) -} - -// (protected) alternate constructor -function bnpFromNumber(a, b, c) { - var self = this - if ("number" == typeof b) { - // new BigInteger(int,int,RNG) - if (a < 2) self.fromInt(1) - else { - self.fromNumber(a, c) - if (!self.testBit(a - 1)) // force MSB set - self.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, self) - if (self.isEven()) self.dAddOffset(1, 0); // force odd - while (!self.isProbablePrime(b)) { - self.dAddOffset(2, 0) - if (self.bitLength() > a) self.subTo(BigInteger.ONE.shiftLeft(a - 1), self) - } - } - } else { - // new BigInteger(int,RNG) - var x = new Array(), - t = a & 7 - x.length = (a >> 3) + 1 - b.nextBytes(x) - if (t > 0) x[0] &= ((1 << t) - 1) - else x[0] = 0 - self.fromString(x, 256) - } -} - -// (public) convert to bigendian byte array -function bnToByteArray() { - var self = this - var i = self.t, - r = new Array() - r[0] = self.s - var p = self.DB - (i * self.DB) % 8, - d, k = 0 - if (i-- > 0) { - if (p < self.DB && (d = self[i] >> p) != (self.s & self.DM) >> p) - r[k++] = d | (self.s << (self.DB - p)) - while (i >= 0) { - if (p < 8) { - d = (self[i] & ((1 << p) - 1)) << (8 - p) - d |= self[--i] >> (p += self.DB - 8) - } else { - d = (self[i] >> (p -= 8)) & 0xff - if (p <= 0) { - p += self.DB - --i - } - } - if ((d & 0x80) != 0) d |= -256 - if (k === 0 && (self.s & 0x80) != (d & 0x80))++k - if (k > 0 || d != self.s) r[k++] = d - } - } - return r -} - -function bnEquals(a) { - return (this.compareTo(a) == 0) -} - -function bnMin(a) { - return (this.compareTo(a) < 0) ? this : a -} - -function bnMax(a) { - return (this.compareTo(a) > 0) ? this : a -} - -// (protected) r = this op a (bitwise) -function bnpBitwiseTo(a, op, r) { - var self = this - var i, f, m = Math.min(a.t, self.t) - for (i = 0; i < m; ++i) r[i] = op(self[i], a[i]) - if (a.t < self.t) { - f = a.s & self.DM - for (i = m; i < self.t; ++i) r[i] = op(self[i], f) - r.t = self.t - } else { - f = self.s & self.DM - for (i = m; i < a.t; ++i) r[i] = op(f, a[i]) - r.t = a.t - } - r.s = op(self.s, a.s) - r.clamp() -} - -// (public) this & a -function op_and(x, y) { - return x & y -} - -function bnAnd(a) { - var r = new BigInteger() - this.bitwiseTo(a, op_and, r) - return r -} - -// (public) this | a -function op_or(x, y) { - return x | y -} - -function bnOr(a) { - var r = new BigInteger() - this.bitwiseTo(a, op_or, r) - return r -} - -// (public) this ^ a -function op_xor(x, y) { - return x ^ y -} - -function bnXor(a) { - var r = new BigInteger() - this.bitwiseTo(a, op_xor, r) - return r -} - -// (public) this & ~a -function op_andnot(x, y) { - return x & ~y -} - -function bnAndNot(a) { - var r = new BigInteger() - this.bitwiseTo(a, op_andnot, r) - return r -} - -// (public) ~this -function bnNot() { - var r = new BigInteger() - for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i] - r.t = this.t - r.s = ~this.s - return r -} - -// (public) this << n -function bnShiftLeft(n) { - var r = new BigInteger() - if (n < 0) this.rShiftTo(-n, r) - else this.lShiftTo(n, r) - return r -} - -// (public) this >> n -function bnShiftRight(n) { - var r = new BigInteger() - if (n < 0) this.lShiftTo(-n, r) - else this.rShiftTo(n, r) - return r -} - -// return index of lowest 1-bit in x, x < 2^31 -function lbit(x) { - if (x == 0) return -1 - var r = 0 - if ((x & 0xffff) == 0) { - x >>= 16 - r += 16 - } - if ((x & 0xff) == 0) { - x >>= 8 - r += 8 - } - if ((x & 0xf) == 0) { - x >>= 4 - r += 4 - } - if ((x & 3) == 0) { - x >>= 2 - r += 2 - } - if ((x & 1) == 0)++r - return r -} - -// (public) returns index of lowest 1-bit (or -1 if none) -function bnGetLowestSetBit() { - for (var i = 0; i < this.t; ++i) - if (this[i] != 0) return i * this.DB + lbit(this[i]) - if (this.s < 0) return this.t * this.DB - return -1 -} - -// return number of 1 bits in x -function cbit(x) { - var r = 0 - while (x != 0) { - x &= x - 1 - ++r - } - return r -} - -// (public) return number of set bits -function bnBitCount() { - var r = 0, - x = this.s & this.DM - for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x) - return r -} - -// (public) true iff nth bit is set -function bnTestBit(n) { - var j = Math.floor(n / this.DB) - if (j >= this.t) return (this.s != 0) - return ((this[j] & (1 << (n % this.DB))) != 0) -} - -// (protected) this op (1<>= self.DB - } - if (a.t < self.t) { - c += a.s - while (i < self.t) { - c += self[i] - r[i++] = c & self.DM - c >>= self.DB - } - c += self.s - } else { - c += self.s - while (i < a.t) { - c += a[i] - r[i++] = c & self.DM - c >>= self.DB - } - c += a.s - } - r.s = (c < 0) ? -1 : 0 - if (c > 0) r[i++] = c - else if (c < -1) r[i++] = self.DV + c - r.t = i - r.clamp() -} - -// (public) this + a -function bnAdd(a) { - var r = new BigInteger() - this.addTo(a, r) - return r -} - -// (public) this - a -function bnSubtract(a) { - var r = new BigInteger() - this.subTo(a, r) - return r -} - -// (public) this * a -function bnMultiply(a) { - var r = new BigInteger() - this.multiplyTo(a, r) - return r -} - -// (public) this^2 -function bnSquare() { - var r = new BigInteger() - this.squareTo(r) - return r -} - -// (public) this / a -function bnDivide(a) { - var r = new BigInteger() - this.divRemTo(a, r, null) - return r -} - -// (public) this % a -function bnRemainder(a) { - var r = new BigInteger() - this.divRemTo(a, null, r) - return r -} - -// (public) [this/a,this%a] -function bnDivideAndRemainder(a) { - var q = new BigInteger(), - r = new BigInteger() - this.divRemTo(a, q, r) - return new Array(q, r) -} - -// (protected) this *= n, this >= 0, 1 < n < DV -function bnpDMultiply(n) { - this[this.t] = this.am(0, n - 1, this, 0, 0, this.t) - ++this.t - this.clamp() -} - -// (protected) this += n << w words, this >= 0 -function bnpDAddOffset(n, w) { - if (n == 0) return - while (this.t <= w) this[this.t++] = 0 - this[w] += n - while (this[w] >= this.DV) { - this[w] -= this.DV - if (++w >= this.t) this[this.t++] = 0 - ++this[w] - } -} - -// A "null" reducer -function NullExp() {} - -function nNop(x) { - return x -} - -function nMulTo(x, y, r) { - x.multiplyTo(y, r) -} - -function nSqrTo(x, r) { - x.squareTo(r) -} - -NullExp.prototype.convert = nNop -NullExp.prototype.revert = nNop -NullExp.prototype.mulTo = nMulTo -NullExp.prototype.sqrTo = nSqrTo - -// (public) this^e -function bnPow(e) { - return this.exp(e, new NullExp()) -} - -// (protected) r = lower n words of "this * a", a.t <= n -// "this" should be the larger one if appropriate. -function bnpMultiplyLowerTo(a, n, r) { - var i = Math.min(this.t + a.t, n) - r.s = 0; // assumes a,this >= 0 - r.t = i - while (i > 0) r[--i] = 0 - var j - for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t) - for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i) - r.clamp() -} - -// (protected) r = "this * a" without lower n words, n > 0 -// "this" should be the larger one if appropriate. -function bnpMultiplyUpperTo(a, n, r) { - --n - var i = r.t = this.t + a.t - n - r.s = 0; // assumes a,this >= 0 - while (--i >= 0) r[i] = 0 - for (i = Math.max(n - this.t, 0); i < a.t; ++i) - r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n) - r.clamp() - r.drShiftTo(1, r) -} - -// Barrett modular reduction -function Barrett(m) { - // setup Barrett - this.r2 = new BigInteger() - this.q3 = new BigInteger() - BigInteger.ONE.dlShiftTo(2 * m.t, this.r2) - this.mu = this.r2.divide(m) - this.m = m -} - -function barrettConvert(x) { - if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m) - else if (x.compareTo(this.m) < 0) return x - else { - var r = new BigInteger() - x.copyTo(r) - this.reduce(r) - return r - } -} - -function barrettRevert(x) { - return x -} - -// x = x mod m (HAC 14.42) -function barrettReduce(x) { - var self = this - x.drShiftTo(self.m.t - 1, self.r2) - if (x.t > self.m.t + 1) { - x.t = self.m.t + 1 - x.clamp() - } - self.mu.multiplyUpperTo(self.r2, self.m.t + 1, self.q3) - self.m.multiplyLowerTo(self.q3, self.m.t + 1, self.r2) - while (x.compareTo(self.r2) < 0) x.dAddOffset(1, self.m.t + 1) - x.subTo(self.r2, x) - while (x.compareTo(self.m) >= 0) x.subTo(self.m, x) -} - -// r = x^2 mod m; x != r -function barrettSqrTo(x, r) { - x.squareTo(r) - this.reduce(r) -} - -// r = x*y mod m; x,y != r -function barrettMulTo(x, y, r) { - x.multiplyTo(y, r) - this.reduce(r) -} - -Barrett.prototype.convert = barrettConvert -Barrett.prototype.revert = barrettRevert -Barrett.prototype.reduce = barrettReduce -Barrett.prototype.mulTo = barrettMulTo -Barrett.prototype.sqrTo = barrettSqrTo - -// (public) this^e % m (HAC 14.85) -function bnModPow(e, m) { - var i = e.bitLength(), - k, r = nbv(1), - z - if (i <= 0) return r - else if (i < 18) k = 1 - else if (i < 48) k = 3 - else if (i < 144) k = 4 - else if (i < 768) k = 5 - else k = 6 - if (i < 8) - z = new Classic(m) - else if (m.isEven()) - z = new Barrett(m) - else - z = new Montgomery(m) - - // precomputation - var g = new Array(), - n = 3, - k1 = k - 1, - km = (1 << k) - 1 - g[1] = z.convert(this) - if (k > 1) { - var g2 = new BigInteger() - z.sqrTo(g[1], g2) - while (n <= km) { - g[n] = new BigInteger() - z.mulTo(g2, g[n - 2], g[n]) - n += 2 - } - } - - var j = e.t - 1, - w, is1 = true, - r2 = new BigInteger(), - t - i = nbits(e[j]) - 1 - while (j >= 0) { - if (i >= k1) w = (e[j] >> (i - k1)) & km - else { - w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i) - if (j > 0) w |= e[j - 1] >> (this.DB + i - k1) - } - - n = k - while ((w & 1) == 0) { - w >>= 1 - --n - } - if ((i -= n) < 0) { - i += this.DB - --j - } - if (is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r) - is1 = false - } else { - while (n > 1) { - z.sqrTo(r, r2) - z.sqrTo(r2, r) - n -= 2 - } - if (n > 0) z.sqrTo(r, r2) - else { - t = r - r = r2 - r2 = t - } - z.mulTo(r2, g[w], r) - } - - while (j >= 0 && (e[j] & (1 << i)) == 0) { - z.sqrTo(r, r2) - t = r - r = r2 - r2 = t - if (--i < 0) { - i = this.DB - 1 - --j - } - } - } - return z.revert(r) -} - -// (public) gcd(this,a) (HAC 14.54) -function bnGCD(a) { - var x = (this.s < 0) ? this.negate() : this.clone() - var y = (a.s < 0) ? a.negate() : a.clone() - if (x.compareTo(y) < 0) { - var t = x - x = y - y = t - } - var i = x.getLowestSetBit(), - g = y.getLowestSetBit() - if (g < 0) return x - if (i < g) g = i - if (g > 0) { - x.rShiftTo(g, x) - y.rShiftTo(g, y) - } - while (x.signum() > 0) { - if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x) - if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y) - if (x.compareTo(y) >= 0) { - x.subTo(y, x) - x.rShiftTo(1, x) - } else { - y.subTo(x, y) - y.rShiftTo(1, y) - } - } - if (g > 0) y.lShiftTo(g, y) - return y -} - -// (protected) this % n, n < 2^26 -function bnpModInt(n) { - if (n <= 0) return 0 - var d = this.DV % n, - r = (this.s < 0) ? n - 1 : 0 - if (this.t > 0) - if (d == 0) r = this[0] % n - else - for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n - return r -} - -// (public) 1/this % m (HAC 14.61) -function bnModInverse(m) { - var ac = m.isEven() - if (this.signum() === 0) throw new Error('division by zero') - if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO - var u = m.clone(), - v = this.clone() - var a = nbv(1), - b = nbv(0), - c = nbv(0), - d = nbv(1) - while (u.signum() != 0) { - while (u.isEven()) { - u.rShiftTo(1, u) - if (ac) { - if (!a.isEven() || !b.isEven()) { - a.addTo(this, a) - b.subTo(m, b) - } - a.rShiftTo(1, a) - } else if (!b.isEven()) b.subTo(m, b) - b.rShiftTo(1, b) - } - while (v.isEven()) { - v.rShiftTo(1, v) - if (ac) { - if (!c.isEven() || !d.isEven()) { - c.addTo(this, c) - d.subTo(m, d) - } - c.rShiftTo(1, c) - } else if (!d.isEven()) d.subTo(m, d) - d.rShiftTo(1, d) - } - if (u.compareTo(v) >= 0) { - u.subTo(v, u) - if (ac) a.subTo(c, a) - b.subTo(d, b) - } else { - v.subTo(u, v) - if (ac) c.subTo(a, c) - d.subTo(b, d) - } - } - if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO - while (d.compareTo(m) >= 0) d.subTo(m, d) - while (d.signum() < 0) d.addTo(m, d) - return d -} - -var lowprimes = [ - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, - 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, - 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, - 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, - 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, - 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, - 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, - 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, - 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, - 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997 -] - -var lplim = (1 << 26) / lowprimes[lowprimes.length - 1] - -// (public) test primality with certainty >= 1-.5^t -function bnIsProbablePrime(t) { - var i, x = this.abs() - if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { - for (i = 0; i < lowprimes.length; ++i) - if (x[0] == lowprimes[i]) return true - return false - } - if (x.isEven()) return false - i = 1 - while (i < lowprimes.length) { - var m = lowprimes[i], - j = i + 1 - while (j < lowprimes.length && m < lplim) m *= lowprimes[j++] - m = x.modInt(m) - while (i < j) if (m % lowprimes[i++] == 0) return false - } - return x.millerRabin(t) -} - -// (protected) true if probably prime (HAC 4.24, Miller-Rabin) -function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE) - var k = n1.getLowestSetBit() - if (k <= 0) return false - var r = n1.shiftRight(k) - t = (t + 1) >> 1 - if (t > lowprimes.length) t = lowprimes.length - var a = new BigInteger(null) - var j, bases = [] - for (var i = 0; i < t; ++i) { - for (;;) { - j = lowprimes[Math.floor(Math.random() * lowprimes.length)] - if (bases.indexOf(j) == -1) break - } - bases.push(j) - a.fromInt(j) - var y = a.modPow(r, this) - if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1 - while (j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2, this) - if (y.compareTo(BigInteger.ONE) == 0) return false - } - if (y.compareTo(n1) != 0) return false - } - } - return true -} - -// protected -proto.chunkSize = bnpChunkSize -proto.toRadix = bnpToRadix -proto.fromRadix = bnpFromRadix -proto.fromNumber = bnpFromNumber -proto.bitwiseTo = bnpBitwiseTo -proto.changeBit = bnpChangeBit -proto.addTo = bnpAddTo -proto.dMultiply = bnpDMultiply -proto.dAddOffset = bnpDAddOffset -proto.multiplyLowerTo = bnpMultiplyLowerTo -proto.multiplyUpperTo = bnpMultiplyUpperTo -proto.modInt = bnpModInt -proto.millerRabin = bnpMillerRabin - -// public -proto.clone = bnClone -proto.intValue = bnIntValue -proto.byteValue = bnByteValue -proto.shortValue = bnShortValue -proto.signum = bnSigNum -proto.toByteArray = bnToByteArray -proto.equals = bnEquals -proto.min = bnMin -proto.max = bnMax -proto.and = bnAnd -proto.or = bnOr -proto.xor = bnXor -proto.andNot = bnAndNot -proto.not = bnNot -proto.shiftLeft = bnShiftLeft -proto.shiftRight = bnShiftRight -proto.getLowestSetBit = bnGetLowestSetBit -proto.bitCount = bnBitCount -proto.testBit = bnTestBit -proto.setBit = bnSetBit -proto.clearBit = bnClearBit -proto.flipBit = bnFlipBit -proto.add = bnAdd -proto.subtract = bnSubtract -proto.multiply = bnMultiply -proto.divide = bnDivide -proto.remainder = bnRemainder -proto.divideAndRemainder = bnDivideAndRemainder -proto.modPow = bnModPow -proto.modInverse = bnModInverse -proto.pow = bnPow -proto.gcd = bnGCD -proto.isProbablePrime = bnIsProbablePrime - -// JSBN-specific extension -proto.square = bnSquare - -// constants -BigInteger.ZERO = nbv(0) -BigInteger.ONE = nbv(1) -BigInteger.valueOf = nbv - -module.exports = BigInteger - -},{"../package.json":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/package.json"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/convert.js":[function(require,module,exports){ -(function (Buffer){ -// FIXME: Kind of a weird way to throw exceptions, consider removing -var assert = require('assert') -var BigInteger = require('./bigi') - -/** - * Turns a byte array into a big integer. - * - * This function will interpret a byte array as a big integer in big - * endian notation. - */ -BigInteger.fromByteArrayUnsigned = function(byteArray) { - // BigInteger expects a DER integer conformant byte array - if (byteArray[0] & 0x80) { - return new BigInteger([0].concat(byteArray)) - } - - return new BigInteger(byteArray) -} - -/** - * Returns a byte array representation of the big integer. - * - * This returns the absolute of the contained value in big endian - * form. A value of zero results in an empty array. - */ -BigInteger.prototype.toByteArrayUnsigned = function() { - var byteArray = this.toByteArray() - return byteArray[0] === 0 ? byteArray.slice(1) : byteArray -} - -BigInteger.fromDERInteger = function(byteArray) { - return new BigInteger(byteArray) -} - -/* - * Converts BigInteger to a DER integer representation. - * - * The format for this value uses the most significant bit as a sign - * bit. If the most significant bit is already set and the integer is - * positive, a 0x00 is prepended. - * - * Examples: - * - * 0 => 0x00 - * 1 => 0x01 - * -1 => 0xff - * 127 => 0x7f - * -127 => 0x81 - * 128 => 0x0080 - * -128 => 0x80 - * 255 => 0x00ff - * -255 => 0xff01 - * 16300 => 0x3fac - * -16300 => 0xc054 - * 62300 => 0x00f35c - * -62300 => 0xff0ca4 -*/ -BigInteger.prototype.toDERInteger = BigInteger.prototype.toByteArray - -BigInteger.fromBuffer = function(buffer) { - // BigInteger expects a DER integer conformant byte array - if (buffer[0] & 0x80) { - var byteArray = Array.prototype.slice.call(buffer) - - return new BigInteger([0].concat(byteArray)) - } - - return new BigInteger(buffer) -} - -BigInteger.fromHex = function(hex) { - if (hex === '') return BigInteger.ZERO - - assert.equal(hex, hex.match(/^[A-Fa-f0-9]+/), 'Invalid hex string') - assert.equal(hex.length % 2, 0, 'Incomplete hex') - return new BigInteger(hex, 16) -} - -BigInteger.prototype.toBuffer = function(size) { - var byteArray = this.toByteArrayUnsigned() - var zeros = [] - - var padding = size - byteArray.length - while (zeros.length < padding) zeros.push(0) - - return new Buffer(zeros.concat(byteArray)) -} - -BigInteger.prototype.toHex = function(size) { - return this.toBuffer(size).toString('hex') -} - -}).call(this,require("buffer").Buffer) - -},{"./bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/bigi.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js":[function(require,module,exports){ -var BigInteger = require('./bigi') - -//addons -require('./convert') - -module.exports = BigInteger -},{"./bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/bigi.js","./convert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/convert.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/package.json":[function(require,module,exports){ -module.exports={ - "_args": [ - [ - "bigi@1.4.2", - "/home/sigve/Dev/Bitshares/bitsharesjs" - ] - ], - "_from": "bigi@1.4.2", - "_id": "bigi@1.4.2", - "_inBundle": false, - "_integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU=", - "_location": "/bigi", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "bigi@1.4.2", - "name": "bigi", - "escapedName": "bigi", - "rawSpec": "1.4.2", - "saveSpec": null, - "fetchSpec": "1.4.2" - }, - "_requiredBy": [ - "/", - "/ecurve" - ], - "_resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", - "_spec": "1.4.2", - "_where": "/home/sigve/Dev/Bitshares/bitsharesjs", - "bugs": { - "url": "https://github.com/cryptocoinjs/bigi/issues" - }, - "dependencies": {}, - "description": "Big integers.", - "devDependencies": { - "coveralls": "^2.11.2", - "istanbul": "^0.3.5", - "jshint": "^2.5.1", - "mocha": "^2.1.0", - "mochify": "^2.1.0" - }, - "homepage": "https://github.com/cryptocoinjs/bigi#readme", - "keywords": [ - "cryptography", - "math", - "bitcoin", - "arbitrary", - "precision", - "arithmetic", - "big", - "integer", - "int", - "number", - "biginteger", - "bigint", - "bignumber", - "decimal", - "float" - ], - "main": "./lib/index.js", - "name": "bigi", - "repository": { - "url": "git+https://github.com/cryptocoinjs/bigi.git", - "type": "git" - }, - "scripts": { - "browser-test": "mochify --wd -R spec", - "coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter list test/*.js", - "coveralls": "npm run-script coverage && node ./node_modules/.bin/coveralls < coverage/lcov.info", - "jshint": "jshint --config jshint.json lib/*.js ; true", - "test": "_mocha -- test/*.js", - "unit": "mocha" - }, - "testling": { - "files": "test/*.js", - "harness": "mocha", - "browsers": [ - "ie/9..latest", - "firefox/latest", - "chrome/latest", - "safari/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - }, - "version": "1.4.2" -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/index.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; -exports.Manager = exports.ChainConfig = exports.Apis = undefined; - -var _ApiInstances = require("./src/ApiInstances"); - -var _ApiInstances2 = _interopRequireDefault(_ApiInstances); - -var _ConnectionManager = require("./src/ConnectionManager"); - -var _ConnectionManager2 = _interopRequireDefault(_ConnectionManager); - -var _ChainConfig = require("./src/ChainConfig"); - -var _ChainConfig2 = _interopRequireDefault(_ChainConfig); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -exports.Apis = _ApiInstances2.default; -exports.ChainConfig = _ChainConfig2.default; -exports.Manager = _ConnectionManager2.default; -},{"./src/ApiInstances":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ApiInstances.js","./src/ChainConfig":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ChainConfig.js","./src/ConnectionManager":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ConnectionManager.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ApiInstances.js":[function(require,module,exports){ -(function (global){ -"use strict"; - -exports.__esModule = true; - -var _ChainWebSocket = require("./ChainWebSocket"); - -var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket); - -var _GrapheneApi = require("./GrapheneApi"); - -var _GrapheneApi2 = _interopRequireDefault(_GrapheneApi); - -var _ChainConfig = require("./ChainConfig"); - -var _ChainConfig2 = _interopRequireDefault(_ChainConfig); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // var { List } = require("immutable"); - - -if (global) { - global.inst = ""; -} else { - var _inst = void 0; -}; -var autoReconnect = false; // by default don't use reconnecting-websocket -/** - Configure: configure as follows `Apis.instance("ws://localhost:8090").init_promise`. This returns a promise, once resolved the connection is ready. - - Import: import { Apis } from "@graphene/chain" - - Short-hand: Apis.db("method", "parm1", 2, 3, ...). Returns a promise with results. - - Additional usage: Apis.instance().db_api().exec("method", ["method", "parm1", 2, 3, ...]). Returns a promise with results. -*/ - -exports.default = { - - setRpcConnectionStatusCallback: function setRpcConnectionStatusCallback(callback) { - this.statusCb = callback; - if (inst) inst.setRpcConnectionStatusCallback(callback); - }, - - /** - @arg {boolean} auto means automatic reconnect if possible( browser case), default true - */ - setAutoReconnect: function setAutoReconnect(auto) { - autoReconnect = auto; - }, - - /** - @arg {string} cs is only provided in the first call - @return {Apis} singleton .. Check Apis.instance().init_promise to know when the connection is established - */ - reset: function reset() { - var cs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ws://localhost:8090"; - var connect = arguments[1]; - var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000; - - var _this = this; - - var optionalApis = arguments[3]; - var closeCb = arguments[4]; - - return this.close().then(function () { - inst = new ApisInstance(); - inst.setRpcConnectionStatusCallback(_this.statusCb); - - if (inst && connect) { - inst.connect(cs, connectTimeout, optionalApis, closeCb); - } - - return inst; - }); - }, - instance: function instance() { - var cs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ws://localhost:8090"; - var connect = arguments[1]; - var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000; - var optionalApis = arguments[3]; - var closeCb = arguments[4]; - - if (!inst) { - inst = new ApisInstance(); - inst.setRpcConnectionStatusCallback(this.statusCb); - } - - if (inst && connect) { - inst.connect(cs, connectTimeout, optionalApis); - } - if (closeCb) inst.closeCb = closeCb; - return inst; - }, - chainId: function chainId() { - return Apis.instance().chain_id; - }, - - close: function close() { - if (inst) { - return new Promise(function (res) { - inst.close().then(function () { - inst = null; - res(); - }); - }); - } - - return Promise.resolve(); - } - // db: (method, ...args) => Apis.instance().db_api().exec(method, toStrings(args)), - // network: (method, ...args) => Apis.instance().network_api().exec(method, toStrings(args)), - // history: (method, ...args) => Apis.instance().history_api().exec(method, toStrings(args)), - // crypto: (method, ...args) => Apis.instance().crypto_api().exec(method, toStrings(args)) - // orders: (method, ...args) => Apis.instance().orders_api().exec(method, toStrings(args)) -}; - -var ApisInstance = function () { - function ApisInstance() { - _classCallCheck(this, ApisInstance); - } - - /** @arg {string} connection .. */ - ApisInstance.prototype.connect = function connect(cs, connectTimeout) { - var _this2 = this; - - var optionalApis = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { enableCrypto: false, enableOrders: false }; - - // console.log("INFO\tApiInstances\tconnect\t", cs); - this.url = cs; - var rpc_user = "", - rpc_password = ""; - if (typeof window !== "undefined" && window.location && window.location.protocol === "https:" && cs.indexOf("wss://") < 0) { - throw new Error("Secure domains require wss connection"); - } - - if (this.ws_rpc) { - this.ws_rpc.statusCb = null; - this.ws_rpc.keepAliveCb = null; - this.ws_rpc.on_close = null; - this.ws_rpc.on_reconnect = null; - } - this.ws_rpc = new _ChainWebSocket2.default(cs, this.statusCb, connectTimeout, autoReconnect, function (closed) { - if (_this2._db && !closed) { - _this2._db.exec('get_objects', [['2.1.0']]).catch(function (e) {}); - } - }); - this.init_promise = this.ws_rpc.login(rpc_user, rpc_password).then(function () { - //console.log("Connected to API node:", cs); - _this2._db = new _GrapheneApi2.default(_this2.ws_rpc, "database"); - _this2._net = new _GrapheneApi2.default(_this2.ws_rpc, "network_broadcast"); - _this2._hist = new _GrapheneApi2.default(_this2.ws_rpc, "history"); - if (optionalApis.enableOrders) _this2._orders = new _GrapheneApi2.default(_this2.ws_rpc, "orders"); - if (optionalApis.enableCrypto) _this2._crypt = new _GrapheneApi2.default(_this2.ws_rpc, "crypto"); - var db_promise = _this2._db.init().then(function () { - //https://github.com/cryptonomex/graphene/wiki/chain-locked-tx - return _this2._db.exec("get_chain_id", []).then(function (_chain_id) { - _this2.chain_id = _chain_id; - return _ChainConfig2.default.setChainId(_chain_id); - //DEBUG console.log("chain_id1",this.chain_id) - }); - }); - _this2.ws_rpc.on_reconnect = function () { - if (!_this2.ws_rpc) return; - _this2.ws_rpc.login("", "").then(function () { - _this2._db.init().then(function () { - if (_this2.statusCb) _this2.statusCb("reconnect"); - }); - _this2._net.init(); - _this2._hist.init(); - if (optionalApis.enableOrders) _this2._orders.init(); - if (optionalApis.enableCrypto) _this2._crypt.init(); - }); - }; - _this2.ws_rpc.on_close = function () { - _this2.close().then(function () { - if (_this2.closeCb) _this2.closeCb(); - }); - }; - var initPromises = [db_promise, _this2._net.init(), _this2._hist.init()]; - - if (optionalApis.enableOrders) initPromises.push(_this2._orders.init()); - if (optionalApis.enableCrypto) initPromises.push(_this2._crypt.init()); - return Promise.all(initPromises); - }).catch(function (err) { - console.error(cs, "Failed to initialize with error", err && err.message); - return _this2.close().then(function () { - throw err; - }); - }); - }; - - ApisInstance.prototype.close = function close() { - var _this3 = this; - - if (this.ws_rpc && this.ws_rpc.ws.readyState === 1) { - return this.ws_rpc.close().then(function () { - _this3.ws_rpc = null; - }); - }; - this.ws_rpc = null; - return Promise.resolve(); - }; - - ApisInstance.prototype.db_api = function db_api() { - return this._db; - }; - - ApisInstance.prototype.network_api = function network_api() { - return this._net; - }; - - ApisInstance.prototype.history_api = function history_api() { - return this._hist; - }; - - ApisInstance.prototype.crypto_api = function crypto_api() { - return this._crypt; - }; - - ApisInstance.prototype.orders_api = function orders_api() { - return this._orders; - }; - - ApisInstance.prototype.setRpcConnectionStatusCallback = function setRpcConnectionStatusCallback(callback) { - this.statusCb = callback; - }; - - return ApisInstance; -}(); - -module.exports = exports["default"]; -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"./ChainConfig":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ChainConfig.js","./ChainWebSocket":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ChainWebSocket.js","./GrapheneApi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/GrapheneApi.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ChainConfig.js":[function(require,module,exports){ -(function (process){ -"use strict"; - -exports.__esModule = true; -var _this = void 0; - -var ecc_config = { - address_prefix: process.env.npm_config__graphene_ecc_default_address_prefix || "GPH" -}; - -_this = { - core_asset: "CORE", - address_prefix: "GPH", - expire_in_secs: 15, - expire_in_secs_proposal: 24 * 60 * 60, - review_in_secs_committee: 24 * 60 * 60, - networks: { - BitShares: { - core_asset: "BTS", - address_prefix: "BTS", - chain_id: "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8" - }, - Muse: { - core_asset: "MUSE", - address_prefix: "MUSE", - chain_id: "45ad2d3f9ef92a49b55c2227eb06123f613bb35dd08bd876f2aea21925a67a67" - }, - Test: { - core_asset: "TEST", - address_prefix: "TEST", - chain_id: "39f5e2ede1f8bc1a3a54a7914414e3779e33193f1f5693510e73cb7a87617447" - }, - Obelisk: { - core_asset: "GOV", - address_prefix: "FEW", - chain_id: "1cfde7c388b9e8ac06462d68aadbd966b58f88797637d9af805b4560b0e9661e" - } - }, - - /** Set a few properties for known chain IDs. */ - setChainId: function setChainId(chain_id) { - - var i = void 0, - len = void 0, - network = void 0, - network_name = void 0, - ref = void 0; - ref = Object.keys(_this.networks); - - for (i = 0, len = ref.length; i < len; i++) { - - network_name = ref[i]; - network = _this.networks[network_name]; - - if (network.chain_id === chain_id) { - - _this.network_name = network_name; - - if (network.address_prefix) { - _this.address_prefix = network.address_prefix; - ecc_config.address_prefix = network.address_prefix; - } - - // console.log("INFO Configured for", network_name, ":", network.core_asset, "\n"); - - return { - network_name: network_name, - network: network - }; - } - } - - if (!_this.network_name) { - console.log("Unknown chain id (this may be a testnet)", chain_id); - } - }, - - reset: function reset() { - _this.core_asset = "CORE"; - _this.address_prefix = "GPH"; - ecc_config.address_prefix = "GPH"; - _this.expire_in_secs = 15; - _this.expire_in_secs_proposal = 24 * 60 * 60; - - console.log("Chain config reset"); - }, - - setPrefix: function setPrefix() { - var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "GPH"; - - _this.address_prefix = prefix; - ecc_config.address_prefix = prefix; - } -}; - -exports.default = _this; -module.exports = exports["default"]; -}).call(this,require('_process')) - -},{"_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ChainWebSocket.js":[function(require,module,exports){ -(function (process){ -"use strict"; - -exports.__esModule = true; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var WebSocketClient = void 0; -if (typeof WebSocket === "undefined" && !process.env.browser) { - WebSocketClient = require("ws"); -} else { - WebSocketClient = WebSocket; -} - -var SOCKET_DEBUG = false; - -function getWebSocketClient(autoReconnect) { - if (!autoReconnect && typeof WebSocket !== "undefined" && typeof document !== "undefined") { - return WebSocket; - } - return WebSocketClient; -} - -var keep_alive_interval = 5000; -var max_send_life = 5; -var max_recv_life = max_send_life * 2; - -var ChainWebSocket = function () { - function ChainWebSocket(ws_server, statusCb) { - var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5000; - - var _this = this; - - var autoReconnect = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; - var keepAliveCb = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; - - _classCallCheck(this, ChainWebSocket); - - this.url = ws_server; - this.statusCb = statusCb; - this.connectionTimeout = setTimeout(function () { - if (_this.current_reject) { - var reject = _this.current_reject; - _this.current_reject = null; - _this.close(); - reject(new Error("Connection attempt timed out after " + connectTimeout / 1000 + "s")); - } - }, connectTimeout); - - this.current_reject = null; - this.on_reconnect = null; - this.closed = false; - this.send_life = max_send_life; - this.recv_life = max_recv_life; - this.keepAliveCb = keepAliveCb; - this.connect_promise = new Promise(function (resolve, reject) { - _this.current_reject = reject; - var WsClient = getWebSocketClient(autoReconnect); - try { - _this.ws = new WsClient(ws_server); - } catch (error) { - _this.ws = { readyState: 3, close: function close() {} }; // DISCONNECTED - reject(new Error("Invalid url", ws_server, " closed")); - // return this.close().then(() => { - // console.log("Invalid url", ws_server, " closed"); - // // throw new Error("Invalid url", ws_server, " closed") - // // return this.current_reject(Error("Invalid websocket url: " + ws_server)); - // }) - } - - _this.ws.onopen = function () { - clearTimeout(_this.connectionTimeout); - if (_this.statusCb) _this.statusCb("open"); - if (_this.on_reconnect) _this.on_reconnect(); - _this.keepalive_timer = setInterval(function () { - - _this.recv_life--; - if (_this.recv_life == 0) { - console.error(_this.url + ' connection is dead, terminating ws'); - _this.close(); - // clearInterval(this.keepalive_timer); - // this.keepalive_timer = undefined; - return; - } - _this.send_life--; - if (_this.send_life == 0) { - // this.ws.ping('', false, true); - if (_this.keepAliveCb) { - _this.keepAliveCb(_this.closed); - } - _this.send_life = max_send_life; - } - }, 5000); - _this.current_reject = null; - resolve(); - }; - _this.ws.onerror = function (error) { - if (_this.keepalive_timer) { - clearInterval(_this.keepalive_timer); - _this.keepalive_timer = undefined; - } - clearTimeout(_this.connectionTimeout); - if (_this.statusCb) _this.statusCb("error"); - - if (_this.current_reject) { - _this.current_reject(error); - } - }; - _this.ws.onmessage = function (message) { - _this.recv_life = max_recv_life; - _this.listener(JSON.parse(message.data)); - }; - _this.ws.onclose = function () { - _this.closed = true; - if (_this.keepalive_timer) { - clearInterval(_this.keepalive_timer); - _this.keepalive_timer = undefined; - } - var err = new Error('connection closed'); - for (var cbId = _this.responseCbId + 1; cbId <= _this.cbId; cbId += 1) { - _this.cbs[cbId].reject(err); - } - if (_this.statusCb) _this.statusCb("closed"); - if (_this._closeCb) _this._closeCb(); - if (_this.on_close) _this.on_close(); - }; - }); - this.cbId = 0; - this.responseCbId = 0; - this.cbs = {}; - this.subs = {}; - this.unsub = {}; - } - - ChainWebSocket.prototype.call = function call(params) { - var _this2 = this; - - if (this.ws.readyState !== 1) { - return Promise.reject(new Error('websocket state error:' + this.ws.readyState)); - } - var method = params[1]; - if (SOCKET_DEBUG) console.log("[ChainWebSocket] >---- call -----> \"id\":" + (this.cbId + 1), JSON.stringify(params)); - - this.cbId += 1; - - if (method === "set_subscribe_callback" || method === "subscribe_to_market" || method === "broadcast_transaction_with_callback" || method === "set_pending_transaction_callback") { - // Store callback in subs map - this.subs[this.cbId] = { - callback: params[2][0] - }; - - // Replace callback with the callback id - params[2][0] = this.cbId; - } - - if (method === "unsubscribe_from_market" || method === "unsubscribe_from_accounts") { - if (typeof params[2][0] !== "function") { - throw new Error("First parameter of unsub must be the original callback"); - } - - var unSubCb = params[2].splice(0, 1)[0]; - - // Find the corresponding subscription - for (var id in this.subs) { - if (this.subs[id].callback === unSubCb) { - this.unsub[this.cbId] = id; - break; - } - } - } - - var request = { - method: "call", - params: params - }; - request.id = this.cbId; - this.send_life = max_send_life; - - return new Promise(function (resolve, reject) { - _this2.cbs[_this2.cbId] = { - time: new Date(), - resolve: resolve, - reject: reject - }; - _this2.ws.send(JSON.stringify(request)); - }); - }; - - ChainWebSocket.prototype.listener = function listener(response) { - if (SOCKET_DEBUG) console.log("[ChainWebSocket] <---- reply ----<", JSON.stringify(response)); - - var sub = false, - callback = null; - - if (response.method === "notice") { - sub = true; - response.id = response.params[0]; - } - - if (!sub) { - callback = this.cbs[response.id]; - this.responseCbId = response.id; - } else { - callback = this.subs[response.id].callback; - } - - if (callback && !sub) { - if (response.error) { - callback.reject(response.error); - } else { - callback.resolve(response.result); - } - delete this.cbs[response.id]; - - if (this.unsub[response.id]) { - delete this.subs[this.unsub[response.id]]; - delete this.unsub[response.id]; - } - } else if (callback && sub) { - callback(response.params[1]); - } else { - console.log("Warning: unknown websocket response: ", response); - } - }; - - ChainWebSocket.prototype.login = function login(user, password) { - var _this3 = this; - - return this.connect_promise.then(function () { - return _this3.call([1, "login", [user, password]]); - }); - }; - - ChainWebSocket.prototype.close = function close() { - var _this4 = this; - - return new Promise(function (res) { - clearInterval(_this4.keepalive_timer); - _this4.keepalive_timer = undefined; - _this4._closeCb = function () { - res(); - _this4._closeCb = null; - }; - if (!_this4.ws) { - console.log("Websocket already cleared", _this4); - return res(); - } - if (_this4.ws.terminate) { - _this4.ws.terminate(); - } else { - _this4.ws.close(); - } - if (_this4.ws.readyState === 3) res(); - }); - }; - - return ChainWebSocket; -}(); - -exports.default = ChainWebSocket; -module.exports = exports["default"]; -}).call(this,require('_process')) - -},{"_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","ws":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browser-resolve/empty.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ConnectionManager.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -var _ApiInstances = require("./ApiInstances"); - -var _ApiInstances2 = _interopRequireDefault(_ApiInstances); - -var _ChainWebSocket = require("./ChainWebSocket"); - -var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Manager = function () { - function Manager(_ref) { - var url = _ref.url, - urls = _ref.urls, - autoFallback = _ref.autoFallback, - closeCb = _ref.closeCb, - optionalApis = _ref.optionalApis, - urlChangeCallback = _ref.urlChangeCallback; - - _classCallCheck(this, Manager); - - this.url = url; - this.urls = urls.filter(function (a) { - return a !== url; - }); - this.autoFallback = autoFallback; - this.closeCb = closeCb; - this.optionalApis = optionalApis || {}; - this.isConnected = false; - this.urlChangeCallback = urlChangeCallback; - } - - Manager.prototype.setCloseCb = function setCloseCb(cb) { - this.closeCb = cb; - }; - - Manager.close = function close() { - return _ApiInstances2.default.close(); - }; - - Manager.prototype.logFailure = function logFailure(method, url, err) { - var message = err && err.message ? err.message : ""; - console.error(method, "Failed to connect to " + url + (message ? " Error: " + JSON.stringify(message) : "")); - }; - - Manager.prototype._onClose = function _onClose() { - this.isConnected = false; - if (this.closeCb) { - this.closeCb(); - this.setCloseCb(null); - } - if (this.autoFallback) { - this.connectWithFallback(); - }; - }; - - Manager.prototype.connect = function connect() { - var _this = this; - - var _connect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.url; - - return new Promise(function (resolve, reject) { - _ApiInstances2.default.instance(url, _connect, undefined, _this.optionalApis, _this._onClose.bind(_this)).init_promise.then(function (res) { - _this.url = url; - _this.isConnected = true; - resolve(res); - }).catch(function (err) { - _ApiInstances2.default.close().then(function () { - reject(err); - }); - }); - }); - }; - - Manager.prototype.connectWithFallback = function connectWithFallback() { - var connect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.url; - var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - - var _this2 = this; - - var resolve = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - var reject = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; - - if (reject && index > this.urls.length) return reject(new Error("Tried " + index + " connections, none of which worked: " + JSON.stringify(this.urls.concat(this.url)))); - var fallback = function fallback(err, resolve, reject) { - if (_this2.urlChangeCallback) _this2.urlChangeCallback(_this2.urls[index]); - return _this2.connectWithFallback(connect, _this2.urls[index], index + 1, resolve, reject); - }; - if (resolve && reject) { - return this.connect(connect, url).then(resolve).catch(function (err) { - fallback(err, resolve, reject); - }); - } else { - return new Promise(function (resolve, reject) { - _this2.connect(connect, undefined).then(resolve).catch(function (err) { - fallback(err, resolve, reject); - }); - }); - } - }; - - Manager.prototype.checkConnections = function checkConnections() { - var rpc_user = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ""; - var rpc_password = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; - - var _this3 = this; - - var resolve = arguments[2]; - var reject = arguments[3]; - - var connectionStartTimes = {}; - var checkFunction = function checkFunction(resolve, reject) { - var fullList = _this3.urls.concat(_this3.url); - var connectionPromises = []; - - fullList.forEach(function (url) { - /* Use default timeout and no reconnecting-websocket */ - var conn = new _ChainWebSocket2.default(url, function () {}, undefined, false); - connectionStartTimes[url] = new Date().getTime(); - connectionPromises.push(function () { - return conn.login(rpc_user, rpc_password).then(function (data) { - var _result; - - var result = (_result = {}, _result[url] = new Date().getTime() - connectionStartTimes[url], _result); - return conn.close().then(function () { - return result; - }); - }).catch(function (err) { - _this3.logFailure("checkConnections", url, err); - if (url === _this3.url) { - _this3.url = _this3.urls[0]; - } else { - _this3.urls = _this3.urls.filter(function (a) { - return a !== url; - }); - } - return conn.close().then(function () { - return null; - }); - }); - }); - }); - - Promise.all(connectionPromises.map(function (a) { - return a(); - })).then(function (res) { - var final = res.filter(function (a) { - return !!a; - }).sort(function (a, b) { - return Object.values(a)[0] - Object.values(b)[0]; - }).reduce(function (f, a) { - var key = Object.keys(a)[0]; - f[key] = a[key]; - return f; - }, {}); - - console.log("Checked " + res.length + " connections, " + (res.length - Object.keys(final).length) + " failed"); - return resolve(final); - }).catch(function () { - return _this3.checkConnections(rpc_user, rpc_password, resolve, reject); - }); - }; - - if (resolve && reject) { - checkFunction(resolve, reject); - } else { - return new Promise(checkFunction); - } - }; - - return Manager; -}(); - -exports.default = Manager; -module.exports = exports["default"]; -},{"./ApiInstances":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ApiInstances.js","./ChainWebSocket":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/ChainWebSocket.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bitsharesjs-ws/cjs/src/GrapheneApi.js":[function(require,module,exports){ -"use strict"; - -exports.__esModule = true; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var GrapheneApi = function () { - function GrapheneApi(ws_rpc, api_name) { - _classCallCheck(this, GrapheneApi); - - this.ws_rpc = ws_rpc; - this.api_name = api_name; - } - - GrapheneApi.prototype.init = function init() { - var self = this; - return this.ws_rpc.call([1, this.api_name, []]).then(function (response) { - //console.log("[GrapheneApi.js:11] ----- GrapheneApi.init ----->", this.api_name, response); - self.api_id = response; - return self; - }); - }; - - GrapheneApi.prototype.exec = function exec(method, params) { - return this.ws_rpc.call([this.api_id, method, params]).catch(function (error) { - // console.log("!!! GrapheneApi error: ", method, params, error, JSON.stringify(error)); - throw error; - }); - }; - - return GrapheneApi; -}(); - -exports.default = GrapheneApi; -module.exports = exports["default"]; -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browser-resolve/empty.js":[function(require,module,exports){ - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browserify/node_modules/safe-buffer/index.js":[function(require,module,exports){ -/* eslint-disable node/no-deprecated-api */ -var buffer = require('buffer') -var Buffer = buffer.Buffer - -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] - } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer -} - -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) -} - -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) - -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) -} - -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - } else { - buf.fill(0) - } - return buf -} - -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) -} - -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return buffer.SlowBuffer(size) -} - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browserify/node_modules/string_decoder/lib/string_decoder.js":[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -/**/ - -var Buffer = require('safe-buffer').Buffer; -/**/ - -var isEncoding = Buffer.isEncoding || function (encoding) { - encoding = '' + encoding; - switch (encoding && encoding.toLowerCase()) { - case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': - return true; - default: - return false; - } -}; - -function _normalizeEncoding(enc) { - if (!enc) return 'utf8'; - var retried; - while (true) { - switch (enc) { - case 'utf8': - case 'utf-8': - return 'utf8'; - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return 'utf16le'; - case 'latin1': - case 'binary': - return 'latin1'; - case 'base64': - case 'ascii': - case 'hex': - return enc; - default: - if (retried) return; // undefined - enc = ('' + enc).toLowerCase(); - retried = true; - } - } -}; - -// Do not cache `Buffer.isEncoding` when checking encoding names as some -// modules monkey-patch it to support additional encodings -function normalizeEncoding(enc) { - var nenc = _normalizeEncoding(enc); - if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); - return nenc || enc; -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. -exports.StringDecoder = StringDecoder; -function StringDecoder(encoding) { - this.encoding = normalizeEncoding(encoding); - var nb; - switch (this.encoding) { - case 'utf16le': - this.text = utf16Text; - this.end = utf16End; - nb = 4; - break; - case 'utf8': - this.fillLast = utf8FillLast; - nb = 4; - break; - case 'base64': - this.text = base64Text; - this.end = base64End; - nb = 3; - break; - default: - this.write = simpleWrite; - this.end = simpleEnd; - return; - } - this.lastNeed = 0; - this.lastTotal = 0; - this.lastChar = Buffer.allocUnsafe(nb); -} - -StringDecoder.prototype.write = function (buf) { - if (buf.length === 0) return ''; - var r; - var i; - if (this.lastNeed) { - r = this.fillLast(buf); - if (r === undefined) return ''; - i = this.lastNeed; - this.lastNeed = 0; - } else { - i = 0; - } - if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); - return r || ''; -}; - -StringDecoder.prototype.end = utf8End; - -// Returns only complete characters in a Buffer -StringDecoder.prototype.text = utf8Text; - -// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer -StringDecoder.prototype.fillLast = function (buf) { - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); - this.lastNeed -= buf.length; -}; - -// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a -// continuation byte. If an invalid byte is detected, -2 is returned. -function utf8CheckByte(byte) { - if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; - return byte >> 6 === 0x02 ? -1 : -2; -} - -// Checks at most 3 bytes at the end of a Buffer in order to detect an -// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) -// needed to complete the UTF-8 character (if applicable) are returned. -function utf8CheckIncomplete(self, buf, i) { - var j = buf.length - 1; - if (j < i) return 0; - var nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 1; - return nb; - } - if (--j < i || nb === -2) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 2; - return nb; - } - if (--j < i || nb === -2) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) { - if (nb === 2) nb = 0;else self.lastNeed = nb - 3; - } - return nb; - } - return 0; -} - -// Validates as many continuation bytes for a multi-byte UTF-8 character as -// needed or are available. If we see a non-continuation byte where we expect -// one, we "replace" the validated continuation bytes we've seen so far with -// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding -// behavior. The continuation byte check is included three times in the case -// where all of the continuation bytes for a character exist in the same buffer. -// It is also done this way as a slight performance increase instead of using a -// loop. -function utf8CheckExtraBytes(self, buf, p) { - if ((buf[0] & 0xC0) !== 0x80) { - self.lastNeed = 0; - return '\ufffd'; - } - if (self.lastNeed > 1 && buf.length > 1) { - if ((buf[1] & 0xC0) !== 0x80) { - self.lastNeed = 1; - return '\ufffd'; - } - if (self.lastNeed > 2 && buf.length > 2) { - if ((buf[2] & 0xC0) !== 0x80) { - self.lastNeed = 2; - return '\ufffd'; - } - } - } -} - -// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. -function utf8FillLast(buf) { - var p = this.lastTotal - this.lastNeed; - var r = utf8CheckExtraBytes(this, buf, p); - if (r !== undefined) return r; - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, p, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, p, 0, buf.length); - this.lastNeed -= buf.length; -} - -// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a -// partial character, the character's bytes are buffered until the required -// number of bytes are available. -function utf8Text(buf, i) { - var total = utf8CheckIncomplete(this, buf, i); - if (!this.lastNeed) return buf.toString('utf8', i); - this.lastTotal = total; - var end = buf.length - (total - this.lastNeed); - buf.copy(this.lastChar, 0, end); - return buf.toString('utf8', i, end); -} - -// For UTF-8, a replacement character is added when ending on a partial -// character. -function utf8End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + '\ufffd'; - return r; -} - -// UTF-16LE typically needs two bytes per character, but even if we have an even -// number of bytes available, we need to check if we end on a leading/high -// surrogate. In that case, we need to wait for the next two bytes in order to -// decode the last character properly. -function utf16Text(buf, i) { - if ((buf.length - i) % 2 === 0) { - var r = buf.toString('utf16le', i); - if (r) { - var c = r.charCodeAt(r.length - 1); - if (c >= 0xD800 && c <= 0xDBFF) { - this.lastNeed = 2; - this.lastTotal = 4; - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - return r.slice(0, -1); - } - } - return r; - } - this.lastNeed = 1; - this.lastTotal = 2; - this.lastChar[0] = buf[buf.length - 1]; - return buf.toString('utf16le', i, buf.length - 1); -} - -// For UTF-16LE we do not explicitly append special replacement characters if we -// end on a partial character, we simply let v8 handle that. -function utf16End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) { - var end = this.lastTotal - this.lastNeed; - return r + this.lastChar.toString('utf16le', 0, end); - } - return r; -} - -function base64Text(buf, i) { - var n = (buf.length - i) % 3; - if (n === 0) return buf.toString('base64', i); - this.lastNeed = 3 - n; - this.lastTotal = 3; - if (n === 1) { - this.lastChar[0] = buf[buf.length - 1]; - } else { - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - } - return buf.toString('base64', i, buf.length - n); -} - -function base64End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); - return r; -} - -// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) -function simpleWrite(buf) { - return buf.toString(this.encoding); -} - -function simpleEnd(buf) { - return buf && buf.length ? this.write(buf) : ''; -} -},{"safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browserify/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bs58/index.js":[function(require,module,exports){ -var basex = require('base-x') -var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' - -module.exports = basex(ALPHABET) - -},{"base-x":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/base-x/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer-shims/index.js":[function(require,module,exports){ -(function (global){ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js":[function(require,module,exports){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ - -'use strict' - -var base64 = require('base64-js') -var ieee754 = require('ieee754') - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 - -var K_MAX_LENGTH = 0x7fffffff -exports.kMaxLength = K_MAX_LENGTH - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Print warning and recommend using `buffer` v4.x which has an Object - * implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * We report that the browser does not support typed arrays if the are not subclassable - * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` - * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support - * for __proto__ and has a buggy typed array implementation. - */ -Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport() - -if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && - typeof console.error === 'function') { - console.error( - 'This browser lacks typed array (Uint8Array) support which is required by ' + - '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.' - ) -} - -function typedArraySupport () { - // Can typed array instances can be augmented? - try { - var arr = new Uint8Array(1) - arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} - return arr.foo() === 42 - } catch (e) { - return false - } -} - -Object.defineProperty(Buffer.prototype, 'parent', { - get: function () { - if (!(this instanceof Buffer)) { - return undefined - } - return this.buffer - } -}) - -Object.defineProperty(Buffer.prototype, 'offset', { - get: function () { - if (!(this instanceof Buffer)) { - return undefined - } - return this.byteOffset - } -}) - -function createBuffer (length) { - if (length > K_MAX_LENGTH) { - throw new RangeError('Invalid typed array length') - } - // Return an augmented `Uint8Array` instance - var buf = new Uint8Array(length) - buf.__proto__ = Buffer.prototype - return buf -} - -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ - -function Buffer (arg, encodingOrOffset, length) { - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new Error( - 'If encoding is specified then the first argument must be a string' - ) - } - return allocUnsafe(arg) - } - return from(arg, encodingOrOffset, length) -} - -// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 -if (typeof Symbol !== 'undefined' && Symbol.species && - Buffer[Symbol.species] === Buffer) { - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true, - enumerable: false, - writable: false - }) -} - -Buffer.poolSize = 8192 // not used by this implementation - -function from (value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (isArrayBuffer(value) || (value && isArrayBuffer(value.buffer))) { - return fromArrayBuffer(value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(value, encodingOrOffset) - } - - return fromObject(value) -} - -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(value, encodingOrOffset, length) -} - -// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: -// https://github.com/feross/buffer/pull/148 -Buffer.prototype.__proto__ = Uint8Array.prototype -Buffer.__proto__ = Uint8Array - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be of type number') - } else if (size < 0) { - throw new RangeError('"size" argument must not be negative') - } -} - -function alloc (size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(size).fill(fill, encoding) - : createBuffer(size).fill(fill) - } - return createBuffer(size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(size, fill, encoding) -} - -function allocUnsafe (size) { - assertSize(size) - return createBuffer(size < 0 ? 0 : checked(size) | 0) -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(size) -} - -function fromString (string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - - var length = byteLength(string, encoding) | 0 - var buf = createBuffer(length) - - var actual = buf.write(string, encoding) - - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - buf = buf.slice(0, actual) - } - - return buf -} - -function fromArrayLike (array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - var buf = createBuffer(length) - for (var i = 0; i < length; i += 1) { - buf[i] = array[i] & 255 - } - return buf -} - -function fromArrayBuffer (array, byteOffset, length) { - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('"offset" is outside of buffer bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('"length" is outside of buffer bounds') - } - - var buf - if (byteOffset === undefined && length === undefined) { - buf = new Uint8Array(array) - } else if (length === undefined) { - buf = new Uint8Array(array, byteOffset) - } else { - buf = new Uint8Array(array, byteOffset, length) - } - - // Return an augmented `Uint8Array` instance - buf.__proto__ = Buffer.prototype - return buf -} - -function fromObject (obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - var buf = createBuffer(len) - - if (buf.length === 0) { - return buf - } - - obj.copy(buf, 0, 0, len) - return buf - } - - if (obj) { - if (ArrayBuffer.isView(obj) || 'length' in obj) { - if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) { - return createBuffer(0) - } - return fromArrayLike(obj) - } - - if (obj.type === 'Buffer' && Array.isArray(obj.data)) { - return fromArrayLike(obj.data) - } - } - - throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object.') -} - -function checked (length) { - // Note: cannot use `length < K_MAX_LENGTH` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= K_MAX_LENGTH) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') - } - return length | 0 -} - -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} - -Buffer.isBuffer = function isBuffer (b) { - return b != null && b._isBuffer === true -} - -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') - } - - if (a === b) return 0 - - var x = a.length - var y = b.length - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} - -Buffer.concat = function concat (list, length) { - if (!Array.isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (ArrayBuffer.isView(buf)) { - buf = Buffer.from(buf) - } - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (ArrayBuffer.isView(string) || isArrayBuffer(string)) { - return string.byteLength - } - if (typeof string !== 'string') { - string = '' + string - } - - var len = string.length - if (len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - case undefined: - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 - - if (end <= start) { - return '' - } - - if (!encoding) encoding = 'utf8' - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } -} - -// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package) -// to detect a Buffer instance. It's not possible to use `instanceof Buffer` -// reliably in a browserify context because there could be multiple different -// copies of the 'buffer' package in use. This method works even for Buffer -// instances that were created from another copy of the `buffer` package. -// See: https://github.com/feross/buffer/issues/154 -Buffer.prototype._isBuffer = true - -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} - -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} - -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} - -Buffer.prototype.swap64 = function swap64 () { - var len = this.length - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7) - swap(this, i + 1, i + 6) - swap(this, i + 2, i + 5) - swap(this, i + 3, i + 4) - } - return this -} - -Buffer.prototype.toString = function toString () { - var length = this.length - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} - -Buffer.prototype.toLocaleString = Buffer.prototype.toString - -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' - } - return '' -} - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (!Buffer.isBuffer(target)) { - throw new TypeError('Argument must be a Buffer') - } - - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) - - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 - - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (numberIsNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1) - } - - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset - if (byteOffset >= buffer.length) { - if (dir) return -1 - else byteOffset = buffer.length - 1 - } else if (byteOffset < 0) { - if (dir) byteOffset = 0 - else return -1 - } - - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding) - } - - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF // Search for a byte value [0-255] - if (typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) - } - - throw new TypeError('val must be string, number or Buffer') -} - -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } - - return -1 -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - var strLen = string.length - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (numberIsNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} - -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} - -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} - -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} - -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} - -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset >>> 0 - if (isFinite(length)) { - length = length >>> 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } - - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } - - if (!encoding) encoding = 'utf8' - - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) - - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - - case 'ascii': - return asciiWrite(this, string, offset, length) - - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) - - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} - -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 - - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint - - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } - - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } - - res.push(codePoint) - i += bytesPerSequence - } - - return decodeCodePointsArray(res) -} - -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 - -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } - - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} - -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) - } - return ret -} - -function latin1Slice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length - - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len - - var out = '' - for (var i = start; i < end; ++i) { - out += toHex(buf[i]) - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256)) - } - return res -} - -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end - - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } - - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len - } - - if (end < start) end = start - - var newBuf = this.subarray(start, end) - // Return an augmented `Uint8Array` instance - newBuf.__proto__ = Buffer.prototype - return newBuf -} - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - - return val -} - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } - - return val -} - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} - -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} - -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - return offset + 2 -} - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - return offset + 2 -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - return offset + 4 -} - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - return offset + 4 -} - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - var limit = Math.pow(2, (8 * byteLength) - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - var limit = Math.pow(2, (8 * byteLength) - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - return offset + 2 -} - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - return offset + 2 -} - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - return offset + 4 -} - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - return offset + 4 -} - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer') - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start - - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('Index out of range') - if (end < 0) throw new RangeError('sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } - - var len = end - start - - if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') { - // Use built-in when available, missing from IE11 - this.copyWithin(targetStart, start, end) - } else if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (var i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, end), - targetStart - ) - } - - return len -} - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if ((encoding === 'utf8' && code < 128) || - encoding === 'latin1') { - // Fast path: If `val` fits into a single byte, use that numeric value. - val = code - } - } - } else if (typeof val === 'number') { - val = val & 255 - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : new Buffer(val, encoding) - var len = bytes.length - if (len === 0) { - throw new TypeError('The value "' + val + - '" is invalid for argument "value"') - } - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } - - return this -} - -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g - -function base64clean (str) { - // Node takes equal signs as end of the Base64 encoding - str = str.split('=')[0] - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = str.trim().replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } - - // valid lead - leadSurrogate = codePoint - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } - - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break - - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} - -// ArrayBuffers from another context (i.e. an iframe) do not pass the `instanceof` check -// but they should be treated as valid. See: https://github.com/feross/buffer/issues/166 -function isArrayBuffer (obj) { - return obj instanceof ArrayBuffer || - (obj != null && obj.constructor != null && obj.constructor.name === 'ArrayBuffer' && - typeof obj.byteLength === 'number') -} - -function numberIsNaN (obj) { - return obj !== obj // eslint-disable-line no-self-compare -} - -},{"base64-js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/base64-js/index.js","ieee754":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ieee754/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bytebuffer/dist/bytebuffer.js":[function(require,module,exports){ -/* - Copyright 2013-2014 Daniel Wirtz - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/** - * @license bytebuffer.js (c) 2015 Daniel Wirtz - * Backing buffer: ArrayBuffer, Accessor: Uint8Array - * Released under the Apache License, Version 2.0 - * see: https://github.com/dcodeIO/bytebuffer.js for details - */ -(function(global, factory) { - - /* AMD */ if (typeof define === 'function' && define["amd"]) - define(["long"], factory); - /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) - module['exports'] = (function() { - var Long; try { Long = require("long"); } catch (e) {} - return factory(Long); - })(); - /* Global */ else - (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]); - -})(this, function(Long) { - "use strict"; - - /** - * Constructs a new ByteBuffer. - * @class The swiss army knife for binary data in JavaScript. - * @exports ByteBuffer - * @constructor - * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @expose - */ - var ByteBuffer = function(capacity, littleEndian, noAssert) { - if (typeof capacity === 'undefined') - capacity = ByteBuffer.DEFAULT_CAPACITY; - if (typeof littleEndian === 'undefined') - littleEndian = ByteBuffer.DEFAULT_ENDIAN; - if (typeof noAssert === 'undefined') - noAssert = ByteBuffer.DEFAULT_NOASSERT; - if (!noAssert) { - capacity = capacity | 0; - if (capacity < 0) - throw RangeError("Illegal capacity"); - littleEndian = !!littleEndian; - noAssert = !!noAssert; - } - - /** - * Backing ArrayBuffer. - * @type {!ArrayBuffer} - * @expose - */ - this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity); - - /** - * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`. - * @type {?Uint8Array} - * @expose - */ - this.view = capacity === 0 ? null : new Uint8Array(this.buffer); - - /** - * Absolute read/write offset. - * @type {number} - * @expose - * @see ByteBuffer#flip - * @see ByteBuffer#clear - */ - this.offset = 0; - - /** - * Marked offset. - * @type {number} - * @expose - * @see ByteBuffer#mark - * @see ByteBuffer#reset - */ - this.markedOffset = -1; - - /** - * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation. - * @type {number} - * @expose - * @see ByteBuffer#flip - * @see ByteBuffer#clear - */ - this.limit = capacity; - - /** - * Whether to use little endian byte order, defaults to `false` for big endian. - * @type {boolean} - * @expose - */ - this.littleEndian = littleEndian; - - /** - * Whether to skip assertions of offsets and values, defaults to `false`. - * @type {boolean} - * @expose - */ - this.noAssert = noAssert; - }; - - /** - * ByteBuffer version. - * @type {string} - * @const - * @expose - */ - ByteBuffer.VERSION = "5.0.1"; - - /** - * Little endian constant that can be used instead of its boolean value. Evaluates to `true`. - * @type {boolean} - * @const - * @expose - */ - ByteBuffer.LITTLE_ENDIAN = true; - - /** - * Big endian constant that can be used instead of its boolean value. Evaluates to `false`. - * @type {boolean} - * @const - * @expose - */ - ByteBuffer.BIG_ENDIAN = false; - - /** - * Default initial capacity of `16`. - * @type {number} - * @expose - */ - ByteBuffer.DEFAULT_CAPACITY = 16; - - /** - * Default endianess of `false` for big endian. - * @type {boolean} - * @expose - */ - ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN; - - /** - * Default no assertions flag of `false`. - * @type {boolean} - * @expose - */ - ByteBuffer.DEFAULT_NOASSERT = false; - - /** - * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded - * and int64 support is not available. - * @type {?Long} - * @const - * @see https://github.com/dcodeIO/long.js - * @expose - */ - ByteBuffer.Long = Long || null; - - /** - * @alias ByteBuffer.prototype - * @inner - */ - var ByteBufferPrototype = ByteBuffer.prototype; - - /** - * An indicator used to reliably determine if an object is a ByteBuffer or not. - * @type {boolean} - * @const - * @expose - * @private - */ - ByteBufferPrototype.__isByteBuffer__; - - Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", { - value: true, - enumerable: false, - configurable: false - }); - - // helpers - - /** - * @type {!ArrayBuffer} - * @inner - */ - var EMPTY_BUFFER = new ArrayBuffer(0); - - /** - * String.fromCharCode reference for compile-time renaming. - * @type {function(...number):string} - * @inner - */ - var stringFromCharCode = String.fromCharCode; - - /** - * Creates a source function for a string. - * @param {string} s String to read from - * @returns {function():number|null} Source function returning the next char code respectively `null` if there are - * no more characters left. - * @throws {TypeError} If the argument is invalid - * @inner - */ - function stringSource(s) { - var i=0; return function() { - return i < s.length ? s.charCodeAt(i++) : null; - }; - } - - /** - * Creates a destination function for a string. - * @returns {function(number=):undefined|string} Destination function successively called with the next char code. - * Returns the final string when called without arguments. - * @inner - */ - function stringDestination() { - var cs = [], ps = []; return function() { - if (arguments.length === 0) - return ps.join('')+stringFromCharCode.apply(String, cs); - if (cs.length + arguments.length > 1024) - ps.push(stringFromCharCode.apply(String, cs)), - cs.length = 0; - Array.prototype.push.apply(cs, arguments); - }; - } - - /** - * Gets the accessor type. - * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes) - * @expose - */ - ByteBuffer.accessor = function() { - return Uint8Array; - }; - /** - * Allocates a new ByteBuffer backed by a buffer of the specified capacity. - * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @returns {!ByteBuffer} - * @expose - */ - ByteBuffer.allocate = function(capacity, littleEndian, noAssert) { - return new ByteBuffer(capacity, littleEndian, noAssert); - }; - - /** - * Concatenates multiple ByteBuffers into one. - * @param {!Array.} buffers Buffers to concatenate - * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary", - * defaults to "utf8") - * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults - * to {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @returns {!ByteBuffer} Concatenated ByteBuffer - * @expose - */ - ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) { - if (typeof encoding === 'boolean' || typeof encoding !== 'string') { - noAssert = littleEndian; - littleEndian = encoding; - encoding = undefined; - } - var capacity = 0; - for (var i=0, k=buffers.length, length; i 0) capacity += length; - } - if (capacity === 0) - return new ByteBuffer(0, littleEndian, noAssert); - var bb = new ByteBuffer(capacity, littleEndian, noAssert), - bi; - i=0; while (i} buffer Anything that can be wrapped - * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to - * "utf8") - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer` - * @expose - */ - ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) { - if (typeof encoding !== 'string') { - noAssert = littleEndian; - littleEndian = encoding; - encoding = undefined; - } - if (typeof buffer === 'string') { - if (typeof encoding === 'undefined') - encoding = "utf8"; - switch (encoding) { - case "base64": - return ByteBuffer.fromBase64(buffer, littleEndian); - case "hex": - return ByteBuffer.fromHex(buffer, littleEndian); - case "binary": - return ByteBuffer.fromBinary(buffer, littleEndian); - case "utf8": - return ByteBuffer.fromUTF8(buffer, littleEndian); - case "debug": - return ByteBuffer.fromDebug(buffer, littleEndian); - default: - throw Error("Unsupported encoding: "+encoding); - } - } - if (buffer === null || typeof buffer !== 'object') - throw TypeError("Illegal buffer"); - var bb; - if (ByteBuffer.isByteBuffer(buffer)) { - bb = ByteBufferPrototype.clone.call(buffer); - bb.markedOffset = -1; - return bb; - } - if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array - bb = new ByteBuffer(0, littleEndian, noAssert); - if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER - bb.buffer = buffer.buffer; - bb.offset = buffer.byteOffset; - bb.limit = buffer.byteOffset + buffer.byteLength; - bb.view = new Uint8Array(buffer.buffer); - } - } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer - bb = new ByteBuffer(0, littleEndian, noAssert); - if (buffer.byteLength > 0) { - bb.buffer = buffer; - bb.offset = 0; - bb.limit = buffer.byteLength; - bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null; - } - } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets - bb = new ByteBuffer(buffer.length, littleEndian, noAssert); - bb.limit = buffer.length; - for (var i=0; i} value Array of booleans to write - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. - * @returns {!ByteBuffer} - * @expose - */ - ByteBufferPrototype.writeBitSet = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (!(value instanceof Array)) - throw TypeError("Illegal BitSet: Not an array"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - - var start = offset, - bits = value.length, - bytes = (bits >> 3), - bit = 0, - k; - - offset += this.writeVarint32(bits,offset); - - while(bytes--) { - k = (!!value[bit++] & 1) | - ((!!value[bit++] & 1) << 1) | - ((!!value[bit++] & 1) << 2) | - ((!!value[bit++] & 1) << 3) | - ((!!value[bit++] & 1) << 4) | - ((!!value[bit++] & 1) << 5) | - ((!!value[bit++] & 1) << 6) | - ((!!value[bit++] & 1) << 7); - this.writeByte(k,offset++); - } - - if(bit < bits) { - var m = 0; k = 0; - while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++)); - this.writeByte(k,offset++); - } - - if (relative) { - this.offset = offset; - return this; - } - return offset - start; - } - - /** - * Reads a BitSet as an array of booleans. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. - * @returns {Array - * @expose - */ - ByteBufferPrototype.readBitSet = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - - var ret = this.readVarint32(offset), - bits = ret.value, - bytes = (bits >> 3), - bit = 0, - value = [], - k; - - offset += ret.length; - - while(bytes--) { - k = this.readByte(offset++); - value[bit++] = !!(k & 0x01); - value[bit++] = !!(k & 0x02); - value[bit++] = !!(k & 0x04); - value[bit++] = !!(k & 0x08); - value[bit++] = !!(k & 0x10); - value[bit++] = !!(k & 0x20); - value[bit++] = !!(k & 0x40); - value[bit++] = !!(k & 0x80); - } - - if(bit < bits) { - var m = 0; - k = this.readByte(offset++); - while(bit < bits) value[bit++] = !!((k >> (m++)) & 1); - } - - if (relative) { - this.offset = offset; - } - return value; - } - /** - * Reads the specified number of bytes. - * @param {number} length Number of bytes to read - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. - * @returns {!ByteBuffer} - * @expose - */ - ByteBufferPrototype.readBytes = function(length, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + length > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); - } - var slice = this.slice(offset, offset + length); - if (relative) this.offset += length; - return slice; - }; - - /** - * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}. - * @function - * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets - * will be modified according to the performed read operation. - * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeBytes = ByteBufferPrototype.append; - - // types/ints/int8 - - /** - * Writes an 8bit signed integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeInt8 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value |= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 1; - var capacity0 = this.buffer.byteLength; - if (offset > capacity0) - this.resize((capacity0 *= 2) > offset ? capacity0 : offset); - offset -= 1; - this.view[offset] = value; - if (relative) this.offset += 1; - return this; - }; - - /** - * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8; - - /** - * Reads an 8bit signed integer. - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readInt8 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 1 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); - } - var value = this.view[offset]; - if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed - if (relative) this.offset += 1; - return value; - }; - - /** - * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}. - * @function - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8; - - /** - * Writes an 8bit unsigned integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeUint8 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value >>>= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 1; - var capacity1 = this.buffer.byteLength; - if (offset > capacity1) - this.resize((capacity1 *= 2) > offset ? capacity1 : offset); - offset -= 1; - this.view[offset] = value; - if (relative) this.offset += 1; - return this; - }; - - /** - * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8; - - /** - * Reads an 8bit unsigned integer. - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readUint8 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 1 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); - } - var value = this.view[offset]; - if (relative) this.offset += 1; - return value; - }; - - /** - * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}. - * @function - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8; - - // types/ints/int16 - - /** - * Writes a 16bit signed integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @throws {TypeError} If `offset` or `value` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.writeInt16 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value |= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 2; - var capacity2 = this.buffer.byteLength; - if (offset > capacity2) - this.resize((capacity2 *= 2) > offset ? capacity2 : offset); - offset -= 2; - if (this.littleEndian) { - this.view[offset+1] = (value & 0xFF00) >>> 8; - this.view[offset ] = value & 0x00FF; - } else { - this.view[offset] = (value & 0xFF00) >>> 8; - this.view[offset+1] = value & 0x00FF; - } - if (relative) this.offset += 2; - return this; - }; - - /** - * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @throws {TypeError} If `offset` or `value` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16; - - /** - * Reads a 16bit signed integer. - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @returns {number} Value read - * @throws {TypeError} If `offset` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.readInt16 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 2 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); - } - var value = 0; - if (this.littleEndian) { - value = this.view[offset ]; - value |= this.view[offset+1] << 8; - } else { - value = this.view[offset ] << 8; - value |= this.view[offset+1]; - } - if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed - if (relative) this.offset += 2; - return value; - }; - - /** - * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}. - * @function - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @returns {number} Value read - * @throws {TypeError} If `offset` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16; - - /** - * Writes a 16bit unsigned integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @throws {TypeError} If `offset` or `value` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.writeUint16 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value >>>= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 2; - var capacity3 = this.buffer.byteLength; - if (offset > capacity3) - this.resize((capacity3 *= 2) > offset ? capacity3 : offset); - offset -= 2; - if (this.littleEndian) { - this.view[offset+1] = (value & 0xFF00) >>> 8; - this.view[offset ] = value & 0x00FF; - } else { - this.view[offset] = (value & 0xFF00) >>> 8; - this.view[offset+1] = value & 0x00FF; - } - if (relative) this.offset += 2; - return this; - }; - - /** - * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @throws {TypeError} If `offset` or `value` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16; - - /** - * Reads a 16bit unsigned integer. - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @returns {number} Value read - * @throws {TypeError} If `offset` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.readUint16 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 2 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); - } - var value = 0; - if (this.littleEndian) { - value = this.view[offset ]; - value |= this.view[offset+1] << 8; - } else { - value = this.view[offset ] << 8; - value |= this.view[offset+1]; - } - if (relative) this.offset += 2; - return value; - }; - - /** - * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}. - * @function - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. - * @returns {number} Value read - * @throws {TypeError} If `offset` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @expose - */ - ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16; - - // types/ints/int32 - - /** - * Writes a 32bit signed integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @expose - */ - ByteBufferPrototype.writeInt32 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value |= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 4; - var capacity4 = this.buffer.byteLength; - if (offset > capacity4) - this.resize((capacity4 *= 2) > offset ? capacity4 : offset); - offset -= 4; - if (this.littleEndian) { - this.view[offset+3] = (value >>> 24) & 0xFF; - this.view[offset+2] = (value >>> 16) & 0xFF; - this.view[offset+1] = (value >>> 8) & 0xFF; - this.view[offset ] = value & 0xFF; - } else { - this.view[offset ] = (value >>> 24) & 0xFF; - this.view[offset+1] = (value >>> 16) & 0xFF; - this.view[offset+2] = (value >>> 8) & 0xFF; - this.view[offset+3] = value & 0xFF; - } - if (relative) this.offset += 4; - return this; - }; - - /** - * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @expose - */ - ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32; - - /** - * Reads a 32bit signed integer. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readInt32 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 4 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); - } - var value = 0; - if (this.littleEndian) { - value = this.view[offset+2] << 16; - value |= this.view[offset+1] << 8; - value |= this.view[offset ]; - value += this.view[offset+3] << 24 >>> 0; - } else { - value = this.view[offset+1] << 16; - value |= this.view[offset+2] << 8; - value |= this.view[offset+3]; - value += this.view[offset ] << 24 >>> 0; - } - value |= 0; // Cast to signed - if (relative) this.offset += 4; - return value; - }; - - /** - * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}. - * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32; - - /** - * Writes a 32bit unsigned integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @expose - */ - ByteBufferPrototype.writeUint32 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value >>>= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 4; - var capacity5 = this.buffer.byteLength; - if (offset > capacity5) - this.resize((capacity5 *= 2) > offset ? capacity5 : offset); - offset -= 4; - if (this.littleEndian) { - this.view[offset+3] = (value >>> 24) & 0xFF; - this.view[offset+2] = (value >>> 16) & 0xFF; - this.view[offset+1] = (value >>> 8) & 0xFF; - this.view[offset ] = value & 0xFF; - } else { - this.view[offset ] = (value >>> 24) & 0xFF; - this.view[offset+1] = (value >>> 16) & 0xFF; - this.view[offset+2] = (value >>> 8) & 0xFF; - this.view[offset+3] = value & 0xFF; - } - if (relative) this.offset += 4; - return this; - }; - - /** - * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @expose - */ - ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32; - - /** - * Reads a 32bit unsigned integer. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readUint32 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 4 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); - } - var value = 0; - if (this.littleEndian) { - value = this.view[offset+2] << 16; - value |= this.view[offset+1] << 8; - value |= this.view[offset ]; - value += this.view[offset+3] << 24 >>> 0; - } else { - value = this.view[offset+1] << 16; - value |= this.view[offset+2] << 8; - value |= this.view[offset+3]; - value += this.view[offset ] << 24 >>> 0; - } - if (relative) this.offset += 4; - return value; - }; - - /** - * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}. - * @function - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {number} Value read - * @expose - */ - ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32; - - // types/ints/int64 - - if (Long) { - - /** - * Writes a 64bit signed integer. - * @param {number|!Long} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeInt64 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value === 'number') - value = Long.fromNumber(value); - else if (typeof value === 'string') - value = Long.fromString(value); - else if (!(value && value instanceof Long)) - throw TypeError("Illegal value: "+value+" (not an integer or Long)"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - if (typeof value === 'number') - value = Long.fromNumber(value); - else if (typeof value === 'string') - value = Long.fromString(value); - offset += 8; - var capacity6 = this.buffer.byteLength; - if (offset > capacity6) - this.resize((capacity6 *= 2) > offset ? capacity6 : offset); - offset -= 8; - var lo = value.low, - hi = value.high; - if (this.littleEndian) { - this.view[offset+3] = (lo >>> 24) & 0xFF; - this.view[offset+2] = (lo >>> 16) & 0xFF; - this.view[offset+1] = (lo >>> 8) & 0xFF; - this.view[offset ] = lo & 0xFF; - offset += 4; - this.view[offset+3] = (hi >>> 24) & 0xFF; - this.view[offset+2] = (hi >>> 16) & 0xFF; - this.view[offset+1] = (hi >>> 8) & 0xFF; - this.view[offset ] = hi & 0xFF; - } else { - this.view[offset ] = (hi >>> 24) & 0xFF; - this.view[offset+1] = (hi >>> 16) & 0xFF; - this.view[offset+2] = (hi >>> 8) & 0xFF; - this.view[offset+3] = hi & 0xFF; - offset += 4; - this.view[offset ] = (lo >>> 24) & 0xFF; - this.view[offset+1] = (lo >>> 16) & 0xFF; - this.view[offset+2] = (lo >>> 8) & 0xFF; - this.view[offset+3] = lo & 0xFF; - } - if (relative) this.offset += 8; - return this; - }; - - /** - * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}. - * @param {number|!Long} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64; - - /** - * Reads a 64bit signed integer. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!Long} - * @expose - */ - ByteBufferPrototype.readInt64 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 8 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); - } - var lo = 0, - hi = 0; - if (this.littleEndian) { - lo = this.view[offset+2] << 16; - lo |= this.view[offset+1] << 8; - lo |= this.view[offset ]; - lo += this.view[offset+3] << 24 >>> 0; - offset += 4; - hi = this.view[offset+2] << 16; - hi |= this.view[offset+1] << 8; - hi |= this.view[offset ]; - hi += this.view[offset+3] << 24 >>> 0; - } else { - hi = this.view[offset+1] << 16; - hi |= this.view[offset+2] << 8; - hi |= this.view[offset+3]; - hi += this.view[offset ] << 24 >>> 0; - offset += 4; - lo = this.view[offset+1] << 16; - lo |= this.view[offset+2] << 8; - lo |= this.view[offset+3]; - lo += this.view[offset ] << 24 >>> 0; - } - var value = new Long(lo, hi, false); - if (relative) this.offset += 8; - return value; - }; - - /** - * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!Long} - * @expose - */ - ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64; - - /** - * Writes a 64bit unsigned integer. - * @param {number|!Long} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeUint64 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value === 'number') - value = Long.fromNumber(value); - else if (typeof value === 'string') - value = Long.fromString(value); - else if (!(value && value instanceof Long)) - throw TypeError("Illegal value: "+value+" (not an integer or Long)"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - if (typeof value === 'number') - value = Long.fromNumber(value); - else if (typeof value === 'string') - value = Long.fromString(value); - offset += 8; - var capacity7 = this.buffer.byteLength; - if (offset > capacity7) - this.resize((capacity7 *= 2) > offset ? capacity7 : offset); - offset -= 8; - var lo = value.low, - hi = value.high; - if (this.littleEndian) { - this.view[offset+3] = (lo >>> 24) & 0xFF; - this.view[offset+2] = (lo >>> 16) & 0xFF; - this.view[offset+1] = (lo >>> 8) & 0xFF; - this.view[offset ] = lo & 0xFF; - offset += 4; - this.view[offset+3] = (hi >>> 24) & 0xFF; - this.view[offset+2] = (hi >>> 16) & 0xFF; - this.view[offset+1] = (hi >>> 8) & 0xFF; - this.view[offset ] = hi & 0xFF; - } else { - this.view[offset ] = (hi >>> 24) & 0xFF; - this.view[offset+1] = (hi >>> 16) & 0xFF; - this.view[offset+2] = (hi >>> 8) & 0xFF; - this.view[offset+3] = hi & 0xFF; - offset += 4; - this.view[offset ] = (lo >>> 24) & 0xFF; - this.view[offset+1] = (lo >>> 16) & 0xFF; - this.view[offset+2] = (lo >>> 8) & 0xFF; - this.view[offset+3] = lo & 0xFF; - } - if (relative) this.offset += 8; - return this; - }; - - /** - * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}. - * @function - * @param {number|!Long} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64; - - /** - * Reads a 64bit unsigned integer. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!Long} - * @expose - */ - ByteBufferPrototype.readUint64 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 8 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); - } - var lo = 0, - hi = 0; - if (this.littleEndian) { - lo = this.view[offset+2] << 16; - lo |= this.view[offset+1] << 8; - lo |= this.view[offset ]; - lo += this.view[offset+3] << 24 >>> 0; - offset += 4; - hi = this.view[offset+2] << 16; - hi |= this.view[offset+1] << 8; - hi |= this.view[offset ]; - hi += this.view[offset+3] << 24 >>> 0; - } else { - hi = this.view[offset+1] << 16; - hi |= this.view[offset+2] << 8; - hi |= this.view[offset+3]; - hi += this.view[offset ] << 24 >>> 0; - offset += 4; - lo = this.view[offset+1] << 16; - lo |= this.view[offset+2] << 8; - lo |= this.view[offset+3]; - lo += this.view[offset ] << 24 >>> 0; - } - var value = new Long(lo, hi, true); - if (relative) this.offset += 8; - return value; - }; - - /** - * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}. - * @function - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!Long} - * @expose - */ - ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64; - - } // Long - - - // types/floats/float32 - - /* - ieee754 - https://github.com/feross/ieee754 - - The MIT License (MIT) - - Copyright (c) Feross Aboukhadijeh - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - - /** - * Reads an IEEE754 float from a byte array. - * @param {!Array} buffer - * @param {number} offset - * @param {boolean} isLE - * @param {number} mLen - * @param {number} nBytes - * @returns {number} - * @inner - */ - function ieee754_read(buffer, offset, isLE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isLE ? (nBytes - 1) : 0, - d = isLE ? -1 : 1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); - } - - /** - * Writes an IEEE754 float to a byte array. - * @param {!Array} buffer - * @param {number} value - * @param {number} offset - * @param {boolean} isLE - * @param {number} mLen - * @param {number} nBytes - * @inner - */ - function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isLE ? 0 : (nBytes - 1), - d = isLE ? 1 : -1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128; - } - - /** - * Writes a 32bit float. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeFloat32 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number') - throw TypeError("Illegal value: "+value+" (not a number)"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 4; - var capacity8 = this.buffer.byteLength; - if (offset > capacity8) - this.resize((capacity8 *= 2) > offset ? capacity8 : offset); - offset -= 4; - ieee754_write(this.view, value, offset, this.littleEndian, 23, 4); - if (relative) this.offset += 4; - return this; - }; - - /** - * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32; - - /** - * Reads a 32bit float. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {number} - * @expose - */ - ByteBufferPrototype.readFloat32 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 4 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); - } - var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4); - if (relative) this.offset += 4; - return value; - }; - - /** - * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}. - * @function - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. - * @returns {number} - * @expose - */ - ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32; - - // types/floats/float64 - - /** - * Writes a 64bit float. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeFloat64 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number') - throw TypeError("Illegal value: "+value+" (not a number)"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - offset += 8; - var capacity9 = this.buffer.byteLength; - if (offset > capacity9) - this.resize((capacity9 *= 2) > offset ? capacity9 : offset); - offset -= 8; - ieee754_write(this.view, value, offset, this.littleEndian, 52, 8); - if (relative) this.offset += 8; - return this; - }; - - /** - * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}. - * @function - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64; - - /** - * Reads a 64bit float. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {number} - * @expose - */ - ByteBufferPrototype.readFloat64 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 8 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); - } - var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8); - if (relative) this.offset += 8; - return value; - }; - - /** - * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}. - * @function - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. - * @returns {number} - * @expose - */ - ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64; - - - // types/varints/varint32 - - /** - * Maximum number of bytes required to store a 32bit base 128 variable-length integer. - * @type {number} - * @const - * @expose - */ - ByteBuffer.MAX_VARINT32_BYTES = 5; - - /** - * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer. - * @param {number} value Value to encode - * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES} - * @expose - */ - ByteBuffer.calculateVarint32 = function(value) { - // ref: src/google/protobuf/io/coded_stream.cc - value = value >>> 0; - if (value < 1 << 7 ) return 1; - else if (value < 1 << 14) return 2; - else if (value < 1 << 21) return 3; - else if (value < 1 << 28) return 4; - else return 5; - }; - - /** - * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding. - * @param {number} n Signed 32bit integer - * @returns {number} Unsigned zigzag encoded 32bit integer - * @expose - */ - ByteBuffer.zigZagEncode32 = function(n) { - return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h - }; - - /** - * Decodes a zigzag encoded signed 32bit integer. - * @param {number} n Unsigned zigzag encoded 32bit integer - * @returns {number} Signed 32bit integer - * @expose - */ - ByteBuffer.zigZagDecode32 = function(n) { - return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h - }; - - /** - * Writes a 32bit base 128 variable-length integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written - * @expose - */ - ByteBufferPrototype.writeVarint32 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value |= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - var size = ByteBuffer.calculateVarint32(value), - b; - offset += size; - var capacity10 = this.buffer.byteLength; - if (offset > capacity10) - this.resize((capacity10 *= 2) > offset ? capacity10 : offset); - offset -= size; - value >>>= 0; - while (value >= 0x80) { - b = (value & 0x7f) | 0x80; - this.view[offset++] = b; - value >>>= 7; - } - this.view[offset++] = value; - if (relative) { - this.offset = offset; - return this; - } - return size; - }; - - /** - * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer. - * @param {number} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written - * @expose - */ - ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) { - return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset); - }; - - /** - * Reads a 32bit base 128 variable-length integer. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read - * and the actual number of bytes read. - * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available - * to fully decode the varint. - * @expose - */ - ByteBufferPrototype.readVarint32 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 1 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); - } - var c = 0, - value = 0 >>> 0, - b; - do { - if (!this.noAssert && offset > this.limit) { - var err = Error("Truncated"); - err['truncated'] = true; - throw err; - } - b = this.view[offset++]; - if (c < 5) - value |= (b & 0x7f) << (7*c); - ++c; - } while ((b & 0x80) !== 0); - value |= 0; - if (relative) { - this.offset = offset; - return value; - } - return { - "value": value, - "length": c - }; - }; - - /** - * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read - * and the actual number of bytes read. - * @throws {Error} If it's not a valid varint - * @expose - */ - ByteBufferPrototype.readVarint32ZigZag = function(offset) { - var val = this.readVarint32(offset); - if (typeof val === 'object') - val["value"] = ByteBuffer.zigZagDecode32(val["value"]); - else - val = ByteBuffer.zigZagDecode32(val); - return val; - }; - - // types/varints/varint64 - - if (Long) { - - /** - * Maximum number of bytes required to store a 64bit base 128 variable-length integer. - * @type {number} - * @const - * @expose - */ - ByteBuffer.MAX_VARINT64_BYTES = 10; - - /** - * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer. - * @param {number|!Long} value Value to encode - * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES} - * @expose - */ - ByteBuffer.calculateVarint64 = function(value) { - if (typeof value === 'number') - value = Long.fromNumber(value); - else if (typeof value === 'string') - value = Long.fromString(value); - // ref: src/google/protobuf/io/coded_stream.cc - var part0 = value.toInt() >>> 0, - part1 = value.shiftRightUnsigned(28).toInt() >>> 0, - part2 = value.shiftRightUnsigned(56).toInt() >>> 0; - if (part2 == 0) { - if (part1 == 0) { - if (part0 < 1 << 14) - return part0 < 1 << 7 ? 1 : 2; - else - return part0 < 1 << 21 ? 3 : 4; - } else { - if (part1 < 1 << 14) - return part1 < 1 << 7 ? 5 : 6; - else - return part1 < 1 << 21 ? 7 : 8; - } - } else - return part2 < 1 << 7 ? 9 : 10; - }; - - /** - * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding. - * @param {number|!Long} value Signed long - * @returns {!Long} Unsigned zigzag encoded long - * @expose - */ - ByteBuffer.zigZagEncode64 = function(value) { - if (typeof value === 'number') - value = Long.fromNumber(value, false); - else if (typeof value === 'string') - value = Long.fromString(value, false); - else if (value.unsigned !== false) value = value.toSigned(); - // ref: src/google/protobuf/wire_format_lite.h - return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned(); - }; - - /** - * Decodes a zigzag encoded signed 64bit integer. - * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number - * @returns {!Long} Signed long - * @expose - */ - ByteBuffer.zigZagDecode64 = function(value) { - if (typeof value === 'number') - value = Long.fromNumber(value, false); - else if (typeof value === 'string') - value = Long.fromString(value, false); - else if (value.unsigned !== false) value = value.toSigned(); - // ref: src/google/protobuf/wire_format_lite.h - return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned(); - }; - - /** - * Writes a 64bit base 128 variable-length integer. - * @param {number|Long} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. - * @expose - */ - ByteBufferPrototype.writeVarint64 = function(value, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof value === 'number') - value = Long.fromNumber(value); - else if (typeof value === 'string') - value = Long.fromString(value); - else if (!(value && value instanceof Long)) - throw TypeError("Illegal value: "+value+" (not an integer or Long)"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - if (typeof value === 'number') - value = Long.fromNumber(value, false); - else if (typeof value === 'string') - value = Long.fromString(value, false); - else if (value.unsigned !== false) value = value.toSigned(); - var size = ByteBuffer.calculateVarint64(value), - part0 = value.toInt() >>> 0, - part1 = value.shiftRightUnsigned(28).toInt() >>> 0, - part2 = value.shiftRightUnsigned(56).toInt() >>> 0; - offset += size; - var capacity11 = this.buffer.byteLength; - if (offset > capacity11) - this.resize((capacity11 *= 2) > offset ? capacity11 : offset); - offset -= size; - switch (size) { - case 10: this.view[offset+9] = (part2 >>> 7) & 0x01; - case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F; - case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F; - case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F; - case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F; - case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F; - case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F; - case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F; - case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F; - case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F; - } - if (relative) { - this.offset += size; - return this; - } else { - return size; - } - }; - - /** - * Writes a zig-zag encoded 64bit base 128 variable-length integer. - * @param {number|Long} value Value to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. - * @expose - */ - ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) { - return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset); - }; - - /** - * Reads a 64bit base 128 variable-length integer. Requires Long.js. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and - * the actual number of bytes read. - * @throws {Error} If it's not a valid varint - * @expose - */ - ByteBufferPrototype.readVarint64 = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 1 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); - } - // ref: src/google/protobuf/io/coded_stream.cc - var start = offset, - part0 = 0, - part1 = 0, - part2 = 0, - b = 0; - b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) { - b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { - throw Error("Buffer overrun"); }}}}}}}}}} - var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false); - if (relative) { - this.offset = offset; - return value; - } else { - return { - 'value': value, - 'length': offset-start - }; - } - }; - - /** - * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and - * the actual number of bytes read. - * @throws {Error} If it's not a valid varint - * @expose - */ - ByteBufferPrototype.readVarint64ZigZag = function(offset) { - var val = this.readVarint64(offset); - if (val && val['value'] instanceof Long) - val["value"] = ByteBuffer.zigZagDecode64(val["value"]); - else - val = ByteBuffer.zigZagDecode64(val); - return val; - }; - - } // Long - - - // types/strings/cstring - - /** - * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL - * characters itself. - * @param {string} str String to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * contained in `str` + 1 if omitted. - * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written - * @expose - */ - ByteBufferPrototype.writeCString = function(str, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - var i, - k = str.length; - if (!this.noAssert) { - if (typeof str !== 'string') - throw TypeError("Illegal str: Not a string"); - for (i=0; i>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - // UTF8 strings do not contain zero bytes in between except for the zero character, so: - k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; - offset += k+1; - var capacity12 = this.buffer.byteLength; - if (offset > capacity12) - this.resize((capacity12 *= 2) > offset ? capacity12 : offset); - offset -= k+1; - utfx.encodeUTF16toUTF8(stringSource(str), function(b) { - this.view[offset++] = b; - }.bind(this)); - this.view[offset++] = 0; - if (relative) { - this.offset = offset; - return this; - } - return k; - }; - - /** - * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters - * itself. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string - * read and the actual number of bytes read. - * @expose - */ - ByteBufferPrototype.readCString = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 1 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); - } - var start = offset, - temp; - // UTF8 strings do not contain zero bytes in between except for the zero character itself, so: - var sd, b = -1; - utfx.decodeUTF8toUTF16(function() { - if (b === 0) return null; - if (offset >= this.limit) - throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit); - b = this.view[offset++]; - return b === 0 ? null : b; - }.bind(this), sd = stringDestination(), true); - if (relative) { - this.offset = offset; - return sd(); - } else { - return { - "string": sd(), - "length": offset - start - }; - } - }; - - // types/strings/istring - - /** - * Writes a length as uint32 prefixed UTF8 encoded string. - * @param {string} str String to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written - * @expose - * @see ByteBuffer#writeVarint32 - */ - ByteBufferPrototype.writeIString = function(str, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof str !== 'string') - throw TypeError("Illegal str: Not a string"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - var start = offset, - k; - k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; - offset += 4+k; - var capacity13 = this.buffer.byteLength; - if (offset > capacity13) - this.resize((capacity13 *= 2) > offset ? capacity13 : offset); - offset -= 4+k; - if (this.littleEndian) { - this.view[offset+3] = (k >>> 24) & 0xFF; - this.view[offset+2] = (k >>> 16) & 0xFF; - this.view[offset+1] = (k >>> 8) & 0xFF; - this.view[offset ] = k & 0xFF; - } else { - this.view[offset ] = (k >>> 24) & 0xFF; - this.view[offset+1] = (k >>> 16) & 0xFF; - this.view[offset+2] = (k >>> 8) & 0xFF; - this.view[offset+3] = k & 0xFF; - } - offset += 4; - utfx.encodeUTF16toUTF8(stringSource(str), function(b) { - this.view[offset++] = b; - }.bind(this)); - if (offset !== start + 4 + k) - throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k)); - if (relative) { - this.offset = offset; - return this; - } - return offset - start; - }; - - /** - * Reads a length as uint32 prefixed UTF8 encoded string. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string - * read and the actual number of bytes read. - * @expose - * @see ByteBuffer#readVarint32 - */ - ByteBufferPrototype.readIString = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 4 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); - } - var start = offset; - var len = this.readUint32(offset); - var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4); - offset += str['length']; - if (relative) { - this.offset = offset; - return str['string']; - } else { - return { - 'string': str['string'], - 'length': offset - start - }; - } - }; - - // types/strings/utf8string - - /** - * Metrics representing number of UTF8 characters. Evaluates to `c`. - * @type {string} - * @const - * @expose - */ - ByteBuffer.METRICS_CHARS = 'c'; - - /** - * Metrics representing number of bytes. Evaluates to `b`. - * @type {string} - * @const - * @expose - */ - ByteBuffer.METRICS_BYTES = 'b'; - - /** - * Writes an UTF8 encoded string. - * @param {string} str String to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. - * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. - * @expose - */ - ByteBufferPrototype.writeUTF8String = function(str, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - var k; - var start = offset; - k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; - offset += k; - var capacity14 = this.buffer.byteLength; - if (offset > capacity14) - this.resize((capacity14 *= 2) > offset ? capacity14 : offset); - offset -= k; - utfx.encodeUTF16toUTF8(stringSource(str), function(b) { - this.view[offset++] = b; - }.bind(this)); - if (relative) { - this.offset = offset; - return this; - } - return offset - start; - }; - - /** - * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}. - * @function - * @param {string} str String to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. - * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. - * @expose - */ - ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String; - - /** - * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's - * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF. - * @param {string} str String to calculate - * @returns {number} Number of UTF8 characters - * @expose - */ - ByteBuffer.calculateUTF8Chars = function(str) { - return utfx.calculateUTF16asUTF8(stringSource(str))[0]; - }; - - /** - * Calculates the number of UTF8 bytes of a string. - * @param {string} str String to calculate - * @returns {number} Number of UTF8 bytes - * @expose - */ - ByteBuffer.calculateUTF8Bytes = function(str) { - return utfx.calculateUTF16asUTF8(stringSource(str))[1]; - }; - - /** - * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}. - * @function - * @param {string} str String to calculate - * @returns {number} Number of UTF8 bytes - * @expose - */ - ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes; - - /** - * Reads an UTF8 encoded string. - * @param {number} length Number of characters or bytes to read. - * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to - * {@link ByteBuffer.METRICS_CHARS}. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string - * read and the actual number of bytes read. - * @expose - */ - ByteBufferPrototype.readUTF8String = function(length, metrics, offset) { - if (typeof metrics === 'number') { - offset = metrics; - metrics = undefined; - } - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS; - if (!this.noAssert) { - if (typeof length !== 'number' || length % 1 !== 0) - throw TypeError("Illegal length: "+length+" (not an integer)"); - length |= 0; - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - var i = 0, - start = offset, - sd; - if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser - sd = stringDestination(); - utfx.decodeUTF8(function() { - return i < length && offset < this.limit ? this.view[offset++] : null; - }.bind(this), function(cp) { - ++i; utfx.UTF8toUTF16(cp, sd); - }); - if (i !== length) - throw RangeError("Illegal range: Truncated data, "+i+" == "+length); - if (relative) { - this.offset = offset; - return sd(); - } else { - return { - "string": sd(), - "length": offset - start - }; - } - } else if (metrics === ByteBuffer.METRICS_BYTES) { - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + length > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); - } - var k = offset + length; - utfx.decodeUTF8toUTF16(function() { - return offset < k ? this.view[offset++] : null; - }.bind(this), sd = stringDestination(), this.noAssert); - if (offset !== k) - throw RangeError("Illegal range: Truncated data, "+offset+" == "+k); - if (relative) { - this.offset = offset; - return sd(); - } else { - return { - 'string': sd(), - 'length': offset - start - }; - } - } else - throw TypeError("Unsupported metrics: "+metrics); - }; - - /** - * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}. - * @function - * @param {number} length Number of characters or bytes to read - * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to - * {@link ByteBuffer.METRICS_CHARS}. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string - * read and the actual number of bytes read. - * @expose - */ - ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String; - - // types/strings/vstring - - /** - * Writes a length as varint32 prefixed UTF8 encoded string. - * @param {string} str String to write - * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written - * @expose - * @see ByteBuffer#writeVarint32 - */ - ByteBufferPrototype.writeVString = function(str, offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof str !== 'string') - throw TypeError("Illegal str: Not a string"); - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - var start = offset, - k, l; - k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; - l = ByteBuffer.calculateVarint32(k); - offset += l+k; - var capacity15 = this.buffer.byteLength; - if (offset > capacity15) - this.resize((capacity15 *= 2) > offset ? capacity15 : offset); - offset -= l+k; - offset += this.writeVarint32(k, offset); - utfx.encodeUTF16toUTF8(stringSource(str), function(b) { - this.view[offset++] = b; - }.bind(this)); - if (offset !== start+k+l) - throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l)); - if (relative) { - this.offset = offset; - return this; - } - return offset - start; - }; - - /** - * Reads a length as varint32 prefixed UTF8 encoded string. - * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string - * read and the actual number of bytes read. - * @expose - * @see ByteBuffer#readVarint32 - */ - ByteBufferPrototype.readVString = function(offset) { - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 1 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); - } - var start = offset; - var len = this.readVarint32(offset); - var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']); - offset += str['length']; - if (relative) { - this.offset = offset; - return str['string']; - } else { - return { - 'string': str['string'], - 'length': offset - start - }; - } - }; - - - /** - * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended - * data's length. - * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets - * will be modified according to the performed read operation. - * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") - * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. - * @returns {!ByteBuffer} this - * @expose - * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|` - * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|` - */ - ByteBufferPrototype.append = function(source, encoding, offset) { - if (typeof encoding === 'number' || typeof encoding !== 'string') { - offset = encoding; - encoding = undefined; - } - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - if (!(source instanceof ByteBuffer)) - source = ByteBuffer.wrap(source, encoding); - var length = source.limit - source.offset; - if (length <= 0) return this; // Nothing to append - offset += length; - var capacity16 = this.buffer.byteLength; - if (offset > capacity16) - this.resize((capacity16 *= 2) > offset ? capacity16 : offset); - offset -= length; - this.view.set(source.view.subarray(source.offset, source.limit), offset); - source.offset += length; - if (relative) this.offset += length; - return this; - }; - - /** - * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the - specified offset up to the length of this ByteBuffer's data. - * @param {!ByteBuffer} target Target ByteBuffer - * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * read if omitted. - * @returns {!ByteBuffer} this - * @expose - * @see ByteBuffer#append - */ - ByteBufferPrototype.appendTo = function(target, offset) { - target.append(this, offset); - return this; - }; - - /** - * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to - * disable them if your code already makes sure that everything is valid. - * @param {boolean} assert `true` to enable assertions, otherwise `false` - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.assert = function(assert) { - this.noAssert = !assert; - return this; - }; - - /** - * Gets the capacity of this ByteBuffer's backing buffer. - * @returns {number} Capacity of the backing buffer - * @expose - */ - ByteBufferPrototype.capacity = function() { - return this.buffer.byteLength; - }; - /** - * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the - * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.clear = function() { - this.offset = 0; - this.limit = this.buffer.byteLength; - this.markedOffset = -1; - return this; - }; - - /** - * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset}, - * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}. - * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false` - * @returns {!ByteBuffer} Cloned instance - * @expose - */ - ByteBufferPrototype.clone = function(copy) { - var bb = new ByteBuffer(0, this.littleEndian, this.noAssert); - if (copy) { - bb.buffer = new ArrayBuffer(this.buffer.byteLength); - bb.view = new Uint8Array(bb.buffer); - } else { - bb.buffer = this.buffer; - bb.view = this.view; - } - bb.offset = this.offset; - bb.markedOffset = this.markedOffset; - bb.limit = this.limit; - return bb; - }; - - /** - * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes - * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and - * adapt {@link ByteBuffer#markedOffset} to the same relative position if set. - * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} - * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.compact = function(begin, end) { - if (typeof begin === 'undefined') begin = this.offset; - if (typeof end === 'undefined') end = this.limit; - if (!this.noAssert) { - if (typeof begin !== 'number' || begin % 1 !== 0) - throw TypeError("Illegal begin: Not an integer"); - begin >>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - if (begin === 0 && end === this.buffer.byteLength) - return this; // Already compacted - var len = end - begin; - if (len === 0) { - this.buffer = EMPTY_BUFFER; - this.view = null; - if (this.markedOffset >= 0) this.markedOffset -= begin; - this.offset = 0; - this.limit = 0; - return this; - } - var buffer = new ArrayBuffer(len); - var view = new Uint8Array(buffer); - view.set(this.view.subarray(begin, end)); - this.buffer = buffer; - this.view = view; - if (this.markedOffset >= 0) this.markedOffset -= begin; - this.offset = 0; - this.limit = len; - return this; - }; - - /** - * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and - * {@link ByteBuffer#limit}. - * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. - * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. - * @returns {!ByteBuffer} Copy - * @expose - */ - ByteBufferPrototype.copy = function(begin, end) { - if (typeof begin === 'undefined') begin = this.offset; - if (typeof end === 'undefined') end = this.limit; - if (!this.noAssert) { - if (typeof begin !== 'number' || begin % 1 !== 0) - throw TypeError("Illegal begin: Not an integer"); - begin >>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - if (begin === end) - return new ByteBuffer(0, this.littleEndian, this.noAssert); - var capacity = end - begin, - bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert); - bb.offset = 0; - bb.limit = capacity; - if (bb.markedOffset >= 0) bb.markedOffset -= begin; - this.copyTo(bb, 0, begin, end); - return bb; - }; - - /** - * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and - * {@link ByteBuffer#limit}. - * @param {!ByteBuffer} target Target ByteBuffer - * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset} - * by the number of bytes copied if omitted. - * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the - * number of bytes copied if omitted. - * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit} - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) { - var relative, - targetRelative; - if (!this.noAssert) { - if (!ByteBuffer.isByteBuffer(target)) - throw TypeError("Illegal target: Not a ByteBuffer"); - } - targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0; - sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0; - sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0; - - if (targetOffset < 0 || targetOffset > target.buffer.byteLength) - throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength); - if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength) - throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength); - - var len = sourceLimit - sourceOffset; - if (len === 0) - return target; // Nothing to copy - - target.ensureCapacity(targetOffset + len); - - target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset); - - if (relative) this.offset += len; - if (targetRelative) target.offset += len; - - return this; - }; - - /** - * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the - * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity, - * the required capacity will be used instead. - * @param {number} capacity Required capacity - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.ensureCapacity = function(capacity) { - var current = this.buffer.byteLength; - if (current < capacity) - return this.resize((current *= 2) > capacity ? current : capacity); - return this; - }; - - /** - * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between - * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. - * @param {number|string} value Byte value to fill with. If given as a string, the first character is used. - * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes - * written if omitted. defaults to {@link ByteBuffer#offset}. - * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. - * @returns {!ByteBuffer} this - * @expose - * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes - */ - ByteBufferPrototype.fill = function(value, begin, end) { - var relative = typeof begin === 'undefined'; - if (relative) begin = this.offset; - if (typeof value === 'string' && value.length > 0) - value = value.charCodeAt(0); - if (typeof begin === 'undefined') begin = this.offset; - if (typeof end === 'undefined') end = this.limit; - if (!this.noAssert) { - if (typeof value !== 'number' || value % 1 !== 0) - throw TypeError("Illegal value: "+value+" (not an integer)"); - value |= 0; - if (typeof begin !== 'number' || begin % 1 !== 0) - throw TypeError("Illegal begin: Not an integer"); - begin >>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - if (begin >= end) - return this; // Nothing to fill - while (begin < end) this.view[begin++] = value; - if (relative) this.offset = begin; - return this; - }; - - /** - * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and - * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.flip = function() { - this.limit = this.offset; - this.offset = 0; - return this; - }; - /** - * Marks an offset on this ByteBuffer to be used later. - * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}. - * @returns {!ByteBuffer} this - * @throws {TypeError} If `offset` is not a valid number - * @throws {RangeError} If `offset` is out of bounds - * @see ByteBuffer#reset - * @expose - */ - ByteBufferPrototype.mark = function(offset) { - offset = typeof offset === 'undefined' ? this.offset : offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - this.markedOffset = offset; - return this; - }; - /** - * Sets the byte order. - * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.order = function(littleEndian) { - if (!this.noAssert) { - if (typeof littleEndian !== 'boolean') - throw TypeError("Illegal littleEndian: Not a boolean"); - } - this.littleEndian = !!littleEndian; - return this; - }; - - /** - * Switches (to) little endian byte order. - * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.LE = function(littleEndian) { - this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true; - return this; - }; - - /** - * Switches (to) big endian byte order. - * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.BE = function(bigEndian) { - this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false; - return this; - }; - /** - * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the - * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer - * will be resized and its contents moved accordingly. - * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be - * modified according to the performed read operation. - * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") - * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes - * prepended if omitted. - * @returns {!ByteBuffer} this - * @expose - * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|` - * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|` - */ - ByteBufferPrototype.prepend = function(source, encoding, offset) { - if (typeof encoding === 'number' || typeof encoding !== 'string') { - offset = encoding; - encoding = undefined; - } - var relative = typeof offset === 'undefined'; - if (relative) offset = this.offset; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: "+offset+" (not an integer)"); - offset >>>= 0; - if (offset < 0 || offset + 0 > this.buffer.byteLength) - throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); - } - if (!(source instanceof ByteBuffer)) - source = ByteBuffer.wrap(source, encoding); - var len = source.limit - source.offset; - if (len <= 0) return this; // Nothing to prepend - var diff = len - offset; - if (diff > 0) { // Not enough space before offset, so resize + move - var buffer = new ArrayBuffer(this.buffer.byteLength + diff); - var view = new Uint8Array(buffer); - view.set(this.view.subarray(offset, this.buffer.byteLength), len); - this.buffer = buffer; - this.view = view; - this.offset += diff; - if (this.markedOffset >= 0) this.markedOffset += diff; - this.limit += diff; - offset += diff; - } else { - var arrayView = new Uint8Array(this.buffer); - } - this.view.set(source.view.subarray(source.offset, source.limit), offset - len); - - source.offset = source.limit; - if (relative) - this.offset -= len; - return this; - }; - - /** - * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the - * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer - * will be resized and its contents moved accordingly. - * @param {!ByteBuffer} target Target ByteBuffer - * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes - * prepended if omitted. - * @returns {!ByteBuffer} this - * @expose - * @see ByteBuffer#prepend - */ - ByteBufferPrototype.prependTo = function(target, offset) { - target.prepend(this, offset); - return this; - }; - /** - * Prints debug information about this ByteBuffer's contents. - * @param {function(string)=} out Output function to call, defaults to console.log - * @expose - */ - ByteBufferPrototype.printDebug = function(out) { - if (typeof out !== 'function') out = console.log.bind(console); - out( - this.toString()+"\n"+ - "-------------------------------------------------------------------\n"+ - this.toDebug(/* columns */ true) - ); - }; - - /** - * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and - * {@link ByteBuffer#limit}, so this returns `limit - offset`. - * @returns {number} Remaining readable bytes. May be negative if `offset > limit`. - * @expose - */ - ByteBufferPrototype.remaining = function() { - return this.limit - this.offset; - }; - /** - * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark} - * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been - * marked, sets `offset = 0`. - * @returns {!ByteBuffer} this - * @see ByteBuffer#mark - * @expose - */ - ByteBufferPrototype.reset = function() { - if (this.markedOffset >= 0) { - this.offset = this.markedOffset; - this.markedOffset = -1; - } else { - this.offset = 0; - } - return this; - }; - /** - * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that - * large or larger. - * @param {number} capacity Capacity required - * @returns {!ByteBuffer} this - * @throws {TypeError} If `capacity` is not a number - * @throws {RangeError} If `capacity < 0` - * @expose - */ - ByteBufferPrototype.resize = function(capacity) { - if (!this.noAssert) { - if (typeof capacity !== 'number' || capacity % 1 !== 0) - throw TypeError("Illegal capacity: "+capacity+" (not an integer)"); - capacity |= 0; - if (capacity < 0) - throw RangeError("Illegal capacity: 0 <= "+capacity); - } - if (this.buffer.byteLength < capacity) { - var buffer = new ArrayBuffer(capacity); - var view = new Uint8Array(buffer); - view.set(this.view); - this.buffer = buffer; - this.view = view; - } - return this; - }; - /** - * Reverses this ByteBuffer's contents. - * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} - * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.reverse = function(begin, end) { - if (typeof begin === 'undefined') begin = this.offset; - if (typeof end === 'undefined') end = this.limit; - if (!this.noAssert) { - if (typeof begin !== 'number' || begin % 1 !== 0) - throw TypeError("Illegal begin: Not an integer"); - begin >>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - if (begin === end) - return this; // Nothing to reverse - Array.prototype.reverse.call(this.view.subarray(begin, end)); - return this; - }; - /** - * Skips the next `length` bytes. This will just advance - * @param {number} length Number of bytes to skip. May also be negative to move the offset back. - * @returns {!ByteBuffer} this - * @expose - */ - ByteBufferPrototype.skip = function(length) { - if (!this.noAssert) { - if (typeof length !== 'number' || length % 1 !== 0) - throw TypeError("Illegal length: "+length+" (not an integer)"); - length |= 0; - } - var offset = this.offset + length; - if (!this.noAssert) { - if (offset < 0 || offset > this.buffer.byteLength) - throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength); - } - this.offset = offset; - return this; - }; - - /** - * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`. - * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. - * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. - * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer} - * @expose - */ - ByteBufferPrototype.slice = function(begin, end) { - if (typeof begin === 'undefined') begin = this.offset; - if (typeof end === 'undefined') end = this.limit; - if (!this.noAssert) { - if (typeof begin !== 'number' || begin % 1 !== 0) - throw TypeError("Illegal begin: Not an integer"); - begin >>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - var bb = this.clone(); - bb.offset = begin; - bb.limit = end; - return bb; - }; - /** - * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between - * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. - * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if - * possible. Defaults to `false` - * @returns {!ArrayBuffer} Contents as an ArrayBuffer - * @expose - */ - ByteBufferPrototype.toBuffer = function(forceCopy) { - var offset = this.offset, - limit = this.limit; - if (!this.noAssert) { - if (typeof offset !== 'number' || offset % 1 !== 0) - throw TypeError("Illegal offset: Not an integer"); - offset >>>= 0; - if (typeof limit !== 'number' || limit % 1 !== 0) - throw TypeError("Illegal limit: Not an integer"); - limit >>>= 0; - if (offset < 0 || offset > limit || limit > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength); - } - // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is - // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So: - if (!forceCopy && offset === 0 && limit === this.buffer.byteLength) - return this.buffer; - if (offset === limit) - return EMPTY_BUFFER; - var buffer = new ArrayBuffer(limit - offset); - new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0); - return buffer; - }; - - /** - * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between - * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}. - * @function - * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory. - * Defaults to `false` - * @returns {!ArrayBuffer} Contents as an ArrayBuffer - * @expose - */ - ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer; - - /** - * Converts the ByteBuffer's contents to a string. - * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows - * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with - * highlighted offsets. - * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset} - * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} - * @returns {string} String representation - * @throws {Error} If `encoding` is invalid - * @expose - */ - ByteBufferPrototype.toString = function(encoding, begin, end) { - if (typeof encoding === 'undefined') - return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")"; - if (typeof encoding === 'number') - encoding = "utf8", - begin = encoding, - end = begin; - switch (encoding) { - case "utf8": - return this.toUTF8(begin, end); - case "base64": - return this.toBase64(begin, end); - case "hex": - return this.toHex(begin, end); - case "binary": - return this.toBinary(begin, end); - case "debug": - return this.toDebug(); - case "columns": - return this.toColumns(); - default: - throw Error("Unsupported encoding: "+encoding); - } - }; - - // lxiv-embeddable - - /** - * lxiv-embeddable (c) 2014 Daniel Wirtz - * Released under the Apache License, Version 2.0 - * see: https://github.com/dcodeIO/lxiv for details - */ - var lxiv = function() { - "use strict"; - - /** - * lxiv namespace. - * @type {!Object.} - * @exports lxiv - */ - var lxiv = {}; - - /** - * Character codes for output. - * @type {!Array.} - * @inner - */ - var aout = [ - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 - ]; - - /** - * Character codes for input. - * @type {!Array.} - * @inner - */ - var ain = []; - for (var i=0, k=aout.length; i>2)&0x3f]); - t = (b&0x3)<<4; - if ((b = src()) !== null) { - t |= (b>>4)&0xf; - dst(aout[(t|((b>>4)&0xf))&0x3f]); - t = (b&0xf)<<2; - if ((b = src()) !== null) - dst(aout[(t|((b>>6)&0x3))&0x3f]), - dst(aout[b&0x3f]); - else - dst(aout[t&0x3f]), - dst(61); - } else - dst(aout[t&0x3f]), - dst(61), - dst(61); - } - }; - - /** - * Decodes base64 char codes to bytes. - * @param {!function():number|null} src Characters source as a function returning the next char code respectively - * `null` if there are no more characters left. - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. - * @throws {Error} If a character code is invalid - */ - lxiv.decode = function(src, dst) { - var c, t1, t2; - function fail(c) { - throw Error("Illegal character code: "+c); - } - while ((c = src()) !== null) { - t1 = ain[c]; - if (typeof t1 === 'undefined') fail(c); - if ((c = src()) !== null) { - t2 = ain[c]; - if (typeof t2 === 'undefined') fail(c); - dst((t1<<2)>>>0|(t2&0x30)>>4); - if ((c = src()) !== null) { - t1 = ain[c]; - if (typeof t1 === 'undefined') - if (c === 61) break; else fail(c); - dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2); - if ((c = src()) !== null) { - t2 = ain[c]; - if (typeof t2 === 'undefined') - if (c === 61) break; else fail(c); - dst(((t1&0x3)<<6)>>>0|t2); - } - } - } - } - }; - - /** - * Tests if a string is valid base64. - * @param {string} str String to test - * @returns {boolean} `true` if valid, otherwise `false` - */ - lxiv.test = function(str) { - return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str); - }; - - return lxiv; - }(); - - // encodings/base64 - - /** - * Encodes this ByteBuffer's contents to a base64 encoded string. - * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}. - * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}. - * @returns {string} Base64 encoded string - * @throws {RangeError} If `begin` or `end` is out of bounds - * @expose - */ - ByteBufferPrototype.toBase64 = function(begin, end) { - if (typeof begin === 'undefined') - begin = this.offset; - if (typeof end === 'undefined') - end = this.limit; - begin = begin | 0; end = end | 0; - if (begin < 0 || end > this.capacity || begin > end) - throw RangeError("begin, end"); - var sd; lxiv.encode(function() { - return begin < end ? this.view[begin++] : null; - }.bind(this), sd = stringDestination()); - return sd(); - }; - - /** - * Decodes a base64 encoded string to a ByteBuffer. - * @param {string} str String to decode - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @returns {!ByteBuffer} ByteBuffer - * @expose - */ - ByteBuffer.fromBase64 = function(str, littleEndian) { - if (typeof str !== 'string') - throw TypeError("str"); - var bb = new ByteBuffer(str.length/4*3, littleEndian), - i = 0; - lxiv.decode(stringSource(str), function(b) { - bb.view[i++] = b; - }); - bb.limit = i; - return bb; - }; - - /** - * Encodes a binary string to base64 like `window.btoa` does. - * @param {string} str Binary string - * @returns {string} Base64 encoded string - * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa - * @expose - */ - ByteBuffer.btoa = function(str) { - return ByteBuffer.fromBinary(str).toBase64(); - }; - - /** - * Decodes a base64 encoded string to binary like `window.atob` does. - * @param {string} b64 Base64 encoded string - * @returns {string} Binary string - * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob - * @expose - */ - ByteBuffer.atob = function(b64) { - return ByteBuffer.fromBase64(b64).toBinary(); - }; - - // encodings/binary - - /** - * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes. - * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}. - * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}. - * @returns {string} Binary encoded string - * @throws {RangeError} If `offset > limit` - * @expose - */ - ByteBufferPrototype.toBinary = function(begin, end) { - if (typeof begin === 'undefined') - begin = this.offset; - if (typeof end === 'undefined') - end = this.limit; - begin |= 0; end |= 0; - if (begin < 0 || end > this.capacity() || begin > end) - throw RangeError("begin, end"); - if (begin === end) - return ""; - var chars = [], - parts = []; - while (begin < end) { - chars.push(this.view[begin++]); - if (chars.length >= 1024) - parts.push(String.fromCharCode.apply(String, chars)), - chars = []; - } - return parts.join('') + String.fromCharCode.apply(String, chars); - }; - - /** - * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer. - * @param {string} str String to decode - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @returns {!ByteBuffer} ByteBuffer - * @expose - */ - ByteBuffer.fromBinary = function(str, littleEndian) { - if (typeof str !== 'string') - throw TypeError("str"); - var i = 0, - k = str.length, - charCode, - bb = new ByteBuffer(k, littleEndian); - while (i 0xff) - throw RangeError("illegal char code: "+charCode); - bb.view[i++] = charCode; - } - bb.limit = k; - return bb; - }; - - // encodings/debug - - /** - * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are: - * * `<` : offset, - * * `'` : markedOffset, - * * `>` : limit, - * * `|` : offset and limit, - * * `[` : offset and markedOffset, - * * `]` : markedOffset and limit, - * * `!` : offset, markedOffset and limit - * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false` - * @returns {string|!Array.} Debug string or array of lines if `asArray = true` - * @expose - * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3` - * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4` - * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1` - * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1` - */ - ByteBufferPrototype.toDebug = function(columns) { - var i = -1, - k = this.buffer.byteLength, - b, - hex = "", - asc = "", - out = ""; - while (i 32 && b < 127 ? String.fromCharCode(b) : '.'; - } - ++i; - if (columns) { - if (i > 0 && i % 16 === 0 && i !== k) { - while (hex.length < 3*16+3) hex += " "; - out += hex+asc+"\n"; - hex = asc = ""; - } - } - if (i === this.offset && i === this.limit) - hex += i === this.markedOffset ? "!" : "|"; - else if (i === this.offset) - hex += i === this.markedOffset ? "[" : "<"; - else if (i === this.limit) - hex += i === this.markedOffset ? "]" : ">"; - else - hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : ""); - } - if (columns && hex !== " ") { - while (hex.length < 3*16+3) - hex += " "; - out += hex + asc + "\n"; - } - return columns ? out : hex; - }; - - /** - * Decodes a hex encoded string with marked offsets to a ByteBuffer. - * @param {string} str Debug string to decode (not be generated with `columns = true`) - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @returns {!ByteBuffer} ByteBuffer - * @expose - * @see ByteBuffer#toDebug - */ - ByteBuffer.fromDebug = function(str, littleEndian, noAssert) { - var k = str.length, - bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert); - var i = 0, j = 0, ch, b, - rs = false, // Require symbol next - ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)? - fail = false; - while (i': - if (!noAssert) { - if (hl) { - fail = true; - break; - } - hl = true; - } - bb.limit = j; - rs = false; - break; - case "'": - if (!noAssert) { - if (hm) { - fail = true; - break; - } - hm = true; - } - bb.markedOffset = j; - rs = false; - break; - case ' ': - rs = false; - break; - default: - if (!noAssert) { - if (rs) { - fail = true; - break; - } - } - b = parseInt(ch+str.charAt(i++), 16); - if (!noAssert) { - if (isNaN(b) || b < 0 || b > 255) - throw TypeError("Illegal str: Not a debug encoded string"); - } - bb.view[j++] = b; - rs = true; - } - if (fail) - throw TypeError("Illegal str: Invalid symbol at "+i); - } - if (!noAssert) { - if (!ho || !hl) - throw TypeError("Illegal str: Missing offset or limit"); - if (j>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - var out = new Array(end - begin), - b; - while (begin < end) { - b = this.view[begin++]; - if (b < 0x10) - out.push("0", b.toString(16)); - else out.push(b.toString(16)); - } - return out.join(''); - }; - - /** - * Decodes a hex encoded string to a ByteBuffer. - * @param {string} str String to decode - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @returns {!ByteBuffer} ByteBuffer - * @expose - */ - ByteBuffer.fromHex = function(str, littleEndian, noAssert) { - if (!noAssert) { - if (typeof str !== 'string') - throw TypeError("Illegal str: Not a string"); - if (str.length % 2 !== 0) - throw TypeError("Illegal str: Length not a multiple of 2"); - } - var k = str.length, - bb = new ByteBuffer((k / 2) | 0, littleEndian), - b; - for (var i=0, j=0; i 255) - throw TypeError("Illegal str: Contains non-hex characters"); - bb.view[j++] = b; - } - bb.limit = j; - return bb; - }; - - // utfx-embeddable - - /** - * utfx-embeddable (c) 2014 Daniel Wirtz - * Released under the Apache License, Version 2.0 - * see: https://github.com/dcodeIO/utfx for details - */ - var utfx = function() { - "use strict"; - - /** - * utfx namespace. - * @inner - * @type {!Object.} - */ - var utfx = {}; - - /** - * Maximum valid code point. - * @type {number} - * @const - */ - utfx.MAX_CODEPOINT = 0x10FFFF; - - /** - * Encodes UTF8 code points to UTF8 bytes. - * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point - * respectively `null` if there are no more code points left or a single numeric code point. - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte - */ - utfx.encodeUTF8 = function(src, dst) { - var cp = null; - if (typeof src === 'number') - cp = src, - src = function() { return null; }; - while (cp !== null || (cp = src()) !== null) { - if (cp < 0x80) - dst(cp&0x7F); - else if (cp < 0x800) - dst(((cp>>6)&0x1F)|0xC0), - dst((cp&0x3F)|0x80); - else if (cp < 0x10000) - dst(((cp>>12)&0x0F)|0xE0), - dst(((cp>>6)&0x3F)|0x80), - dst((cp&0x3F)|0x80); - else - dst(((cp>>18)&0x07)|0xF0), - dst(((cp>>12)&0x3F)|0x80), - dst(((cp>>6)&0x3F)|0x80), - dst((cp&0x3F)|0x80); - cp = null; - } - }; - - /** - * Decodes UTF8 bytes to UTF8 code points. - * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there - * are no more bytes left. - * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. - * @throws {RangeError} If a starting byte is invalid in UTF8 - * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the - * remaining bytes. - */ - utfx.decodeUTF8 = function(src, dst) { - var a, b, c, d, fail = function(b) { - b = b.slice(0, b.indexOf(null)); - var err = Error(b.toString()); - err.name = "TruncatedError"; - err['bytes'] = b; - throw err; - }; - while ((a = src()) !== null) { - if ((a&0x80) === 0) - dst(a); - else if ((a&0xE0) === 0xC0) - ((b = src()) === null) && fail([a, b]), - dst(((a&0x1F)<<6) | (b&0x3F)); - else if ((a&0xF0) === 0xE0) - ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), - dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); - else if ((a&0xF8) === 0xF0) - ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), - dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); - else throw RangeError("Illegal starting byte: "+a); - } - }; - - /** - * Converts UTF16 characters to UTF8 code points. - * @param {!function():number|null} src Characters source as a function returning the next char code respectively - * `null` if there are no more characters left. - * @param {!function(number)} dst Code points destination as a function successively called with each converted code - * point. - */ - utfx.UTF16toUTF8 = function(src, dst) { - var c1, c2 = null; - while (true) { - if ((c1 = c2 !== null ? c2 : src()) === null) - break; - if (c1 >= 0xD800 && c1 <= 0xDFFF) { - if ((c2 = src()) !== null) { - if (c2 >= 0xDC00 && c2 <= 0xDFFF) { - dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); - c2 = null; continue; - } - } - } - dst(c1); - } - if (c2 !== null) dst(c2); - }; - - /** - * Converts UTF8 code points to UTF16 characters. - * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point - * respectively `null` if there are no more code points left or a single numeric code point. - * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. - * @throws {RangeError} If a code point is out of range - */ - utfx.UTF8toUTF16 = function(src, dst) { - var cp = null; - if (typeof src === 'number') - cp = src, src = function() { return null; }; - while (cp !== null || (cp = src()) !== null) { - if (cp <= 0xFFFF) - dst(cp); - else - cp -= 0x10000, - dst((cp>>10)+0xD800), - dst((cp%0x400)+0xDC00); - cp = null; - } - }; - - /** - * Converts and encodes UTF16 characters to UTF8 bytes. - * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` - * if there are no more characters left. - * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. - */ - utfx.encodeUTF16toUTF8 = function(src, dst) { - utfx.UTF16toUTF8(src, function(cp) { - utfx.encodeUTF8(cp, dst); - }); - }; - - /** - * Decodes and converts UTF8 bytes to UTF16 characters. - * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there - * are no more bytes left. - * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. - * @throws {RangeError} If a starting byte is invalid in UTF8 - * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. - */ - utfx.decodeUTF8toUTF16 = function(src, dst) { - utfx.decodeUTF8(src, function(cp) { - utfx.UTF8toUTF16(cp, dst); - }); - }; - - /** - * Calculates the byte length of an UTF8 code point. - * @param {number} cp UTF8 code point - * @returns {number} Byte length - */ - utfx.calculateCodePoint = function(cp) { - return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; - }; - - /** - * Calculates the number of UTF8 bytes required to store UTF8 code points. - * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively - * `null` if there are no more code points left. - * @returns {number} The number of UTF8 bytes required - */ - utfx.calculateUTF8 = function(src) { - var cp, l=0; - while ((cp = src()) !== null) - l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; - return l; - }; - - /** - * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. - * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively - * `null` if there are no more characters left. - * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. - */ - utfx.calculateUTF16asUTF8 = function(src) { - var n=0, l=0; - utfx.UTF16toUTF8(src, function(cp) { - ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; - }); - return [n,l]; - }; - - return utfx; - }(); - - // encodings/utf8 - - /** - * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded - * string. - * @returns {string} Hex encoded string - * @throws {RangeError} If `offset > limit` - * @expose - */ - ByteBufferPrototype.toUTF8 = function(begin, end) { - if (typeof begin === 'undefined') begin = this.offset; - if (typeof end === 'undefined') end = this.limit; - if (!this.noAssert) { - if (typeof begin !== 'number' || begin % 1 !== 0) - throw TypeError("Illegal begin: Not an integer"); - begin >>>= 0; - if (typeof end !== 'number' || end % 1 !== 0) - throw TypeError("Illegal end: Not an integer"); - end >>>= 0; - if (begin < 0 || begin > end || end > this.buffer.byteLength) - throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); - } - var sd; try { - utfx.decodeUTF8toUTF16(function() { - return begin < end ? this.view[begin++] : null; - }.bind(this), sd = stringDestination()); - } catch (e) { - if (begin !== end) - throw RangeError("Illegal range: Truncated data, "+begin+" != "+end); - } - return sd(); - }; - - /** - * Decodes an UTF8 encoded string to a ByteBuffer. - * @param {string} str String to decode - * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to - * {@link ByteBuffer.DEFAULT_ENDIAN}. - * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to - * {@link ByteBuffer.DEFAULT_NOASSERT}. - * @returns {!ByteBuffer} ByteBuffer - * @expose - */ - ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) { - if (!noAssert) - if (typeof str !== 'string') - throw TypeError("Illegal str: Not a string"); - var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert), - i = 0; - utfx.encodeUTF16toUTF8(stringSource(str), function(b) { - bb.view[i++] = b; - }); - bb.limit = i; - return bb; - }; - - return ByteBuffer; -}); - -},{"long":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/long/dist/long.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/cipher-base/index.js":[function(require,module,exports){ -(function (Buffer){ -var Transform = require('stream').Transform -var inherits = require('inherits') -var StringDecoder = require('string_decoder').StringDecoder -module.exports = CipherBase -inherits(CipherBase, Transform) -function CipherBase (hashMode) { - Transform.call(this) - this.hashMode = typeof hashMode === 'string' - if (this.hashMode) { - this[hashMode] = this._finalOrDigest - } else { - this.final = this._finalOrDigest - } - this._decoder = null - this._encoding = null -} -CipherBase.prototype.update = function (data, inputEnc, outputEnc) { - if (typeof data === 'string') { - data = new Buffer(data, inputEnc) - } - var outData = this._update(data) - if (this.hashMode) { - return this - } - if (outputEnc) { - outData = this._toString(outData, outputEnc) - } - return outData -} - -CipherBase.prototype.setAutoPadding = function () {} - -CipherBase.prototype.getAuthTag = function () { - throw new Error('trying to get auth tag in unsupported state') -} - -CipherBase.prototype.setAuthTag = function () { - throw new Error('trying to set auth tag in unsupported state') -} - -CipherBase.prototype.setAAD = function () { - throw new Error('trying to set aad in unsupported state') -} - -CipherBase.prototype._transform = function (data, _, next) { - var err - try { - if (this.hashMode) { - this._update(data) - } else { - this.push(this._update(data)) - } - } catch (e) { - err = e - } finally { - next(err) - } -} -CipherBase.prototype._flush = function (done) { - var err - try { - this.push(this._final()) - } catch (e) { - err = e - } finally { - done(err) - } -} -CipherBase.prototype._finalOrDigest = function (outputEnc) { - var outData = this._final() || new Buffer('') - if (outputEnc) { - outData = this._toString(outData, outputEnc, true) - } - return outData -} - -CipherBase.prototype._toString = function (value, enc, fin) { - if (!this._decoder) { - this._decoder = new StringDecoder(enc) - this._encoding = enc - } - if (this._encoding !== enc) { - throw new Error('can\'t switch encodings') - } - var out = this._decoder.write(value) - if (fin) { - out += this._decoder.end() - } - return out -} - -}).call(this,require("buffer").Buffer) - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","stream":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/stream-browserify/index.js","string_decoder":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browserify/node_modules/string_decoder/lib/string_decoder.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/core-util-is/lib/util.js":[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); - } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = Buffer.isBuffer; - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) - -},{"../../is-buffer/index.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/is-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hash/browser.js":[function(require,module,exports){ -'use strict' -var inherits = require('inherits') -var MD5 = require('md5.js') -var RIPEMD160 = require('ripemd160') -var sha = require('sha.js') -var Base = require('cipher-base') - -function Hash (hash) { - Base.call(this, 'digest') - - this._hash = hash -} - -inherits(Hash, Base) - -Hash.prototype._update = function (data) { - this._hash.update(data) -} - -Hash.prototype._final = function () { - return this._hash.digest() -} - -module.exports = function createHash (alg) { - alg = alg.toLowerCase() - if (alg === 'md5') return new MD5() - if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160() - - return new Hash(sha(alg)) -} - -},{"cipher-base":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/cipher-base/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","md5.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/md5.js/index.js","ripemd160":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ripemd160/index.js","sha.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hash/md5.js":[function(require,module,exports){ -var MD5 = require('md5.js') - -module.exports = function (buffer) { - return new MD5().update(buffer).digest() -} - -},{"md5.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/md5.js/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hmac/browser.js":[function(require,module,exports){ -'use strict' -var inherits = require('inherits') -var Legacy = require('./legacy') -var Base = require('cipher-base') -var Buffer = require('safe-buffer').Buffer -var md5 = require('create-hash/md5') -var RIPEMD160 = require('ripemd160') - -var sha = require('sha.js') - -var ZEROS = Buffer.alloc(128) - -function Hmac (alg, key) { - Base.call(this, 'digest') - if (typeof key === 'string') { - key = Buffer.from(key) - } - - var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64 - - this._alg = alg - this._key = key - if (key.length > blocksize) { - var hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg) - key = hash.update(key).digest() - } else if (key.length < blocksize) { - key = Buffer.concat([key, ZEROS], blocksize) - } - - var ipad = this._ipad = Buffer.allocUnsafe(blocksize) - var opad = this._opad = Buffer.allocUnsafe(blocksize) - - for (var i = 0; i < blocksize; i++) { - ipad[i] = key[i] ^ 0x36 - opad[i] = key[i] ^ 0x5C - } - this._hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg) - this._hash.update(ipad) -} - -inherits(Hmac, Base) - -Hmac.prototype._update = function (data) { - this._hash.update(data) -} - -Hmac.prototype._final = function () { - var h = this._hash.digest() - var hash = this._alg === 'rmd160' ? new RIPEMD160() : sha(this._alg) - return hash.update(this._opad).update(h).digest() -} - -module.exports = function createHmac (alg, key) { - alg = alg.toLowerCase() - if (alg === 'rmd160' || alg === 'ripemd160') { - return new Hmac('rmd160', key) - } - if (alg === 'md5') { - return new Legacy(md5, key) - } - return new Hmac(alg, key) -} - -},{"./legacy":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hmac/legacy.js","cipher-base":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/cipher-base/index.js","create-hash/md5":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hash/md5.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","ripemd160":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ripemd160/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js","sha.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/create-hmac/legacy.js":[function(require,module,exports){ -'use strict' -var inherits = require('inherits') -var Buffer = require('safe-buffer').Buffer - -var Base = require('cipher-base') - -var ZEROS = Buffer.alloc(128) -var blocksize = 64 - -function Hmac (alg, key) { - Base.call(this, 'digest') - if (typeof key === 'string') { - key = Buffer.from(key) - } - - this._alg = alg - this._key = key - - if (key.length > blocksize) { - key = alg(key) - } else if (key.length < blocksize) { - key = Buffer.concat([key, ZEROS], blocksize) - } - - var ipad = this._ipad = Buffer.allocUnsafe(blocksize) - var opad = this._opad = Buffer.allocUnsafe(blocksize) - - for (var i = 0; i < blocksize; i++) { - ipad[i] = key[i] ^ 0x36 - opad[i] = key[i] ^ 0x5C - } - - this._hash = [ipad] -} - -inherits(Hmac, Base) - -Hmac.prototype._update = function (data) { - this._hash.push(data) -} - -Hmac.prototype._final = function () { - var h = this._alg(Buffer.concat(this._hash)) - return this._alg(Buffer.concat([this._opad, h])) -} -module.exports = Hmac - -},{"cipher-base":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/cipher-base/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/aes.js":[function(require,module,exports){ -;(function (root, factory, undef) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var BlockCipher = C_lib.BlockCipher; - var C_algo = C.algo; - - // Lookup tables - var SBOX = []; - var INV_SBOX = []; - var SUB_MIX_0 = []; - var SUB_MIX_1 = []; - var SUB_MIX_2 = []; - var SUB_MIX_3 = []; - var INV_SUB_MIX_0 = []; - var INV_SUB_MIX_1 = []; - var INV_SUB_MIX_2 = []; - var INV_SUB_MIX_3 = []; - - // Compute lookup tables - (function () { - // Compute double table - var d = []; - for (var i = 0; i < 256; i++) { - if (i < 128) { - d[i] = i << 1; - } else { - d[i] = (i << 1) ^ 0x11b; - } - } - - // Walk GF(2^8) - var x = 0; - var xi = 0; - for (var i = 0; i < 256; i++) { - // Compute sbox - var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); - sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; - SBOX[x] = sx; - INV_SBOX[sx] = x; - - // Compute multiplication - var x2 = d[x]; - var x4 = d[x2]; - var x8 = d[x4]; - - // Compute sub bytes, mix columns tables - var t = (d[sx] * 0x101) ^ (sx * 0x1010100); - SUB_MIX_0[x] = (t << 24) | (t >>> 8); - SUB_MIX_1[x] = (t << 16) | (t >>> 16); - SUB_MIX_2[x] = (t << 8) | (t >>> 24); - SUB_MIX_3[x] = t; - - // Compute inv sub bytes, inv mix columns tables - var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); - INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8); - INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16); - INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24); - INV_SUB_MIX_3[sx] = t; - - // Compute next counter - if (!x) { - x = xi = 1; - } else { - x = x2 ^ d[d[d[x8 ^ x2]]]; - xi ^= d[d[xi]]; - } - } - }()); - - // Precomputed Rcon lookup - var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; - - /** - * AES block cipher algorithm. - */ - var AES = C_algo.AES = BlockCipher.extend({ - _doReset: function () { - // Skip reset of nRounds has been set before and key did not change - if (this._nRounds && this._keyPriorReset === this._key) { - return; - } - - // Shortcuts - var key = this._keyPriorReset = this._key; - var keyWords = key.words; - var keySize = key.sigBytes / 4; - - // Compute number of rounds - var nRounds = this._nRounds = keySize + 6; - - // Compute number of key schedule rows - var ksRows = (nRounds + 1) * 4; - - // Compute key schedule - var keySchedule = this._keySchedule = []; - for (var ksRow = 0; ksRow < ksRows; ksRow++) { - if (ksRow < keySize) { - keySchedule[ksRow] = keyWords[ksRow]; - } else { - var t = keySchedule[ksRow - 1]; - - if (!(ksRow % keySize)) { - // Rot word - t = (t << 8) | (t >>> 24); - - // Sub word - t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; - - // Mix Rcon - t ^= RCON[(ksRow / keySize) | 0] << 24; - } else if (keySize > 6 && ksRow % keySize == 4) { - // Sub word - t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff]; - } - - keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t; - } - } - - // Compute inv key schedule - var invKeySchedule = this._invKeySchedule = []; - for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) { - var ksRow = ksRows - invKsRow; - - if (invKsRow % 4) { - var t = keySchedule[ksRow]; - } else { - var t = keySchedule[ksRow - 4]; - } - - if (invKsRow < 4 || ksRow <= 4) { - invKeySchedule[invKsRow] = t; - } else { - invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^ - INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]]; - } - } - }, - - encryptBlock: function (M, offset) { - this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX); - }, - - decryptBlock: function (M, offset) { - // Swap 2nd and 4th rows - var t = M[offset + 1]; - M[offset + 1] = M[offset + 3]; - M[offset + 3] = t; - - this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX); - - // Inv swap 2nd and 4th rows - var t = M[offset + 1]; - M[offset + 1] = M[offset + 3]; - M[offset + 3] = t; - }, - - _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) { - // Shortcut - var nRounds = this._nRounds; - - // Get input, add round key - var s0 = M[offset] ^ keySchedule[0]; - var s1 = M[offset + 1] ^ keySchedule[1]; - var s2 = M[offset + 2] ^ keySchedule[2]; - var s3 = M[offset + 3] ^ keySchedule[3]; - - // Key schedule row counter - var ksRow = 4; - - // Rounds - for (var round = 1; round < nRounds; round++) { - // Shift rows, sub bytes, mix columns, add round key - var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++]; - var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++]; - var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++]; - var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++]; - - // Update state - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - } - - // Shift rows, sub bytes, add round key - var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; - var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; - var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; - var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; - - // Set output - M[offset] = t0; - M[offset + 1] = t1; - M[offset + 2] = t2; - M[offset + 3] = t3; - }, - - keySize: 256/32 - }); - - /** - * Shortcut functions to the cipher's object interface. - * - * @example - * - * var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); - * var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); - */ - C.AES = BlockCipher._createHelper(AES); - }()); - - - return CryptoJS.AES; - -})); -},{"./cipher-core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/cipher-core.js","./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js","./enc-base64":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-base64.js","./evpkdf":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/evpkdf.js","./md5":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/md5.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/cipher-core.js":[function(require,module,exports){ -;(function (root, factory, undef) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core"), require("./evpkdf")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core", "./evpkdf"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - /** - * Cipher core components. - */ - CryptoJS.lib.Cipher || (function (undefined) { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Base = C_lib.Base; - var WordArray = C_lib.WordArray; - var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm; - var C_enc = C.enc; - var Utf8 = C_enc.Utf8; - var Base64 = C_enc.Base64; - var C_algo = C.algo; - var EvpKDF = C_algo.EvpKDF; - - /** - * Abstract base cipher template. - * - * @property {number} keySize This cipher's key size. Default: 4 (128 bits) - * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits) - * @property {number} _ENC_XFORM_MODE A constant representing encryption mode. - * @property {number} _DEC_XFORM_MODE A constant representing decryption mode. - */ - var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({ - /** - * Configuration options. - * - * @property {WordArray} iv The IV to use for this operation. - */ - cfg: Base.extend(), - - /** - * Creates this cipher in encryption mode. - * - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {Cipher} A cipher instance. - * - * @static - * - * @example - * - * var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray }); - */ - createEncryptor: function (key, cfg) { - return this.create(this._ENC_XFORM_MODE, key, cfg); - }, - - /** - * Creates this cipher in decryption mode. - * - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {Cipher} A cipher instance. - * - * @static - * - * @example - * - * var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray }); - */ - createDecryptor: function (key, cfg) { - return this.create(this._DEC_XFORM_MODE, key, cfg); - }, - - /** - * Initializes a newly created cipher. - * - * @param {number} xformMode Either the encryption or decryption transormation mode constant. - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @example - * - * var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray }); - */ - init: function (xformMode, key, cfg) { - // Apply config defaults - this.cfg = this.cfg.extend(cfg); - - // Store transform mode and key - this._xformMode = xformMode; - this._key = key; - - // Set initial values - this.reset(); - }, - - /** - * Resets this cipher to its initial state. - * - * @example - * - * cipher.reset(); - */ - reset: function () { - // Reset data buffer - BufferedBlockAlgorithm.reset.call(this); - - // Perform concrete-cipher logic - this._doReset(); - }, - - /** - * Adds data to be encrypted or decrypted. - * - * @param {WordArray|string} dataUpdate The data to encrypt or decrypt. - * - * @return {WordArray} The data after processing. - * - * @example - * - * var encrypted = cipher.process('data'); - * var encrypted = cipher.process(wordArray); - */ - process: function (dataUpdate) { - // Append - this._append(dataUpdate); - - // Process available blocks - return this._process(); - }, - - /** - * Finalizes the encryption or decryption process. - * Note that the finalize operation is effectively a destructive, read-once operation. - * - * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt. - * - * @return {WordArray} The data after final processing. - * - * @example - * - * var encrypted = cipher.finalize(); - * var encrypted = cipher.finalize('data'); - * var encrypted = cipher.finalize(wordArray); - */ - finalize: function (dataUpdate) { - // Final data update - if (dataUpdate) { - this._append(dataUpdate); - } - - // Perform concrete-cipher logic - var finalProcessedData = this._doFinalize(); - - return finalProcessedData; - }, - - keySize: 128/32, - - ivSize: 128/32, - - _ENC_XFORM_MODE: 1, - - _DEC_XFORM_MODE: 2, - - /** - * Creates shortcut functions to a cipher's object interface. - * - * @param {Cipher} cipher The cipher to create a helper for. - * - * @return {Object} An object with encrypt and decrypt shortcut functions. - * - * @static - * - * @example - * - * var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES); - */ - _createHelper: (function () { - function selectCipherStrategy(key) { - if (typeof key == 'string') { - return PasswordBasedCipher; - } else { - return SerializableCipher; - } - } - - return function (cipher) { - return { - encrypt: function (message, key, cfg) { - return selectCipherStrategy(key).encrypt(cipher, message, key, cfg); - }, - - decrypt: function (ciphertext, key, cfg) { - return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg); - } - }; - }; - }()) - }); - - /** - * Abstract base stream cipher template. - * - * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits) - */ - var StreamCipher = C_lib.StreamCipher = Cipher.extend({ - _doFinalize: function () { - // Process partial blocks - var finalProcessedBlocks = this._process(!!'flush'); - - return finalProcessedBlocks; - }, - - blockSize: 1 - }); - - /** - * Mode namespace. - */ - var C_mode = C.mode = {}; - - /** - * Abstract base block cipher mode template. - */ - var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({ - /** - * Creates this mode for encryption. - * - * @param {Cipher} cipher A block cipher instance. - * @param {Array} iv The IV words. - * - * @static - * - * @example - * - * var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words); - */ - createEncryptor: function (cipher, iv) { - return this.Encryptor.create(cipher, iv); - }, - - /** - * Creates this mode for decryption. - * - * @param {Cipher} cipher A block cipher instance. - * @param {Array} iv The IV words. - * - * @static - * - * @example - * - * var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words); - */ - createDecryptor: function (cipher, iv) { - return this.Decryptor.create(cipher, iv); - }, - - /** - * Initializes a newly created mode. - * - * @param {Cipher} cipher A block cipher instance. - * @param {Array} iv The IV words. - * - * @example - * - * var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words); - */ - init: function (cipher, iv) { - this._cipher = cipher; - this._iv = iv; - } - }); - - /** - * Cipher Block Chaining mode. - */ - var CBC = C_mode.CBC = (function () { - /** - * Abstract base CBC mode. - */ - var CBC = BlockCipherMode.extend(); - - /** - * CBC encryptor. - */ - CBC.Encryptor = CBC.extend({ - /** - * Processes the data block at offset. - * - * @param {Array} words The data words to operate on. - * @param {number} offset The offset where the block starts. - * - * @example - * - * mode.processBlock(data.words, offset); - */ - processBlock: function (words, offset) { - // Shortcuts - var cipher = this._cipher; - var blockSize = cipher.blockSize; - - // XOR and encrypt - xorBlock.call(this, words, offset, blockSize); - cipher.encryptBlock(words, offset); - - // Remember this block to use with next block - this._prevBlock = words.slice(offset, offset + blockSize); - } - }); - - /** - * CBC decryptor. - */ - CBC.Decryptor = CBC.extend({ - /** - * Processes the data block at offset. - * - * @param {Array} words The data words to operate on. - * @param {number} offset The offset where the block starts. - * - * @example - * - * mode.processBlock(data.words, offset); - */ - processBlock: function (words, offset) { - // Shortcuts - var cipher = this._cipher; - var blockSize = cipher.blockSize; - - // Remember this block to use with next block - var thisBlock = words.slice(offset, offset + blockSize); - - // Decrypt and XOR - cipher.decryptBlock(words, offset); - xorBlock.call(this, words, offset, blockSize); - - // This block becomes the previous block - this._prevBlock = thisBlock; - } - }); - - function xorBlock(words, offset, blockSize) { - // Shortcut - var iv = this._iv; - - // Choose mixing block - if (iv) { - var block = iv; - - // Remove IV for subsequent blocks - this._iv = undefined; - } else { - var block = this._prevBlock; - } - - // XOR blocks - for (var i = 0; i < blockSize; i++) { - words[offset + i] ^= block[i]; - } - } - - return CBC; - }()); - - /** - * Padding namespace. - */ - var C_pad = C.pad = {}; - - /** - * PKCS #5/7 padding strategy. - */ - var Pkcs7 = C_pad.Pkcs7 = { - /** - * Pads data using the algorithm defined in PKCS #5/7. - * - * @param {WordArray} data The data to pad. - * @param {number} blockSize The multiple that the data should be padded to. - * - * @static - * - * @example - * - * CryptoJS.pad.Pkcs7.pad(wordArray, 4); - */ - pad: function (data, blockSize) { - // Shortcut - var blockSizeBytes = blockSize * 4; - - // Count padding bytes - var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes; - - // Create padding word - var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes; - - // Create padding - var paddingWords = []; - for (var i = 0; i < nPaddingBytes; i += 4) { - paddingWords.push(paddingWord); - } - var padding = WordArray.create(paddingWords, nPaddingBytes); - - // Add padding - data.concat(padding); - }, - - /** - * Unpads data that had been padded using the algorithm defined in PKCS #5/7. - * - * @param {WordArray} data The data to unpad. - * - * @static - * - * @example - * - * CryptoJS.pad.Pkcs7.unpad(wordArray); - */ - unpad: function (data) { - // Get number of padding bytes from last byte - var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff; - - // Remove padding - data.sigBytes -= nPaddingBytes; - } - }; - - /** - * Abstract base block cipher template. - * - * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits) - */ - var BlockCipher = C_lib.BlockCipher = Cipher.extend({ - /** - * Configuration options. - * - * @property {Mode} mode The block mode to use. Default: CBC - * @property {Padding} padding The padding strategy to use. Default: Pkcs7 - */ - cfg: Cipher.cfg.extend({ - mode: CBC, - padding: Pkcs7 - }), - - reset: function () { - // Reset cipher - Cipher.reset.call(this); - - // Shortcuts - var cfg = this.cfg; - var iv = cfg.iv; - var mode = cfg.mode; - - // Reset block mode - if (this._xformMode == this._ENC_XFORM_MODE) { - var modeCreator = mode.createEncryptor; - } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { - var modeCreator = mode.createDecryptor; - // Keep at least one block in the buffer for unpadding - this._minBufferSize = 1; - } - - if (this._mode && this._mode.__creator == modeCreator) { - this._mode.init(this, iv && iv.words); - } else { - this._mode = modeCreator.call(mode, this, iv && iv.words); - this._mode.__creator = modeCreator; - } - }, - - _doProcessBlock: function (words, offset) { - this._mode.processBlock(words, offset); - }, - - _doFinalize: function () { - // Shortcut - var padding = this.cfg.padding; - - // Finalize - if (this._xformMode == this._ENC_XFORM_MODE) { - // Pad data - padding.pad(this._data, this.blockSize); - - // Process final blocks - var finalProcessedBlocks = this._process(!!'flush'); - } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ { - // Process final blocks - var finalProcessedBlocks = this._process(!!'flush'); - - // Unpad data - padding.unpad(finalProcessedBlocks); - } - - return finalProcessedBlocks; - }, - - blockSize: 128/32 - }); - - /** - * A collection of cipher parameters. - * - * @property {WordArray} ciphertext The raw ciphertext. - * @property {WordArray} key The key to this ciphertext. - * @property {WordArray} iv The IV used in the ciphering operation. - * @property {WordArray} salt The salt used with a key derivation function. - * @property {Cipher} algorithm The cipher algorithm. - * @property {Mode} mode The block mode used in the ciphering operation. - * @property {Padding} padding The padding scheme used in the ciphering operation. - * @property {number} blockSize The block size of the cipher. - * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string. - */ - var CipherParams = C_lib.CipherParams = Base.extend({ - /** - * Initializes a newly created cipher params object. - * - * @param {Object} cipherParams An object with any of the possible cipher parameters. - * - * @example - * - * var cipherParams = CryptoJS.lib.CipherParams.create({ - * ciphertext: ciphertextWordArray, - * key: keyWordArray, - * iv: ivWordArray, - * salt: saltWordArray, - * algorithm: CryptoJS.algo.AES, - * mode: CryptoJS.mode.CBC, - * padding: CryptoJS.pad.PKCS7, - * blockSize: 4, - * formatter: CryptoJS.format.OpenSSL - * }); - */ - init: function (cipherParams) { - this.mixIn(cipherParams); - }, - - /** - * Converts this cipher params object to a string. - * - * @param {Format} formatter (Optional) The formatting strategy to use. - * - * @return {string} The stringified cipher params. - * - * @throws Error If neither the formatter nor the default formatter is set. - * - * @example - * - * var string = cipherParams + ''; - * var string = cipherParams.toString(); - * var string = cipherParams.toString(CryptoJS.format.OpenSSL); - */ - toString: function (formatter) { - return (formatter || this.formatter).stringify(this); - } - }); - - /** - * Format namespace. - */ - var C_format = C.format = {}; - - /** - * OpenSSL formatting strategy. - */ - var OpenSSLFormatter = C_format.OpenSSL = { - /** - * Converts a cipher params object to an OpenSSL-compatible string. - * - * @param {CipherParams} cipherParams The cipher params object. - * - * @return {string} The OpenSSL-compatible string. - * - * @static - * - * @example - * - * var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams); - */ - stringify: function (cipherParams) { - // Shortcuts - var ciphertext = cipherParams.ciphertext; - var salt = cipherParams.salt; - - // Format - if (salt) { - var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext); - } else { - var wordArray = ciphertext; - } - - return wordArray.toString(Base64); - }, - - /** - * Converts an OpenSSL-compatible string to a cipher params object. - * - * @param {string} openSSLStr The OpenSSL-compatible string. - * - * @return {CipherParams} The cipher params object. - * - * @static - * - * @example - * - * var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString); - */ - parse: function (openSSLStr) { - // Parse base64 - var ciphertext = Base64.parse(openSSLStr); - - // Shortcut - var ciphertextWords = ciphertext.words; - - // Test for salt - if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) { - // Extract salt - var salt = WordArray.create(ciphertextWords.slice(2, 4)); - - // Remove salt from ciphertext - ciphertextWords.splice(0, 4); - ciphertext.sigBytes -= 16; - } - - return CipherParams.create({ ciphertext: ciphertext, salt: salt }); - } - }; - - /** - * A cipher wrapper that returns ciphertext as a serializable cipher params object. - */ - var SerializableCipher = C_lib.SerializableCipher = Base.extend({ - /** - * Configuration options. - * - * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL - */ - cfg: Base.extend({ - format: OpenSSLFormatter - }), - - /** - * Encrypts a message. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {WordArray|string} message The message to encrypt. - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {CipherParams} A cipher params object. - * - * @static - * - * @example - * - * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key); - * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv }); - * var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL }); - */ - encrypt: function (cipher, message, key, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Encrypt - var encryptor = cipher.createEncryptor(key, cfg); - var ciphertext = encryptor.finalize(message); - - // Shortcut - var cipherCfg = encryptor.cfg; - - // Create and return serializable cipher params - return CipherParams.create({ - ciphertext: ciphertext, - key: key, - iv: cipherCfg.iv, - algorithm: cipher, - mode: cipherCfg.mode, - padding: cipherCfg.padding, - blockSize: cipher.blockSize, - formatter: cfg.format - }); - }, - - /** - * Decrypts serialized ciphertext. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {CipherParams|string} ciphertext The ciphertext to decrypt. - * @param {WordArray} key The key. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {WordArray} The plaintext. - * - * @static - * - * @example - * - * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL }); - * var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL }); - */ - decrypt: function (cipher, ciphertext, key, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Convert string to CipherParams - ciphertext = this._parse(ciphertext, cfg.format); - - // Decrypt - var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext); - - return plaintext; - }, - - /** - * Converts serialized ciphertext to CipherParams, - * else assumed CipherParams already and returns ciphertext unchanged. - * - * @param {CipherParams|string} ciphertext The ciphertext. - * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext. - * - * @return {CipherParams} The unserialized ciphertext. - * - * @static - * - * @example - * - * var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format); - */ - _parse: function (ciphertext, format) { - if (typeof ciphertext == 'string') { - return format.parse(ciphertext, this); - } else { - return ciphertext; - } - } - }); - - /** - * Key derivation function namespace. - */ - var C_kdf = C.kdf = {}; - - /** - * OpenSSL key derivation function. - */ - var OpenSSLKdf = C_kdf.OpenSSL = { - /** - * Derives a key and IV from a password. - * - * @param {string} password The password to derive from. - * @param {number} keySize The size in words of the key to generate. - * @param {number} ivSize The size in words of the IV to generate. - * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly. - * - * @return {CipherParams} A cipher params object with the key, IV, and salt. - * - * @static - * - * @example - * - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32); - * var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt'); - */ - execute: function (password, keySize, ivSize, salt) { - // Generate random salt - if (!salt) { - salt = WordArray.random(64/8); - } - - // Derive key and IV - var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt); - - // Separate key and IV - var iv = WordArray.create(key.words.slice(keySize), ivSize * 4); - key.sigBytes = keySize * 4; - - // Return params - return CipherParams.create({ key: key, iv: iv, salt: salt }); - } - }; - - /** - * A serializable cipher wrapper that derives the key from a password, - * and returns ciphertext as a serializable cipher params object. - */ - var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({ - /** - * Configuration options. - * - * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL - */ - cfg: SerializableCipher.cfg.extend({ - kdf: OpenSSLKdf - }), - - /** - * Encrypts a message using a password. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {WordArray|string} message The message to encrypt. - * @param {string} password The password. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {CipherParams} A cipher params object. - * - * @static - * - * @example - * - * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password'); - * var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL }); - */ - encrypt: function (cipher, message, password, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Derive key and other params - var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize); - - // Add IV to config - cfg.iv = derivedParams.iv; - - // Encrypt - var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg); - - // Mix in derived params - ciphertext.mixIn(derivedParams); - - return ciphertext; - }, - - /** - * Decrypts serialized ciphertext using a password. - * - * @param {Cipher} cipher The cipher algorithm to use. - * @param {CipherParams|string} ciphertext The ciphertext to decrypt. - * @param {string} password The password. - * @param {Object} cfg (Optional) The configuration options to use for this operation. - * - * @return {WordArray} The plaintext. - * - * @static - * - * @example - * - * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL }); - * var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL }); - */ - decrypt: function (cipher, ciphertext, password, cfg) { - // Apply config defaults - cfg = this.cfg.extend(cfg); - - // Convert string to CipherParams - ciphertext = this._parse(ciphertext, cfg.format); - - // Derive key and other params - var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt); - - // Add IV to config - cfg.iv = derivedParams.iv; - - // Decrypt - var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg); - - return plaintext; - } - }); - }()); - - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js","./evpkdf":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/evpkdf.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js":[function(require,module,exports){ -;(function (root, factory) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(); - } - else if (typeof define === "function" && define.amd) { - // AMD - define([], factory); - } - else { - // Global (browser) - root.CryptoJS = factory(); - } -}(this, function () { - - /** - * CryptoJS core components. - */ - var CryptoJS = CryptoJS || (function (Math, undefined) { - /* - * Local polyfil of Object.create - */ - var create = Object.create || (function () { - function F() {}; - - return function (obj) { - var subtype; - - F.prototype = obj; - - subtype = new F(); - - F.prototype = null; - - return subtype; - }; - }()) - - /** - * CryptoJS namespace. - */ - var C = {}; - - /** - * Library namespace. - */ - var C_lib = C.lib = {}; - - /** - * Base object for prototypal inheritance. - */ - var Base = C_lib.Base = (function () { - - - return { - /** - * Creates a new object that inherits from this object. - * - * @param {Object} overrides Properties to copy into the new object. - * - * @return {Object} The new object. - * - * @static - * - * @example - * - * var MyType = CryptoJS.lib.Base.extend({ - * field: 'value', - * - * method: function () { - * } - * }); - */ - extend: function (overrides) { - // Spawn - var subtype = create(this); - - // Augment - if (overrides) { - subtype.mixIn(overrides); - } - - // Create default initializer - if (!subtype.hasOwnProperty('init') || this.init === subtype.init) { - subtype.init = function () { - subtype.$super.init.apply(this, arguments); - }; - } - - // Initializer's prototype is the subtype object - subtype.init.prototype = subtype; - - // Reference supertype - subtype.$super = this; - - return subtype; - }, - - /** - * Extends this object and runs the init method. - * Arguments to create() will be passed to init(). - * - * @return {Object} The new object. - * - * @static - * - * @example - * - * var instance = MyType.create(); - */ - create: function () { - var instance = this.extend(); - instance.init.apply(instance, arguments); - - return instance; - }, - - /** - * Initializes a newly created object. - * Override this method to add some logic when your objects are created. - * - * @example - * - * var MyType = CryptoJS.lib.Base.extend({ - * init: function () { - * // ... - * } - * }); - */ - init: function () { - }, - - /** - * Copies properties into this object. - * - * @param {Object} properties The properties to mix in. - * - * @example - * - * MyType.mixIn({ - * field: 'value' - * }); - */ - mixIn: function (properties) { - for (var propertyName in properties) { - if (properties.hasOwnProperty(propertyName)) { - this[propertyName] = properties[propertyName]; - } - } - - // IE won't copy toString using the loop above - if (properties.hasOwnProperty('toString')) { - this.toString = properties.toString; - } - }, - - /** - * Creates a copy of this object. - * - * @return {Object} The clone. - * - * @example - * - * var clone = instance.clone(); - */ - clone: function () { - return this.init.prototype.extend(this); - } - }; - }()); - - /** - * An array of 32-bit words. - * - * @property {Array} words The array of 32-bit words. - * @property {number} sigBytes The number of significant bytes in this word array. - */ - var WordArray = C_lib.WordArray = Base.extend({ - /** - * Initializes a newly created word array. - * - * @param {Array} words (Optional) An array of 32-bit words. - * @param {number} sigBytes (Optional) The number of significant bytes in the words. - * - * @example - * - * var wordArray = CryptoJS.lib.WordArray.create(); - * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]); - * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6); - */ - init: function (words, sigBytes) { - words = this.words = words || []; - - if (sigBytes != undefined) { - this.sigBytes = sigBytes; - } else { - this.sigBytes = words.length * 4; - } - }, - - /** - * Converts this word array to a string. - * - * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex - * - * @return {string} The stringified word array. - * - * @example - * - * var string = wordArray + ''; - * var string = wordArray.toString(); - * var string = wordArray.toString(CryptoJS.enc.Utf8); - */ - toString: function (encoder) { - return (encoder || Hex).stringify(this); - }, - - /** - * Concatenates a word array to this word array. - * - * @param {WordArray} wordArray The word array to append. - * - * @return {WordArray} This word array. - * - * @example - * - * wordArray1.concat(wordArray2); - */ - concat: function (wordArray) { - // Shortcuts - var thisWords = this.words; - var thatWords = wordArray.words; - var thisSigBytes = this.sigBytes; - var thatSigBytes = wordArray.sigBytes; - - // Clamp excess bits - this.clamp(); - - // Concat - if (thisSigBytes % 4) { - // Copy one byte at a time - for (var i = 0; i < thatSigBytes; i++) { - var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8); - } - } else { - // Copy one word at a time - for (var i = 0; i < thatSigBytes; i += 4) { - thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2]; - } - } - this.sigBytes += thatSigBytes; - - // Chainable - return this; - }, - - /** - * Removes insignificant bits. - * - * @example - * - * wordArray.clamp(); - */ - clamp: function () { - // Shortcuts - var words = this.words; - var sigBytes = this.sigBytes; - - // Clamp - words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8); - words.length = Math.ceil(sigBytes / 4); - }, - - /** - * Creates a copy of this word array. - * - * @return {WordArray} The clone. - * - * @example - * - * var clone = wordArray.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - clone.words = this.words.slice(0); - - return clone; - }, - - /** - * Creates a word array filled with random bytes. - * - * @param {number} nBytes The number of random bytes to generate. - * - * @return {WordArray} The random word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.lib.WordArray.random(16); - */ - random: function (nBytes) { - var words = []; - - var r = (function (m_w) { - var m_w = m_w; - var m_z = 0x3ade68b1; - var mask = 0xffffffff; - - return function () { - m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask; - m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask; - var result = ((m_z << 0x10) + m_w) & mask; - result /= 0x100000000; - result += 0.5; - return result * (Math.random() > .5 ? 1 : -1); - } - }); - - for (var i = 0, rcache; i < nBytes; i += 4) { - var _r = r((rcache || Math.random()) * 0x100000000); - - rcache = _r() * 0x3ade67b7; - words.push((_r() * 0x100000000) | 0); - } - - return new WordArray.init(words, nBytes); - } - }); - - /** - * Encoder namespace. - */ - var C_enc = C.enc = {}; - - /** - * Hex encoding strategy. - */ - var Hex = C_enc.Hex = { - /** - * Converts a word array to a hex string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The hex string. - * - * @static - * - * @example - * - * var hexString = CryptoJS.enc.Hex.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - - // Convert - var hexChars = []; - for (var i = 0; i < sigBytes; i++) { - var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - hexChars.push((bite >>> 4).toString(16)); - hexChars.push((bite & 0x0f).toString(16)); - } - - return hexChars.join(''); - }, - - /** - * Converts a hex string to a word array. - * - * @param {string} hexStr The hex string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Hex.parse(hexString); - */ - parse: function (hexStr) { - // Shortcut - var hexStrLength = hexStr.length; - - // Convert - var words = []; - for (var i = 0; i < hexStrLength; i += 2) { - words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4); - } - - return new WordArray.init(words, hexStrLength / 2); - } - }; - - /** - * Latin1 encoding strategy. - */ - var Latin1 = C_enc.Latin1 = { - /** - * Converts a word array to a Latin1 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The Latin1 string. - * - * @static - * - * @example - * - * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - - // Convert - var latin1Chars = []; - for (var i = 0; i < sigBytes; i++) { - var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - latin1Chars.push(String.fromCharCode(bite)); - } - - return latin1Chars.join(''); - }, - - /** - * Converts a Latin1 string to a word array. - * - * @param {string} latin1Str The Latin1 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Latin1.parse(latin1String); - */ - parse: function (latin1Str) { - // Shortcut - var latin1StrLength = latin1Str.length; - - // Convert - var words = []; - for (var i = 0; i < latin1StrLength; i++) { - words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8); - } - - return new WordArray.init(words, latin1StrLength); - } - }; - - /** - * UTF-8 encoding strategy. - */ - var Utf8 = C_enc.Utf8 = { - /** - * Converts a word array to a UTF-8 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The UTF-8 string. - * - * @static - * - * @example - * - * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray); - */ - stringify: function (wordArray) { - try { - return decodeURIComponent(escape(Latin1.stringify(wordArray))); - } catch (e) { - throw new Error('Malformed UTF-8 data'); - } - }, - - /** - * Converts a UTF-8 string to a word array. - * - * @param {string} utf8Str The UTF-8 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Utf8.parse(utf8String); - */ - parse: function (utf8Str) { - return Latin1.parse(unescape(encodeURIComponent(utf8Str))); - } - }; - - /** - * Abstract buffered block algorithm template. - * - * The property blockSize must be implemented in a concrete subtype. - * - * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0 - */ - var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({ - /** - * Resets this block algorithm's data buffer to its initial state. - * - * @example - * - * bufferedBlockAlgorithm.reset(); - */ - reset: function () { - // Initial values - this._data = new WordArray.init(); - this._nDataBytes = 0; - }, - - /** - * Adds new data to this block algorithm's buffer. - * - * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8. - * - * @example - * - * bufferedBlockAlgorithm._append('data'); - * bufferedBlockAlgorithm._append(wordArray); - */ - _append: function (data) { - // Convert string to WordArray, else assume WordArray already - if (typeof data == 'string') { - data = Utf8.parse(data); - } - - // Append - this._data.concat(data); - this._nDataBytes += data.sigBytes; - }, - - /** - * Processes available data blocks. - * - * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype. - * - * @param {boolean} doFlush Whether all blocks and partial blocks should be processed. - * - * @return {WordArray} The processed data. - * - * @example - * - * var processedData = bufferedBlockAlgorithm._process(); - * var processedData = bufferedBlockAlgorithm._process(!!'flush'); - */ - _process: function (doFlush) { - // Shortcuts - var data = this._data; - var dataWords = data.words; - var dataSigBytes = data.sigBytes; - var blockSize = this.blockSize; - var blockSizeBytes = blockSize * 4; - - // Count blocks ready - var nBlocksReady = dataSigBytes / blockSizeBytes; - if (doFlush) { - // Round up to include partial blocks - nBlocksReady = Math.ceil(nBlocksReady); - } else { - // Round down to include only full blocks, - // less the number of blocks that must remain in the buffer - nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0); - } - - // Count words ready - var nWordsReady = nBlocksReady * blockSize; - - // Count bytes ready - var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes); - - // Process blocks - if (nWordsReady) { - for (var offset = 0; offset < nWordsReady; offset += blockSize) { - // Perform concrete-algorithm logic - this._doProcessBlock(dataWords, offset); - } - - // Remove processed words - var processedWords = dataWords.splice(0, nWordsReady); - data.sigBytes -= nBytesReady; - } - - // Return processed words - return new WordArray.init(processedWords, nBytesReady); - }, - - /** - * Creates a copy of this object. - * - * @return {Object} The clone. - * - * @example - * - * var clone = bufferedBlockAlgorithm.clone(); - */ - clone: function () { - var clone = Base.clone.call(this); - clone._data = this._data.clone(); - - return clone; - }, - - _minBufferSize: 0 - }); - - /** - * Abstract hasher template. - * - * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits) - */ - var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({ - /** - * Configuration options. - */ - cfg: Base.extend(), - - /** - * Initializes a newly created hasher. - * - * @param {Object} cfg (Optional) The configuration options to use for this hash computation. - * - * @example - * - * var hasher = CryptoJS.algo.SHA256.create(); - */ - init: function (cfg) { - // Apply config defaults - this.cfg = this.cfg.extend(cfg); - - // Set initial values - this.reset(); - }, - - /** - * Resets this hasher to its initial state. - * - * @example - * - * hasher.reset(); - */ - reset: function () { - // Reset data buffer - BufferedBlockAlgorithm.reset.call(this); - - // Perform concrete-hasher logic - this._doReset(); - }, - - /** - * Updates this hasher with a message. - * - * @param {WordArray|string} messageUpdate The message to append. - * - * @return {Hasher} This hasher. - * - * @example - * - * hasher.update('message'); - * hasher.update(wordArray); - */ - update: function (messageUpdate) { - // Append - this._append(messageUpdate); - - // Update the hash - this._process(); - - // Chainable - return this; - }, - - /** - * Finalizes the hash computation. - * Note that the finalize operation is effectively a destructive, read-once operation. - * - * @param {WordArray|string} messageUpdate (Optional) A final message update. - * - * @return {WordArray} The hash. - * - * @example - * - * var hash = hasher.finalize(); - * var hash = hasher.finalize('message'); - * var hash = hasher.finalize(wordArray); - */ - finalize: function (messageUpdate) { - // Final message update - if (messageUpdate) { - this._append(messageUpdate); - } - - // Perform concrete-hasher logic - var hash = this._doFinalize(); - - return hash; - }, - - blockSize: 512/32, - - /** - * Creates a shortcut function to a hasher's object interface. - * - * @param {Hasher} hasher The hasher to create a helper for. - * - * @return {Function} The shortcut function. - * - * @static - * - * @example - * - * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256); - */ - _createHelper: function (hasher) { - return function (message, cfg) { - return new hasher.init(cfg).finalize(message); - }; - }, - - /** - * Creates a shortcut function to the HMAC's object interface. - * - * @param {Hasher} hasher The hasher to use in this HMAC helper. - * - * @return {Function} The shortcut function. - * - * @static - * - * @example - * - * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256); - */ - _createHmacHelper: function (hasher) { - return function (message, key) { - return new C_algo.HMAC.init(hasher, key).finalize(message); - }; - } - }); - - /** - * Algorithm namespace. - */ - var C_algo = C.algo = {}; - - return C; - }(Math)); - - - return CryptoJS; - -})); -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-base64.js":[function(require,module,exports){ -;(function (root, factory) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var C_enc = C.enc; - - /** - * Base64 encoding strategy. - */ - var Base64 = C_enc.Base64 = { - /** - * Converts a word array to a Base64 string. - * - * @param {WordArray} wordArray The word array. - * - * @return {string} The Base64 string. - * - * @static - * - * @example - * - * var base64String = CryptoJS.enc.Base64.stringify(wordArray); - */ - stringify: function (wordArray) { - // Shortcuts - var words = wordArray.words; - var sigBytes = wordArray.sigBytes; - var map = this._map; - - // Clamp excess bits - wordArray.clamp(); - - // Convert - var base64Chars = []; - for (var i = 0; i < sigBytes; i += 3) { - var byte1 = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff; - var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff; - var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff; - - var triplet = (byte1 << 16) | (byte2 << 8) | byte3; - - for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) { - base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f)); - } - } - - // Add padding - var paddingChar = map.charAt(64); - if (paddingChar) { - while (base64Chars.length % 4) { - base64Chars.push(paddingChar); - } - } - - return base64Chars.join(''); - }, - - /** - * Converts a Base64 string to a word array. - * - * @param {string} base64Str The Base64 string. - * - * @return {WordArray} The word array. - * - * @static - * - * @example - * - * var wordArray = CryptoJS.enc.Base64.parse(base64String); - */ - parse: function (base64Str) { - // Shortcuts - var base64StrLength = base64Str.length; - var map = this._map; - var reverseMap = this._reverseMap; - - if (!reverseMap) { - reverseMap = this._reverseMap = []; - for (var j = 0; j < map.length; j++) { - reverseMap[map.charCodeAt(j)] = j; - } - } - - // Ignore padding - var paddingChar = map.charAt(64); - if (paddingChar) { - var paddingIndex = base64Str.indexOf(paddingChar); - if (paddingIndex !== -1) { - base64StrLength = paddingIndex; - } - } - - // Convert - return parseLoop(base64Str, base64StrLength, reverseMap); - - }, - - _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' - }; - - function parseLoop(base64Str, base64StrLength, reverseMap) { - var words = []; - var nBytes = 0; - for (var i = 0; i < base64StrLength; i++) { - if (i % 4) { - var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2); - var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2); - words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8); - nBytes++; - } - } - return WordArray.create(words, nBytes); - } - }()); - - - return CryptoJS.enc.Base64; - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-hex.js":[function(require,module,exports){ -;(function (root, factory) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - return CryptoJS.enc.Hex; - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/evpkdf.js":[function(require,module,exports){ -;(function (root, factory, undef) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core", "./sha1", "./hmac"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Base = C_lib.Base; - var WordArray = C_lib.WordArray; - var C_algo = C.algo; - var MD5 = C_algo.MD5; - - /** - * This key derivation function is meant to conform with EVP_BytesToKey. - * www.openssl.org/docs/crypto/EVP_BytesToKey.html - */ - var EvpKDF = C_algo.EvpKDF = Base.extend({ - /** - * Configuration options. - * - * @property {number} keySize The key size in words to generate. Default: 4 (128 bits) - * @property {Hasher} hasher The hash algorithm to use. Default: MD5 - * @property {number} iterations The number of iterations to perform. Default: 1 - */ - cfg: Base.extend({ - keySize: 128/32, - hasher: MD5, - iterations: 1 - }), - - /** - * Initializes a newly created key derivation function. - * - * @param {Object} cfg (Optional) The configuration options to use for the derivation. - * - * @example - * - * var kdf = CryptoJS.algo.EvpKDF.create(); - * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 }); - * var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 }); - */ - init: function (cfg) { - this.cfg = this.cfg.extend(cfg); - }, - - /** - * Derives a key from a password. - * - * @param {WordArray|string} password The password. - * @param {WordArray|string} salt A salt. - * - * @return {WordArray} The derived key. - * - * @example - * - * var key = kdf.compute(password, salt); - */ - compute: function (password, salt) { - // Shortcut - var cfg = this.cfg; - - // Init hasher - var hasher = cfg.hasher.create(); - - // Initial values - var derivedKey = WordArray.create(); - - // Shortcuts - var derivedKeyWords = derivedKey.words; - var keySize = cfg.keySize; - var iterations = cfg.iterations; - - // Generate key - while (derivedKeyWords.length < keySize) { - if (block) { - hasher.update(block); - } - var block = hasher.update(password).finalize(salt); - hasher.reset(); - - // Iterations - for (var i = 1; i < iterations; i++) { - block = hasher.finalize(block); - hasher.reset(); - } - - derivedKey.concat(block); - } - derivedKey.sigBytes = keySize * 4; - - return derivedKey; - } - }); - - /** - * Derives a key from a password. - * - * @param {WordArray|string} password The password. - * @param {WordArray|string} salt A salt. - * @param {Object} cfg (Optional) The configuration options to use for this computation. - * - * @return {WordArray} The derived key. - * - * @static - * - * @example - * - * var key = CryptoJS.EvpKDF(password, salt); - * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 }); - * var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 }); - */ - C.EvpKDF = function (password, salt, cfg) { - return EvpKDF.create(cfg).compute(password, salt); - }; - }()); - - - return CryptoJS.EvpKDF; - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js","./hmac":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/hmac.js","./sha1":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/sha1.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/hmac.js":[function(require,module,exports){ -;(function (root, factory) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var Base = C_lib.Base; - var C_enc = C.enc; - var Utf8 = C_enc.Utf8; - var C_algo = C.algo; - - /** - * HMAC algorithm. - */ - var HMAC = C_algo.HMAC = Base.extend({ - /** - * Initializes a newly created HMAC. - * - * @param {Hasher} hasher The hash algorithm to use. - * @param {WordArray|string} key The secret key. - * - * @example - * - * var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key); - */ - init: function (hasher, key) { - // Init hasher - hasher = this._hasher = new hasher.init(); - - // Convert string to WordArray, else assume WordArray already - if (typeof key == 'string') { - key = Utf8.parse(key); - } - - // Shortcuts - var hasherBlockSize = hasher.blockSize; - var hasherBlockSizeBytes = hasherBlockSize * 4; - - // Allow arbitrary length keys - if (key.sigBytes > hasherBlockSizeBytes) { - key = hasher.finalize(key); - } - - // Clamp excess bits - key.clamp(); - - // Clone key for inner and outer pads - var oKey = this._oKey = key.clone(); - var iKey = this._iKey = key.clone(); - - // Shortcuts - var oKeyWords = oKey.words; - var iKeyWords = iKey.words; - - // XOR keys with pad constants - for (var i = 0; i < hasherBlockSize; i++) { - oKeyWords[i] ^= 0x5c5c5c5c; - iKeyWords[i] ^= 0x36363636; - } - oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes; - - // Set initial values - this.reset(); - }, - - /** - * Resets this HMAC to its initial state. - * - * @example - * - * hmacHasher.reset(); - */ - reset: function () { - // Shortcut - var hasher = this._hasher; - - // Reset - hasher.reset(); - hasher.update(this._iKey); - }, - - /** - * Updates this HMAC with a message. - * - * @param {WordArray|string} messageUpdate The message to append. - * - * @return {HMAC} This HMAC instance. - * - * @example - * - * hmacHasher.update('message'); - * hmacHasher.update(wordArray); - */ - update: function (messageUpdate) { - this._hasher.update(messageUpdate); - - // Chainable - return this; - }, - - /** - * Finalizes the HMAC computation. - * Note that the finalize operation is effectively a destructive, read-once operation. - * - * @param {WordArray|string} messageUpdate (Optional) A final message update. - * - * @return {WordArray} The HMAC. - * - * @example - * - * var hmac = hmacHasher.finalize(); - * var hmac = hmacHasher.finalize('message'); - * var hmac = hmacHasher.finalize(wordArray); - */ - finalize: function (messageUpdate) { - // Shortcut - var hasher = this._hasher; - - // Compute HMAC - var innerHash = hasher.finalize(messageUpdate); - hasher.reset(); - var hmac = hasher.finalize(this._oKey.clone().concat(innerHash)); - - return hmac; - } - }); - }()); - - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/md5.js":[function(require,module,exports){ -;(function (root, factory) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - (function (Math) { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var Hasher = C_lib.Hasher; - var C_algo = C.algo; - - // Constants table - var T = []; - - // Compute constants - (function () { - for (var i = 0; i < 64; i++) { - T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0; - } - }()); - - /** - * MD5 hash algorithm. - */ - var MD5 = C_algo.MD5 = Hasher.extend({ - _doReset: function () { - this._hash = new WordArray.init([ - 0x67452301, 0xefcdab89, - 0x98badcfe, 0x10325476 - ]); - }, - - _doProcessBlock: function (M, offset) { - // Swap endian - for (var i = 0; i < 16; i++) { - // Shortcuts - var offset_i = offset + i; - var M_offset_i = M[offset_i]; - - M[offset_i] = ( - (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | - (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) - ); - } - - // Shortcuts - var H = this._hash.words; - - var M_offset_0 = M[offset + 0]; - var M_offset_1 = M[offset + 1]; - var M_offset_2 = M[offset + 2]; - var M_offset_3 = M[offset + 3]; - var M_offset_4 = M[offset + 4]; - var M_offset_5 = M[offset + 5]; - var M_offset_6 = M[offset + 6]; - var M_offset_7 = M[offset + 7]; - var M_offset_8 = M[offset + 8]; - var M_offset_9 = M[offset + 9]; - var M_offset_10 = M[offset + 10]; - var M_offset_11 = M[offset + 11]; - var M_offset_12 = M[offset + 12]; - var M_offset_13 = M[offset + 13]; - var M_offset_14 = M[offset + 14]; - var M_offset_15 = M[offset + 15]; - - // Working varialbes - var a = H[0]; - var b = H[1]; - var c = H[2]; - var d = H[3]; - - // Computation - a = FF(a, b, c, d, M_offset_0, 7, T[0]); - d = FF(d, a, b, c, M_offset_1, 12, T[1]); - c = FF(c, d, a, b, M_offset_2, 17, T[2]); - b = FF(b, c, d, a, M_offset_3, 22, T[3]); - a = FF(a, b, c, d, M_offset_4, 7, T[4]); - d = FF(d, a, b, c, M_offset_5, 12, T[5]); - c = FF(c, d, a, b, M_offset_6, 17, T[6]); - b = FF(b, c, d, a, M_offset_7, 22, T[7]); - a = FF(a, b, c, d, M_offset_8, 7, T[8]); - d = FF(d, a, b, c, M_offset_9, 12, T[9]); - c = FF(c, d, a, b, M_offset_10, 17, T[10]); - b = FF(b, c, d, a, M_offset_11, 22, T[11]); - a = FF(a, b, c, d, M_offset_12, 7, T[12]); - d = FF(d, a, b, c, M_offset_13, 12, T[13]); - c = FF(c, d, a, b, M_offset_14, 17, T[14]); - b = FF(b, c, d, a, M_offset_15, 22, T[15]); - - a = GG(a, b, c, d, M_offset_1, 5, T[16]); - d = GG(d, a, b, c, M_offset_6, 9, T[17]); - c = GG(c, d, a, b, M_offset_11, 14, T[18]); - b = GG(b, c, d, a, M_offset_0, 20, T[19]); - a = GG(a, b, c, d, M_offset_5, 5, T[20]); - d = GG(d, a, b, c, M_offset_10, 9, T[21]); - c = GG(c, d, a, b, M_offset_15, 14, T[22]); - b = GG(b, c, d, a, M_offset_4, 20, T[23]); - a = GG(a, b, c, d, M_offset_9, 5, T[24]); - d = GG(d, a, b, c, M_offset_14, 9, T[25]); - c = GG(c, d, a, b, M_offset_3, 14, T[26]); - b = GG(b, c, d, a, M_offset_8, 20, T[27]); - a = GG(a, b, c, d, M_offset_13, 5, T[28]); - d = GG(d, a, b, c, M_offset_2, 9, T[29]); - c = GG(c, d, a, b, M_offset_7, 14, T[30]); - b = GG(b, c, d, a, M_offset_12, 20, T[31]); - - a = HH(a, b, c, d, M_offset_5, 4, T[32]); - d = HH(d, a, b, c, M_offset_8, 11, T[33]); - c = HH(c, d, a, b, M_offset_11, 16, T[34]); - b = HH(b, c, d, a, M_offset_14, 23, T[35]); - a = HH(a, b, c, d, M_offset_1, 4, T[36]); - d = HH(d, a, b, c, M_offset_4, 11, T[37]); - c = HH(c, d, a, b, M_offset_7, 16, T[38]); - b = HH(b, c, d, a, M_offset_10, 23, T[39]); - a = HH(a, b, c, d, M_offset_13, 4, T[40]); - d = HH(d, a, b, c, M_offset_0, 11, T[41]); - c = HH(c, d, a, b, M_offset_3, 16, T[42]); - b = HH(b, c, d, a, M_offset_6, 23, T[43]); - a = HH(a, b, c, d, M_offset_9, 4, T[44]); - d = HH(d, a, b, c, M_offset_12, 11, T[45]); - c = HH(c, d, a, b, M_offset_15, 16, T[46]); - b = HH(b, c, d, a, M_offset_2, 23, T[47]); - - a = II(a, b, c, d, M_offset_0, 6, T[48]); - d = II(d, a, b, c, M_offset_7, 10, T[49]); - c = II(c, d, a, b, M_offset_14, 15, T[50]); - b = II(b, c, d, a, M_offset_5, 21, T[51]); - a = II(a, b, c, d, M_offset_12, 6, T[52]); - d = II(d, a, b, c, M_offset_3, 10, T[53]); - c = II(c, d, a, b, M_offset_10, 15, T[54]); - b = II(b, c, d, a, M_offset_1, 21, T[55]); - a = II(a, b, c, d, M_offset_8, 6, T[56]); - d = II(d, a, b, c, M_offset_15, 10, T[57]); - c = II(c, d, a, b, M_offset_6, 15, T[58]); - b = II(b, c, d, a, M_offset_13, 21, T[59]); - a = II(a, b, c, d, M_offset_4, 6, T[60]); - d = II(d, a, b, c, M_offset_11, 10, T[61]); - c = II(c, d, a, b, M_offset_2, 15, T[62]); - b = II(b, c, d, a, M_offset_9, 21, T[63]); - - // Intermediate hash value - H[0] = (H[0] + a) | 0; - H[1] = (H[1] + b) | 0; - H[2] = (H[2] + c) | 0; - H[3] = (H[3] + d) | 0; - }, - - _doFinalize: function () { - // Shortcuts - var data = this._data; - var dataWords = data.words; - - var nBitsTotal = this._nDataBytes * 8; - var nBitsLeft = data.sigBytes * 8; - - // Add padding - dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); - - var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000); - var nBitsTotalL = nBitsTotal; - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = ( - (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | - (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00) - ); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( - (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | - (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00) - ); - - data.sigBytes = (dataWords.length + 1) * 4; - - // Hash final blocks - this._process(); - - // Shortcuts - var hash = this._hash; - var H = hash.words; - - // Swap endian - for (var i = 0; i < 4; i++) { - // Shortcut - var H_i = H[i]; - - H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | - (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00); - } - - // Return final computed hash - return hash; - }, - - clone: function () { - var clone = Hasher.clone.call(this); - clone._hash = this._hash.clone(); - - return clone; - } - }); - - function FF(a, b, c, d, x, s, t) { - var n = a + ((b & c) | (~b & d)) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - function GG(a, b, c, d, x, s, t) { - var n = a + ((b & d) | (c & ~d)) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - function HH(a, b, c, d, x, s, t) { - var n = a + (b ^ c ^ d) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - function II(a, b, c, d, x, s, t) { - var n = a + (c ^ (b | ~d)) + x + t; - return ((n << s) | (n >>> (32 - s))) + b; - } - - /** - * Shortcut function to the hasher's object interface. - * - * @param {WordArray|string} message The message to hash. - * - * @return {WordArray} The hash. - * - * @static - * - * @example - * - * var hash = CryptoJS.MD5('message'); - * var hash = CryptoJS.MD5(wordArray); - */ - C.MD5 = Hasher._createHelper(MD5); - - /** - * Shortcut function to the HMAC's object interface. - * - * @param {WordArray|string} message The message to hash. - * @param {WordArray|string} key The secret key. - * - * @return {WordArray} The HMAC. - * - * @static - * - * @example - * - * var hmac = CryptoJS.HmacMD5(message, key); - */ - C.HmacMD5 = Hasher._createHmacHelper(MD5); - }(Math)); - - - return CryptoJS.MD5; - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/sha1.js":[function(require,module,exports){ -;(function (root, factory) { - if (typeof exports === "object") { - // CommonJS - module.exports = exports = factory(require("./core")); - } - else if (typeof define === "function" && define.amd) { - // AMD - define(["./core"], factory); - } - else { - // Global (browser) - factory(root.CryptoJS); - } -}(this, function (CryptoJS) { - - (function () { - // Shortcuts - var C = CryptoJS; - var C_lib = C.lib; - var WordArray = C_lib.WordArray; - var Hasher = C_lib.Hasher; - var C_algo = C.algo; - - // Reusable object - var W = []; - - /** - * SHA-1 hash algorithm. - */ - var SHA1 = C_algo.SHA1 = Hasher.extend({ - _doReset: function () { - this._hash = new WordArray.init([ - 0x67452301, 0xefcdab89, - 0x98badcfe, 0x10325476, - 0xc3d2e1f0 - ]); - }, - - _doProcessBlock: function (M, offset) { - // Shortcut - var H = this._hash.words; - - // Working variables - var a = H[0]; - var b = H[1]; - var c = H[2]; - var d = H[3]; - var e = H[4]; - - // Computation - for (var i = 0; i < 80; i++) { - if (i < 16) { - W[i] = M[offset + i] | 0; - } else { - var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; - W[i] = (n << 1) | (n >>> 31); - } - - var t = ((a << 5) | (a >>> 27)) + e + W[i]; - if (i < 20) { - t += ((b & c) | (~b & d)) + 0x5a827999; - } else if (i < 40) { - t += (b ^ c ^ d) + 0x6ed9eba1; - } else if (i < 60) { - t += ((b & c) | (b & d) | (c & d)) - 0x70e44324; - } else /* if (i < 80) */ { - t += (b ^ c ^ d) - 0x359d3e2a; - } - - e = d; - d = c; - c = (b << 30) | (b >>> 2); - b = a; - a = t; - } - - // Intermediate hash value - H[0] = (H[0] + a) | 0; - H[1] = (H[1] + b) | 0; - H[2] = (H[2] + c) | 0; - H[3] = (H[3] + d) | 0; - H[4] = (H[4] + e) | 0; - }, - - _doFinalize: function () { - // Shortcuts - var data = this._data; - var dataWords = data.words; - - var nBitsTotal = this._nDataBytes * 8; - var nBitsLeft = data.sigBytes * 8; - - // Add padding - dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000); - dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal; - data.sigBytes = dataWords.length * 4; - - // Hash final blocks - this._process(); - - // Return final computed hash - return this._hash; - }, - - clone: function () { - var clone = Hasher.clone.call(this); - clone._hash = this._hash.clone(); - - return clone; - } - }); - - /** - * Shortcut function to the hasher's object interface. - * - * @param {WordArray|string} message The message to hash. - * - * @return {WordArray} The hash. - * - * @static - * - * @example - * - * var hash = CryptoJS.SHA1('message'); - * var hash = CryptoJS.SHA1(wordArray); - */ - C.SHA1 = Hasher._createHelper(SHA1); - - /** - * Shortcut function to the HMAC's object interface. - * - * @param {WordArray|string} message The message to hash. - * @param {WordArray|string} key The secret key. - * - * @return {WordArray} The HMAC. - * - * @static - * - * @example - * - * var hmac = CryptoJS.HmacSHA1(message, key); - */ - C.HmacSHA1 = Hasher._createHmacHelper(SHA1); - }()); - - - return CryptoJS.SHA1; - -})); -},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/index.js":[function(require,module,exports){ -var pSlice = Array.prototype.slice; -var objectKeys = require('./lib/keys.js'); -var isArguments = require('./lib/is_arguments.js'); - -var deepEqual = module.exports = function (actual, expected, opts) { - if (!opts) opts = {}; - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - - } else if (actual instanceof Date && expected instanceof Date) { - return actual.getTime() === expected.getTime(); - - // 7.3. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') { - return opts.strict ? actual === expected : actual == expected; - - // 7.4. For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else { - return objEquiv(actual, expected, opts); - } -} - -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - -function isBuffer (x) { - if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false; - if (typeof x.copy !== 'function' || typeof x.slice !== 'function') { - return false; - } - if (x.length > 0 && typeof x[0] !== 'number') return false; - return true; -} - -function objEquiv(a, b, opts) { - var i, key; - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) - return false; - // an identical 'prototype' property. - if (a.prototype !== b.prototype) return false; - //~~~I've managed to break Object.keys through screwy arguments passing. - // Converting to array solves the problem. - if (isArguments(a)) { - if (!isArguments(b)) { - return false; - } - a = pSlice.call(a); - b = pSlice.call(b); - return deepEqual(a, b, opts); - } - if (isBuffer(a)) { - if (!isBuffer(b)) { - return false; - } - if (a.length !== b.length) return false; - for (i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } - return true; - } - try { - var ka = objectKeys(a), - kb = objectKeys(b); - } catch (e) {//happens when one is a string literal and the other isn't - return false; - } - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length != kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] != kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!deepEqual(a[key], b[key], opts)) return false; - } - return typeof a === typeof b; -} - -},{"./lib/is_arguments.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/lib/is_arguments.js","./lib/keys.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/lib/keys.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/lib/is_arguments.js":[function(require,module,exports){ -var supportsArgumentsClass = (function(){ - return Object.prototype.toString.call(arguments) -})() == '[object Arguments]'; - -exports = module.exports = supportsArgumentsClass ? supported : unsupported; - -exports.supported = supported; -function supported(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -}; - -exports.unsupported = unsupported; -function unsupported(object){ - return object && - typeof object == 'object' && - typeof object.length == 'number' && - Object.prototype.hasOwnProperty.call(object, 'callee') && - !Object.prototype.propertyIsEnumerable.call(object, 'callee') || - false; -}; - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/lib/keys.js":[function(require,module,exports){ -exports = module.exports = typeof Object.keys === 'function' - ? Object.keys : shim; - -exports.shim = shim; -function shim (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/curve.js":[function(require,module,exports){ -var assert = require('assert') -var BigInteger = require('bigi') - -var Point = require('./point') - -function Curve (p, a, b, Gx, Gy, n, h) { - this.p = p - this.a = a - this.b = b - this.G = Point.fromAffine(this, Gx, Gy) - this.n = n - this.h = h - - this.infinity = new Point(this, null, null, BigInteger.ZERO) - - // result caching - this.pOverFour = p.add(BigInteger.ONE).shiftRight(2) - - // determine size of p in bytes - this.pLength = Math.floor((this.p.bitLength() + 7) / 8) -} - -Curve.prototype.pointFromX = function (isOdd, x) { - var alpha = x.pow(3).add(this.a.multiply(x)).add(this.b).mod(this.p) - var beta = alpha.modPow(this.pOverFour, this.p) // XXX: not compatible with all curves - - var y = beta - if (beta.isEven() ^ !isOdd) { - y = this.p.subtract(y) // -y % p - } - - return Point.fromAffine(this, x, y) -} - -Curve.prototype.isInfinity = function (Q) { - if (Q === this.infinity) return true - - return Q.z.signum() === 0 && Q.y.signum() !== 0 -} - -Curve.prototype.isOnCurve = function (Q) { - if (this.isInfinity(Q)) return true - - var x = Q.affineX - var y = Q.affineY - var a = this.a - var b = this.b - var p = this.p - - // Check that xQ and yQ are integers in the interval [0, p - 1] - if (x.signum() < 0 || x.compareTo(p) >= 0) return false - if (y.signum() < 0 || y.compareTo(p) >= 0) return false - - // and check that y^2 = x^3 + ax + b (mod p) - var lhs = y.square().mod(p) - var rhs = x.pow(3).add(a.multiply(x)).add(b).mod(p) - return lhs.equals(rhs) -} - -/** - * Validate an elliptic curve point. - * - * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive - */ -Curve.prototype.validate = function (Q) { - // Check Q != O - assert(!this.isInfinity(Q), 'Point is at infinity') - assert(this.isOnCurve(Q), 'Point is not on the curve') - - // Check nQ = O (where Q is a scalar multiple of G) - var nQ = Q.multiply(this.n) - assert(this.isInfinity(nQ), 'Point is not a scalar multiple of G') - - return true -} - -module.exports = Curve - -},{"./point":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/point.js","assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/curves.json":[function(require,module,exports){ -module.exports={ - "secp128r1": { - "p": "fffffffdffffffffffffffffffffffff", - "a": "fffffffdfffffffffffffffffffffffc", - "b": "e87579c11079f43dd824993c2cee5ed3", - "n": "fffffffe0000000075a30d1b9038a115", - "h": "01", - "Gx": "161ff7528b899b2d0c28607ca52c5b86", - "Gy": "cf5ac8395bafeb13c02da292dded7a83" - }, - "secp160k1": { - "p": "fffffffffffffffffffffffffffffffeffffac73", - "a": "00", - "b": "07", - "n": "0100000000000000000001b8fa16dfab9aca16b6b3", - "h": "01", - "Gx": "3b4c382ce37aa192a4019e763036f4f5dd4d7ebb", - "Gy": "938cf935318fdced6bc28286531733c3f03c4fee" - }, - "secp160r1": { - "p": "ffffffffffffffffffffffffffffffff7fffffff", - "a": "ffffffffffffffffffffffffffffffff7ffffffc", - "b": "1c97befc54bd7a8b65acf89f81d4d4adc565fa45", - "n": "0100000000000000000001f4c8f927aed3ca752257", - "h": "01", - "Gx": "4a96b5688ef573284664698968c38bb913cbfc82", - "Gy": "23a628553168947d59dcc912042351377ac5fb32" - }, - "secp192k1": { - "p": "fffffffffffffffffffffffffffffffffffffffeffffee37", - "a": "00", - "b": "03", - "n": "fffffffffffffffffffffffe26f2fc170f69466a74defd8d", - "h": "01", - "Gx": "db4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d", - "Gy": "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d" - }, - "secp192r1": { - "p": "fffffffffffffffffffffffffffffffeffffffffffffffff", - "a": "fffffffffffffffffffffffffffffffefffffffffffffffc", - "b": "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", - "n": "ffffffffffffffffffffffff99def836146bc9b1b4d22831", - "h": "01", - "Gx": "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "Gy": "07192b95ffc8da78631011ed6b24cdd573f977a11e794811" - }, - "secp256k1": { - "p": "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "a": "00", - "b": "07", - "n": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "h": "01", - "Gx": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", - "Gy": "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" - }, - "secp256r1": { - "p": "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "a": "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", - "b": "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "n": "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - "h": "01", - "Gx": "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "Gy": "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" - } -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/index.js":[function(require,module,exports){ -var Point = require('./point') -var Curve = require('./curve') - -var getCurveByName = require('./names') - -module.exports = { - Curve: Curve, - Point: Point, - getCurveByName: getCurveByName -} - -},{"./curve":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/curve.js","./names":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/names.js","./point":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/point.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/names.js":[function(require,module,exports){ -var BigInteger = require('bigi') - -var curves = require('./curves.json') -var Curve = require('./curve') - -function getCurveByName (name) { - var curve = curves[name] - if (!curve) return null - - var p = new BigInteger(curve.p, 16) - var a = new BigInteger(curve.a, 16) - var b = new BigInteger(curve.b, 16) - var n = new BigInteger(curve.n, 16) - var h = new BigInteger(curve.h, 16) - var Gx = new BigInteger(curve.Gx, 16) - var Gy = new BigInteger(curve.Gy, 16) - - return new Curve(p, a, b, Gx, Gy, n, h) -} - -module.exports = getCurveByName - -},{"./curve":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/curve.js","./curves.json":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/curves.json","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ecurve/lib/point.js":[function(require,module,exports){ -var assert = require('assert') -var Buffer = require('safe-buffer').Buffer -var BigInteger = require('bigi') - -var THREE = BigInteger.valueOf(3) - -function Point (curve, x, y, z) { - assert.notStrictEqual(z, undefined, 'Missing Z coordinate') - - this.curve = curve - this.x = x - this.y = y - this.z = z - this._zInv = null - - this.compressed = true -} - -Object.defineProperty(Point.prototype, 'zInv', { - get: function () { - if (this._zInv === null) { - this._zInv = this.z.modInverse(this.curve.p) - } - - return this._zInv - } -}) - -Object.defineProperty(Point.prototype, 'affineX', { - get: function () { - return this.x.multiply(this.zInv).mod(this.curve.p) - } -}) - -Object.defineProperty(Point.prototype, 'affineY', { - get: function () { - return this.y.multiply(this.zInv).mod(this.curve.p) - } -}) - -Point.fromAffine = function (curve, x, y) { - return new Point(curve, x, y, BigInteger.ONE) -} - -Point.prototype.equals = function (other) { - if (other === this) return true - if (this.curve.isInfinity(this)) return this.curve.isInfinity(other) - if (this.curve.isInfinity(other)) return this.curve.isInfinity(this) - - // u = Y2 * Z1 - Y1 * Z2 - var u = other.y.multiply(this.z).subtract(this.y.multiply(other.z)).mod(this.curve.p) - - if (u.signum() !== 0) return false - - // v = X2 * Z1 - X1 * Z2 - var v = other.x.multiply(this.z).subtract(this.x.multiply(other.z)).mod(this.curve.p) - - return v.signum() === 0 -} - -Point.prototype.negate = function () { - var y = this.curve.p.subtract(this.y) - - return new Point(this.curve, this.x, y, this.z) -} - -Point.prototype.add = function (b) { - if (this.curve.isInfinity(this)) return b - if (this.curve.isInfinity(b)) return this - - var x1 = this.x - var y1 = this.y - var x2 = b.x - var y2 = b.y - - // u = Y2 * Z1 - Y1 * Z2 - var u = y2.multiply(this.z).subtract(y1.multiply(b.z)).mod(this.curve.p) - // v = X2 * Z1 - X1 * Z2 - var v = x2.multiply(this.z).subtract(x1.multiply(b.z)).mod(this.curve.p) - - if (v.signum() === 0) { - if (u.signum() === 0) { - return this.twice() // this == b, so double - } - - return this.curve.infinity // this = -b, so infinity - } - - var v2 = v.square() - var v3 = v2.multiply(v) - var x1v2 = x1.multiply(v2) - var zu2 = u.square().multiply(this.z) - - // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3) - var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.p) - // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3 - var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.p) - // z3 = v^3 * z1 * z2 - var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.p) - - return new Point(this.curve, x3, y3, z3) -} - -Point.prototype.twice = function () { - if (this.curve.isInfinity(this)) return this - if (this.y.signum() === 0) return this.curve.infinity - - var x1 = this.x - var y1 = this.y - - var y1z1 = y1.multiply(this.z).mod(this.curve.p) - var y1sqz1 = y1z1.multiply(y1).mod(this.curve.p) - var a = this.curve.a - - // w = 3 * x1^2 + a * z1^2 - var w = x1.square().multiply(THREE) - - if (a.signum() !== 0) { - w = w.add(this.z.square().multiply(a)) - } - - w = w.mod(this.curve.p) - // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1) - var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.p) - // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3 - var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.pow(3)).mod(this.curve.p) - // z3 = 8 * (y1 * z1)^3 - var z3 = y1z1.pow(3).shiftLeft(3).mod(this.curve.p) - - return new Point(this.curve, x3, y3, z3) -} - -// Simple NAF (Non-Adjacent Form) multiplication algorithm -// TODO: modularize the multiplication algorithm -Point.prototype.multiply = function (k) { - if (this.curve.isInfinity(this)) return this - if (k.signum() === 0) return this.curve.infinity - - var e = k - var h = e.multiply(THREE) - - var neg = this.negate() - var R = this - - for (var i = h.bitLength() - 2; i > 0; --i) { - var hBit = h.testBit(i) - var eBit = e.testBit(i) - - R = R.twice() - - if (hBit !== eBit) { - R = R.add(hBit ? this : neg) - } - } - - return R -} - -// Compute this*j + x*k (simultaneous multiplication) -Point.prototype.multiplyTwo = function (j, x, k) { - var i = Math.max(j.bitLength(), k.bitLength()) - 1 - var R = this.curve.infinity - var both = this.add(x) - - while (i >= 0) { - var jBit = j.testBit(i) - var kBit = k.testBit(i) - - R = R.twice() - - if (jBit) { - if (kBit) { - R = R.add(both) - } else { - R = R.add(this) - } - } else if (kBit) { - R = R.add(x) - } - --i - } - - return R -} - -Point.prototype.getEncoded = function (compressed) { - if (compressed == null) compressed = this.compressed - if (this.curve.isInfinity(this)) return Buffer.alloc(1, 0) // Infinity point encoded is simply '00' - - var x = this.affineX - var y = this.affineY - var byteLength = this.curve.pLength - var buffer - - // 0x02/0x03 | X - if (compressed) { - buffer = Buffer.allocUnsafe(1 + byteLength) - buffer.writeUInt8(y.isEven() ? 0x02 : 0x03, 0) - - // 0x04 | X | Y - } else { - buffer = Buffer.allocUnsafe(1 + byteLength + byteLength) - buffer.writeUInt8(0x04, 0) - - y.toBuffer(byteLength).copy(buffer, 1 + byteLength) - } - - x.toBuffer(byteLength).copy(buffer, 1) - - return buffer -} - -Point.decodeFrom = function (curve, buffer) { - var type = buffer.readUInt8(0) - var compressed = (type !== 4) - - var byteLength = Math.floor((curve.p.bitLength() + 7) / 8) - var x = BigInteger.fromBuffer(buffer.slice(1, 1 + byteLength)) - - var Q - if (compressed) { - assert.equal(buffer.length, byteLength + 1, 'Invalid sequence length') - assert(type === 0x02 || type === 0x03, 'Invalid sequence tag') - - var isOdd = (type === 0x03) - Q = curve.pointFromX(isOdd, x) - } else { - assert.equal(buffer.length, 1 + byteLength + byteLength, 'Invalid sequence length') - - var y = BigInteger.fromBuffer(buffer.slice(1 + byteLength)) - Q = Point.fromAffine(curve, x, y) - } - - Q.compressed = compressed - return Q -} - -Point.prototype.toString = function () { - if (this.curve.isInfinity(this)) return '(INFINITY)' - - return '(' + this.affineX.toString() + ',' + this.affineY.toString() + ')' -} - -module.exports = Point - -},{"assert":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/assert/assert.js","bigi":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/index.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/events/events.js":[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var objectCreate = Object.create || objectCreatePolyfill -var objectKeys = Object.keys || objectKeysPolyfill -var bind = Function.prototype.bind || functionBindPolyfill - -function EventEmitter() { - if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) { - this._events = objectCreate(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -var defaultMaxListeners = 10; - -var hasDefineProperty; -try { - var o = {}; - if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 }); - hasDefineProperty = o.x === 0; -} catch (err) { hasDefineProperty = false } -if (hasDefineProperty) { - Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function() { - return defaultMaxListeners; - }, - set: function(arg) { - // check whether the input is a positive number (whose value is zero or - // greater and not a NaN). - if (typeof arg !== 'number' || arg < 0 || arg !== arg) - throw new TypeError('"defaultMaxListeners" must be a positive number'); - defaultMaxListeners = arg; - } - }); -} else { - EventEmitter.defaultMaxListeners = defaultMaxListeners; -} - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || isNaN(n)) - throw new TypeError('"n" argument must be a positive number'); - this._maxListeners = n; - return this; -}; - -function $getMaxListeners(that) { - if (that._maxListeners === undefined) - return EventEmitter.defaultMaxListeners; - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return $getMaxListeners(this); -}; - -// These standalone emit* functions are used to optimize calling of event -// handlers for fast cases because emit() itself often has a variable number of -// arguments and can be deoptimized because of that. These functions always have -// the same number of arguments and thus do not get deoptimized, so the code -// inside them can execute faster. -function emitNone(handler, isFn, self) { - if (isFn) - handler.call(self); - else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - listeners[i].call(self); - } -} -function emitOne(handler, isFn, self, arg1) { - if (isFn) - handler.call(self, arg1); - else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - listeners[i].call(self, arg1); - } -} -function emitTwo(handler, isFn, self, arg1, arg2) { - if (isFn) - handler.call(self, arg1, arg2); - else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - listeners[i].call(self, arg1, arg2); - } -} -function emitThree(handler, isFn, self, arg1, arg2, arg3) { - if (isFn) - handler.call(self, arg1, arg2, arg3); - else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - listeners[i].call(self, arg1, arg2, arg3); - } -} - -function emitMany(handler, isFn, self, args) { - if (isFn) - handler.apply(self, args); - else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - listeners[i].apply(self, args); - } -} - -EventEmitter.prototype.emit = function emit(type) { - var er, handler, len, args, i, events; - var doError = (type === 'error'); - - events = this._events; - if (events) - doError = (doError && events.error == null); - else if (!doError) - return false; - - // If there is no 'error' event listener then throw. - if (doError) { - if (arguments.length > 1) - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } else { - // At least give some kind of context to the user - var err = new Error('Unhandled "error" event. (' + er + ')'); - err.context = er; - throw err; - } - return false; - } - - handler = events[type]; - - if (!handler) - return false; - - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: - emitNone(handler, isFn, this); - break; - case 2: - emitOne(handler, isFn, this, arguments[1]); - break; - case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); - break; - // slower - default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - emitMany(handler, isFn, this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = target._events; - if (!events) { - events = target._events = objectCreate(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (!existing) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - } else { - // If we've already got an array, just append. - if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - } - - // Check for listener leak - if (!existing.warned) { - m = $getMaxListeners(target); - if (m && m > 0 && existing.length > m) { - existing.warned = true; - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' "' + String(type) + '" listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit.'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - if (typeof console === 'object' && console.warn) { - console.warn('%s: %s', w.name, w.message); - } - } - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - switch (arguments.length) { - case 0: - return this.listener.call(this.target); - case 1: - return this.listener.call(this.target, arguments[0]); - case 2: - return this.listener.call(this.target, arguments[0], arguments[1]); - case 3: - return this.listener.call(this.target, arguments[0], arguments[1], - arguments[2]); - default: - var args = new Array(arguments.length); - for (var i = 0; i < args.length; ++i) - args[i] = arguments[i]; - this.listener.apply(this.target, args); - } - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = bind.call(onceWrapper, state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - if (typeof listener !== 'function') - throw new TypeError('"listener" argument must be a function'); - - events = this._events; - if (!events) - return this; - - list = events[type]; - if (!list) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else - spliceOne(list, position); - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (!events) - return this; - - // not listening for removeListener, no need to emit - if (!events.removeListener) { - if (arguments.length === 0) { - this._events = objectCreate(null); - this._eventsCount = 0; - } else if (events[type]) { - if (--this._eventsCount === 0) - this._events = objectCreate(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = objectKeys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = objectCreate(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -EventEmitter.prototype.listeners = function listeners(type) { - var evlistener; - var ret; - var events = this._events; - - if (!events) - ret = []; - else { - evlistener = events[type]; - if (!evlistener) - ret = []; - else if (typeof evlistener === 'function') - ret = [evlistener.listener || evlistener]; - else - ret = unwrapListeners(evlistener); - } - - return ret; -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; -}; - -// About 1.5x faster than the two-arg version of Array#splice(). -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) - list[i] = list[k]; - list.pop(); -} - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function objectCreatePolyfill(proto) { - var F = function() {}; - F.prototype = proto; - return new F; -} -function objectKeysPolyfill(obj) { - var keys = []; - for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } - return k; -} -function functionBindPolyfill(context) { - var fn = this; - return function () { - return fn.apply(context, arguments); - }; -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/hash-base/index.js":[function(require,module,exports){ -(function (Buffer){ -'use strict' -var Transform = require('stream').Transform -var inherits = require('inherits') - -function HashBase (blockSize) { - Transform.call(this) - - this._block = new Buffer(blockSize) - this._blockSize = blockSize - this._blockOffset = 0 - this._length = [0, 0, 0, 0] - - this._finalized = false -} - -inherits(HashBase, Transform) - -HashBase.prototype._transform = function (chunk, encoding, callback) { - var error = null - try { - if (encoding !== 'buffer') chunk = new Buffer(chunk, encoding) - this.update(chunk) - } catch (err) { - error = err - } - - callback(error) -} - -HashBase.prototype._flush = function (callback) { - var error = null - try { - this.push(this._digest()) - } catch (err) { - error = err - } - - callback(error) -} - -HashBase.prototype.update = function (data, encoding) { - if (!Buffer.isBuffer(data) && typeof data !== 'string') throw new TypeError('Data must be a string or a buffer') - if (this._finalized) throw new Error('Digest already called') - if (!Buffer.isBuffer(data)) data = new Buffer(data, encoding || 'binary') - - // consume data - var block = this._block - var offset = 0 - while (this._blockOffset + data.length - offset >= this._blockSize) { - for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++] - this._update() - this._blockOffset = 0 - } - while (offset < data.length) block[this._blockOffset++] = data[offset++] - - // update length - for (var j = 0, carry = data.length * 8; carry > 0; ++j) { - this._length[j] += carry - carry = (this._length[j] / 0x0100000000) | 0 - if (carry > 0) this._length[j] -= 0x0100000000 * carry - } - - return this -} - -HashBase.prototype._update = function (data) { - throw new Error('_update is not implemented') -} - -HashBase.prototype.digest = function (encoding) { - if (this._finalized) throw new Error('Digest already called') - this._finalized = true - - var digest = this._digest() - if (encoding !== undefined) digest = digest.toString(encoding) - return digest -} - -HashBase.prototype._digest = function () { - throw new Error('_digest is not implemented') -} - -module.exports = HashBase - -}).call(this,require("buffer").Buffer) - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","stream":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/stream-browserify/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ieee754/index.js":[function(require,module,exports){ -exports.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m - var eLen = (nBytes * 8) - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var nBits = -7 - var i = isLE ? (nBytes - 1) : 0 - var d = isLE ? -1 : 1 - var s = buffer[offset + i] - - i += d - - e = s & ((1 << (-nBits)) - 1) - s >>= (-nBits) - nBits += eLen - for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1) - e >>= (-nBits) - nBits += mLen - for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen) - e = e - eBias - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} - -exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c - var eLen = (nBytes * 8) - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) - var i = isLE ? 0 : (nBytes - 1) - var d = isLE ? 1 : -1 - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - - value = Math.abs(value) - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0 - e = eMax - } else { - e = Math.floor(Math.log(value) / Math.LN2) - if (value * (c = Math.pow(2, -e)) < 1) { - e-- - c *= 2 - } - if (e + eBias >= 1) { - value += rt / c - } else { - value += rt * Math.pow(2, 1 - eBias) - } - if (value * c >= 2) { - e++ - c /= 2 - } - - if (e + eBias >= eMax) { - m = 0 - e = eMax - } else if (e + eBias >= 1) { - m = ((value * c) - 1) * Math.pow(2, mLen) - e = e + eBias - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) - e = 0 - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js":[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/is-buffer/index.js":[function(require,module,exports){ -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -module.exports = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -} - -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/isarray/index.js":[function(require,module,exports){ -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/long/dist/long.js":[function(require,module,exports){ -/* - Copyright 2013 Daniel Wirtz - Copyright 2009 The Closure Library Authors. All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS-IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -/** - * @license long.js (c) 2013 Daniel Wirtz - * Released under the Apache License, Version 2.0 - * see: https://github.com/dcodeIO/long.js for details - */ -(function(global, factory) { - - /* AMD */ if (typeof define === 'function' && define["amd"]) - define([], factory); - /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) - module["exports"] = factory(); - /* Global */ else - (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory(); - -})(this, function() { - "use strict"; - - /** - * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers. - * See the from* functions below for more convenient ways of constructing Longs. - * @exports Long - * @class A Long class for representing a 64 bit two's-complement integer value. - * @param {number} low The low (signed) 32 bits of the long - * @param {number} high The high (signed) 32 bits of the long - * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed - * @constructor - */ - function Long(low, high, unsigned) { - - /** - * The low 32 bits as a signed value. - * @type {number} - */ - this.low = low | 0; - - /** - * The high 32 bits as a signed value. - * @type {number} - */ - this.high = high | 0; - - /** - * Whether unsigned or not. - * @type {boolean} - */ - this.unsigned = !!unsigned; - } - - // The internal representation of a long is the two given signed, 32-bit values. - // We use 32-bit pieces because these are the size of integers on which - // Javascript performs bit-operations. For operations like addition and - // multiplication, we split each number into 16 bit pieces, which can easily be - // multiplied within Javascript's floating-point representation without overflow - // or change in sign. - // - // In the algorithms below, we frequently reduce the negative case to the - // positive case by negating the input(s) and then post-processing the result. - // Note that we must ALWAYS check specially whether those values are MIN_VALUE - // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as - // a positive number, it overflows back into a negative). Not handling this - // case would often result in infinite recursion. - // - // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from* - // methods on which they depend. - - /** - * An indicator used to reliably determine if an object is a Long or not. - * @type {boolean} - * @const - * @private - */ - Long.prototype.__isLong__; - - Object.defineProperty(Long.prototype, "__isLong__", { - value: true, - enumerable: false, - configurable: false - }); - - /** - * @function - * @param {*} obj Object - * @returns {boolean} - * @inner - */ - function isLong(obj) { - return (obj && obj["__isLong__"]) === true; - } - - /** - * Tests if the specified object is a Long. - * @function - * @param {*} obj Object - * @returns {boolean} - */ - Long.isLong = isLong; - - /** - * A cache of the Long representations of small integer values. - * @type {!Object} - * @inner - */ - var INT_CACHE = {}; - - /** - * A cache of the Long representations of small unsigned integer values. - * @type {!Object} - * @inner - */ - var UINT_CACHE = {}; - - /** - * @param {number} value - * @param {boolean=} unsigned - * @returns {!Long} - * @inner - */ - function fromInt(value, unsigned) { - var obj, cachedObj, cache; - if (unsigned) { - value >>>= 0; - if (cache = (0 <= value && value < 256)) { - cachedObj = UINT_CACHE[value]; - if (cachedObj) - return cachedObj; - } - obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true); - if (cache) - UINT_CACHE[value] = obj; - return obj; - } else { - value |= 0; - if (cache = (-128 <= value && value < 128)) { - cachedObj = INT_CACHE[value]; - if (cachedObj) - return cachedObj; - } - obj = fromBits(value, value < 0 ? -1 : 0, false); - if (cache) - INT_CACHE[value] = obj; - return obj; - } - } - - /** - * Returns a Long representing the given 32 bit integer value. - * @function - * @param {number} value The 32 bit integer in question - * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed - * @returns {!Long} The corresponding Long value - */ - Long.fromInt = fromInt; - - /** - * @param {number} value - * @param {boolean=} unsigned - * @returns {!Long} - * @inner - */ - function fromNumber(value, unsigned) { - if (isNaN(value) || !isFinite(value)) - return unsigned ? UZERO : ZERO; - if (unsigned) { - if (value < 0) - return UZERO; - if (value >= TWO_PWR_64_DBL) - return MAX_UNSIGNED_VALUE; - } else { - if (value <= -TWO_PWR_63_DBL) - return MIN_VALUE; - if (value + 1 >= TWO_PWR_63_DBL) - return MAX_VALUE; - } - if (value < 0) - return fromNumber(-value, unsigned).neg(); - return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned); - } - - /** - * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned. - * @function - * @param {number} value The number in question - * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed - * @returns {!Long} The corresponding Long value - */ - Long.fromNumber = fromNumber; - - /** - * @param {number} lowBits - * @param {number} highBits - * @param {boolean=} unsigned - * @returns {!Long} - * @inner - */ - function fromBits(lowBits, highBits, unsigned) { - return new Long(lowBits, highBits, unsigned); - } - - /** - * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is - * assumed to use 32 bits. - * @function - * @param {number} lowBits The low 32 bits - * @param {number} highBits The high 32 bits - * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed - * @returns {!Long} The corresponding Long value - */ - Long.fromBits = fromBits; - - /** - * @function - * @param {number} base - * @param {number} exponent - * @returns {number} - * @inner - */ - var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4) - - /** - * @param {string} str - * @param {(boolean|number)=} unsigned - * @param {number=} radix - * @returns {!Long} - * @inner - */ - function fromString(str, unsigned, radix) { - if (str.length === 0) - throw Error('empty string'); - if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity") - return ZERO; - if (typeof unsigned === 'number') { - // For goog.math.long compatibility - radix = unsigned, - unsigned = false; - } else { - unsigned = !! unsigned; - } - radix = radix || 10; - if (radix < 2 || 36 < radix) - throw RangeError('radix'); - - var p; - if ((p = str.indexOf('-')) > 0) - throw Error('interior hyphen'); - else if (p === 0) { - return fromString(str.substring(1), unsigned, radix).neg(); - } - - // Do several (8) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = fromNumber(pow_dbl(radix, 8)); - - var result = ZERO; - for (var i = 0; i < str.length; i += 8) { - var size = Math.min(8, str.length - i), - value = parseInt(str.substring(i, i + size), radix); - if (size < 8) { - var power = fromNumber(pow_dbl(radix, size)); - result = result.mul(power).add(fromNumber(value)); - } else { - result = result.mul(radixToPower); - result = result.add(fromNumber(value)); - } - } - result.unsigned = unsigned; - return result; - } - - /** - * Returns a Long representation of the given string, written using the specified radix. - * @function - * @param {string} str The textual representation of the Long - * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed - * @param {number=} radix The radix in which the text is written (2-36), defaults to 10 - * @returns {!Long} The corresponding Long value - */ - Long.fromString = fromString; - - /** - * @function - * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val - * @returns {!Long} - * @inner - */ - function fromValue(val) { - if (val /* is compatible */ instanceof Long) - return val; - if (typeof val === 'number') - return fromNumber(val); - if (typeof val === 'string') - return fromString(val); - // Throws for non-objects, converts non-instanceof Long: - return fromBits(val.low, val.high, val.unsigned); - } - - /** - * Converts the specified value to a Long. - * @function - * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value - * @returns {!Long} - */ - Long.fromValue = fromValue; - - // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be - // no runtime penalty for these. - - /** - * @type {number} - * @const - * @inner - */ - var TWO_PWR_16_DBL = 1 << 16; - - /** - * @type {number} - * @const - * @inner - */ - var TWO_PWR_24_DBL = 1 << 24; - - /** - * @type {number} - * @const - * @inner - */ - var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL; - - /** - * @type {number} - * @const - * @inner - */ - var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL; - - /** - * @type {number} - * @const - * @inner - */ - var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2; - - /** - * @type {!Long} - * @const - * @inner - */ - var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL); - - /** - * @type {!Long} - * @inner - */ - var ZERO = fromInt(0); - - /** - * Signed zero. - * @type {!Long} - */ - Long.ZERO = ZERO; - - /** - * @type {!Long} - * @inner - */ - var UZERO = fromInt(0, true); - - /** - * Unsigned zero. - * @type {!Long} - */ - Long.UZERO = UZERO; - - /** - * @type {!Long} - * @inner - */ - var ONE = fromInt(1); - - /** - * Signed one. - * @type {!Long} - */ - Long.ONE = ONE; - - /** - * @type {!Long} - * @inner - */ - var UONE = fromInt(1, true); - - /** - * Unsigned one. - * @type {!Long} - */ - Long.UONE = UONE; - - /** - * @type {!Long} - * @inner - */ - var NEG_ONE = fromInt(-1); - - /** - * Signed negative one. - * @type {!Long} - */ - Long.NEG_ONE = NEG_ONE; - - /** - * @type {!Long} - * @inner - */ - var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false); - - /** - * Maximum signed value. - * @type {!Long} - */ - Long.MAX_VALUE = MAX_VALUE; - - /** - * @type {!Long} - * @inner - */ - var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true); - - /** - * Maximum unsigned value. - * @type {!Long} - */ - Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE; - - /** - * @type {!Long} - * @inner - */ - var MIN_VALUE = fromBits(0, 0x80000000|0, false); - - /** - * Minimum signed value. - * @type {!Long} - */ - Long.MIN_VALUE = MIN_VALUE; - - /** - * @alias Long.prototype - * @inner - */ - var LongPrototype = Long.prototype; - - /** - * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer. - * @returns {number} - */ - LongPrototype.toInt = function toInt() { - return this.unsigned ? this.low >>> 0 : this.low; - }; - - /** - * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa). - * @returns {number} - */ - LongPrototype.toNumber = function toNumber() { - if (this.unsigned) - return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0); - return this.high * TWO_PWR_32_DBL + (this.low >>> 0); - }; - - /** - * Converts the Long to a string written in the specified radix. - * @param {number=} radix Radix (2-36), defaults to 10 - * @returns {string} - * @override - * @throws {RangeError} If `radix` is out of range - */ - LongPrototype.toString = function toString(radix) { - radix = radix || 10; - if (radix < 2 || 36 < radix) - throw RangeError('radix'); - if (this.isZero()) - return '0'; - if (this.isNegative()) { // Unsigned Longs are never negative - if (this.eq(MIN_VALUE)) { - // We need to change the Long value before it can be negated, so we remove - // the bottom-most digit in this base and then recurse to do the rest. - var radixLong = fromNumber(radix), - div = this.div(radixLong), - rem1 = div.mul(radixLong).sub(this); - return div.toString(radix) + rem1.toInt().toString(radix); - } else - return '-' + this.neg().toString(radix); - } - - // Do several (6) digits each time through the loop, so as to - // minimize the calls to the very expensive emulated div. - var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned), - rem = this; - var result = ''; - while (true) { - var remDiv = rem.div(radixToPower), - intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0, - digits = intval.toString(radix); - rem = remDiv; - if (rem.isZero()) - return digits + result; - else { - while (digits.length < 6) - digits = '0' + digits; - result = '' + digits + result; - } - } - }; - - /** - * Gets the high 32 bits as a signed integer. - * @returns {number} Signed high bits - */ - LongPrototype.getHighBits = function getHighBits() { - return this.high; - }; - - /** - * Gets the high 32 bits as an unsigned integer. - * @returns {number} Unsigned high bits - */ - LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() { - return this.high >>> 0; - }; - - /** - * Gets the low 32 bits as a signed integer. - * @returns {number} Signed low bits - */ - LongPrototype.getLowBits = function getLowBits() { - return this.low; - }; - - /** - * Gets the low 32 bits as an unsigned integer. - * @returns {number} Unsigned low bits - */ - LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() { - return this.low >>> 0; - }; - - /** - * Gets the number of bits needed to represent the absolute value of this Long. - * @returns {number} - */ - LongPrototype.getNumBitsAbs = function getNumBitsAbs() { - if (this.isNegative()) // Unsigned Longs are never negative - return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs(); - var val = this.high != 0 ? this.high : this.low; - for (var bit = 31; bit > 0; bit--) - if ((val & (1 << bit)) != 0) - break; - return this.high != 0 ? bit + 33 : bit + 1; - }; - - /** - * Tests if this Long's value equals zero. - * @returns {boolean} - */ - LongPrototype.isZero = function isZero() { - return this.high === 0 && this.low === 0; - }; - - /** - * Tests if this Long's value is negative. - * @returns {boolean} - */ - LongPrototype.isNegative = function isNegative() { - return !this.unsigned && this.high < 0; - }; - - /** - * Tests if this Long's value is positive. - * @returns {boolean} - */ - LongPrototype.isPositive = function isPositive() { - return this.unsigned || this.high >= 0; - }; - - /** - * Tests if this Long's value is odd. - * @returns {boolean} - */ - LongPrototype.isOdd = function isOdd() { - return (this.low & 1) === 1; - }; - - /** - * Tests if this Long's value is even. - * @returns {boolean} - */ - LongPrototype.isEven = function isEven() { - return (this.low & 1) === 0; - }; - - /** - * Tests if this Long's value equals the specified's. - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.equals = function equals(other) { - if (!isLong(other)) - other = fromValue(other); - if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1) - return false; - return this.high === other.high && this.low === other.low; - }; - - /** - * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}. - * @function - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.eq = LongPrototype.equals; - - /** - * Tests if this Long's value differs from the specified's. - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.notEquals = function notEquals(other) { - return !this.eq(/* validates */ other); - }; - - /** - * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}. - * @function - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.neq = LongPrototype.notEquals; - - /** - * Tests if this Long's value is less than the specified's. - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.lessThan = function lessThan(other) { - return this.comp(/* validates */ other) < 0; - }; - - /** - * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}. - * @function - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.lt = LongPrototype.lessThan; - - /** - * Tests if this Long's value is less than or equal the specified's. - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) { - return this.comp(/* validates */ other) <= 0; - }; - - /** - * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}. - * @function - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.lte = LongPrototype.lessThanOrEqual; - - /** - * Tests if this Long's value is greater than the specified's. - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.greaterThan = function greaterThan(other) { - return this.comp(/* validates */ other) > 0; - }; - - /** - * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}. - * @function - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.gt = LongPrototype.greaterThan; - - /** - * Tests if this Long's value is greater than or equal the specified's. - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) { - return this.comp(/* validates */ other) >= 0; - }; - - /** - * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}. - * @function - * @param {!Long|number|string} other Other value - * @returns {boolean} - */ - LongPrototype.gte = LongPrototype.greaterThanOrEqual; - - /** - * Compares this Long's value with the specified's. - * @param {!Long|number|string} other Other value - * @returns {number} 0 if they are the same, 1 if the this is greater and -1 - * if the given one is greater - */ - LongPrototype.compare = function compare(other) { - if (!isLong(other)) - other = fromValue(other); - if (this.eq(other)) - return 0; - var thisNeg = this.isNegative(), - otherNeg = other.isNegative(); - if (thisNeg && !otherNeg) - return -1; - if (!thisNeg && otherNeg) - return 1; - // At this point the sign bits are the same - if (!this.unsigned) - return this.sub(other).isNegative() ? -1 : 1; - // Both are positive if at least one is unsigned - return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1; - }; - - /** - * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}. - * @function - * @param {!Long|number|string} other Other value - * @returns {number} 0 if they are the same, 1 if the this is greater and -1 - * if the given one is greater - */ - LongPrototype.comp = LongPrototype.compare; - - /** - * Negates this Long's value. - * @returns {!Long} Negated Long - */ - LongPrototype.negate = function negate() { - if (!this.unsigned && this.eq(MIN_VALUE)) - return MIN_VALUE; - return this.not().add(ONE); - }; - - /** - * Negates this Long's value. This is an alias of {@link Long#negate}. - * @function - * @returns {!Long} Negated Long - */ - LongPrototype.neg = LongPrototype.negate; - - /** - * Returns the sum of this and the specified Long. - * @param {!Long|number|string} addend Addend - * @returns {!Long} Sum - */ - LongPrototype.add = function add(addend) { - if (!isLong(addend)) - addend = fromValue(addend); - - // Divide each number into 4 chunks of 16 bits, and then sum the chunks. - - var a48 = this.high >>> 16; - var a32 = this.high & 0xFFFF; - var a16 = this.low >>> 16; - var a00 = this.low & 0xFFFF; - - var b48 = addend.high >>> 16; - var b32 = addend.high & 0xFFFF; - var b16 = addend.low >>> 16; - var b00 = addend.low & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 + b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 + b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 + b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 + b48; - c48 &= 0xFFFF; - return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); - }; - - /** - * Returns the difference of this and the specified Long. - * @param {!Long|number|string} subtrahend Subtrahend - * @returns {!Long} Difference - */ - LongPrototype.subtract = function subtract(subtrahend) { - if (!isLong(subtrahend)) - subtrahend = fromValue(subtrahend); - return this.add(subtrahend.neg()); - }; - - /** - * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}. - * @function - * @param {!Long|number|string} subtrahend Subtrahend - * @returns {!Long} Difference - */ - LongPrototype.sub = LongPrototype.subtract; - - /** - * Returns the product of this and the specified Long. - * @param {!Long|number|string} multiplier Multiplier - * @returns {!Long} Product - */ - LongPrototype.multiply = function multiply(multiplier) { - if (this.isZero()) - return ZERO; - if (!isLong(multiplier)) - multiplier = fromValue(multiplier); - if (multiplier.isZero()) - return ZERO; - if (this.eq(MIN_VALUE)) - return multiplier.isOdd() ? MIN_VALUE : ZERO; - if (multiplier.eq(MIN_VALUE)) - return this.isOdd() ? MIN_VALUE : ZERO; - - if (this.isNegative()) { - if (multiplier.isNegative()) - return this.neg().mul(multiplier.neg()); - else - return this.neg().mul(multiplier).neg(); - } else if (multiplier.isNegative()) - return this.mul(multiplier.neg()).neg(); - - // If both longs are small, use float multiplication - if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24)) - return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned); - - // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products. - // We can skip products that would overflow. - - var a48 = this.high >>> 16; - var a32 = this.high & 0xFFFF; - var a16 = this.low >>> 16; - var a00 = this.low & 0xFFFF; - - var b48 = multiplier.high >>> 16; - var b32 = multiplier.high & 0xFFFF; - var b16 = multiplier.low >>> 16; - var b00 = multiplier.low & 0xFFFF; - - var c48 = 0, c32 = 0, c16 = 0, c00 = 0; - c00 += a00 * b00; - c16 += c00 >>> 16; - c00 &= 0xFFFF; - c16 += a16 * b00; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c16 += a00 * b16; - c32 += c16 >>> 16; - c16 &= 0xFFFF; - c32 += a32 * b00; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a16 * b16; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c32 += a00 * b32; - c48 += c32 >>> 16; - c32 &= 0xFFFF; - c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48; - c48 &= 0xFFFF; - return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned); - }; - - /** - * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}. - * @function - * @param {!Long|number|string} multiplier Multiplier - * @returns {!Long} Product - */ - LongPrototype.mul = LongPrototype.multiply; - - /** - * Returns this Long divided by the specified. The result is signed if this Long is signed or - * unsigned if this Long is unsigned. - * @param {!Long|number|string} divisor Divisor - * @returns {!Long} Quotient - */ - LongPrototype.divide = function divide(divisor) { - if (!isLong(divisor)) - divisor = fromValue(divisor); - if (divisor.isZero()) - throw Error('division by zero'); - if (this.isZero()) - return this.unsigned ? UZERO : ZERO; - var approx, rem, res; - if (!this.unsigned) { - // This section is only relevant for signed longs and is derived from the - // closure library as a whole. - if (this.eq(MIN_VALUE)) { - if (divisor.eq(ONE) || divisor.eq(NEG_ONE)) - return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE - else if (divisor.eq(MIN_VALUE)) - return ONE; - else { - // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|. - var halfThis = this.shr(1); - approx = halfThis.div(divisor).shl(1); - if (approx.eq(ZERO)) { - return divisor.isNegative() ? ONE : NEG_ONE; - } else { - rem = this.sub(divisor.mul(approx)); - res = approx.add(rem.div(divisor)); - return res; - } - } - } else if (divisor.eq(MIN_VALUE)) - return this.unsigned ? UZERO : ZERO; - if (this.isNegative()) { - if (divisor.isNegative()) - return this.neg().div(divisor.neg()); - return this.neg().div(divisor).neg(); - } else if (divisor.isNegative()) - return this.div(divisor.neg()).neg(); - res = ZERO; - } else { - // The algorithm below has not been made for unsigned longs. It's therefore - // required to take special care of the MSB prior to running it. - if (!divisor.unsigned) - divisor = divisor.toUnsigned(); - if (divisor.gt(this)) - return UZERO; - if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true - return UONE; - res = UZERO; - } - - // Repeat the following until the remainder is less than other: find a - // floating-point that approximates remainder / other *from below*, add this - // into the result, and subtract it from the remainder. It is critical that - // the approximate value is less than or equal to the real value so that the - // remainder never becomes negative. - rem = this; - while (rem.gte(divisor)) { - // Approximate the result of division. This may be a little greater or - // smaller than the actual value. - approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber())); - - // We will tweak the approximate result by changing it in the 48-th digit or - // the smallest non-fractional digit, whichever is larger. - var log2 = Math.ceil(Math.log(approx) / Math.LN2), - delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48), - - // Decrease the approximation until it is smaller than the remainder. Note - // that if it is too large, the product overflows and is negative. - approxRes = fromNumber(approx), - approxRem = approxRes.mul(divisor); - while (approxRem.isNegative() || approxRem.gt(rem)) { - approx -= delta; - approxRes = fromNumber(approx, this.unsigned); - approxRem = approxRes.mul(divisor); - } - - // We know the answer can't be zero... and actually, zero would cause - // infinite recursion since we would make no progress. - if (approxRes.isZero()) - approxRes = ONE; - - res = res.add(approxRes); - rem = rem.sub(approxRem); - } - return res; - }; - - /** - * Returns this Long divided by the specified. This is an alias of {@link Long#divide}. - * @function - * @param {!Long|number|string} divisor Divisor - * @returns {!Long} Quotient - */ - LongPrototype.div = LongPrototype.divide; - - /** - * Returns this Long modulo the specified. - * @param {!Long|number|string} divisor Divisor - * @returns {!Long} Remainder - */ - LongPrototype.modulo = function modulo(divisor) { - if (!isLong(divisor)) - divisor = fromValue(divisor); - return this.sub(this.div(divisor).mul(divisor)); - }; - - /** - * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}. - * @function - * @param {!Long|number|string} divisor Divisor - * @returns {!Long} Remainder - */ - LongPrototype.mod = LongPrototype.modulo; - - /** - * Returns the bitwise NOT of this Long. - * @returns {!Long} - */ - LongPrototype.not = function not() { - return fromBits(~this.low, ~this.high, this.unsigned); - }; - - /** - * Returns the bitwise AND of this Long and the specified. - * @param {!Long|number|string} other Other Long - * @returns {!Long} - */ - LongPrototype.and = function and(other) { - if (!isLong(other)) - other = fromValue(other); - return fromBits(this.low & other.low, this.high & other.high, this.unsigned); - }; - - /** - * Returns the bitwise OR of this Long and the specified. - * @param {!Long|number|string} other Other Long - * @returns {!Long} - */ - LongPrototype.or = function or(other) { - if (!isLong(other)) - other = fromValue(other); - return fromBits(this.low | other.low, this.high | other.high, this.unsigned); - }; - - /** - * Returns the bitwise XOR of this Long and the given one. - * @param {!Long|number|string} other Other Long - * @returns {!Long} - */ - LongPrototype.xor = function xor(other) { - if (!isLong(other)) - other = fromValue(other); - return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned); - }; - - /** - * Returns this Long with bits shifted to the left by the given amount. - * @param {number|!Long} numBits Number of bits - * @returns {!Long} Shifted Long - */ - LongPrototype.shiftLeft = function shiftLeft(numBits) { - if (isLong(numBits)) - numBits = numBits.toInt(); - if ((numBits &= 63) === 0) - return this; - else if (numBits < 32) - return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned); - else - return fromBits(0, this.low << (numBits - 32), this.unsigned); - }; - - /** - * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}. - * @function - * @param {number|!Long} numBits Number of bits - * @returns {!Long} Shifted Long - */ - LongPrototype.shl = LongPrototype.shiftLeft; - - /** - * Returns this Long with bits arithmetically shifted to the right by the given amount. - * @param {number|!Long} numBits Number of bits - * @returns {!Long} Shifted Long - */ - LongPrototype.shiftRight = function shiftRight(numBits) { - if (isLong(numBits)) - numBits = numBits.toInt(); - if ((numBits &= 63) === 0) - return this; - else if (numBits < 32) - return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned); - else - return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned); - }; - - /** - * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}. - * @function - * @param {number|!Long} numBits Number of bits - * @returns {!Long} Shifted Long - */ - LongPrototype.shr = LongPrototype.shiftRight; - - /** - * Returns this Long with bits logically shifted to the right by the given amount. - * @param {number|!Long} numBits Number of bits - * @returns {!Long} Shifted Long - */ - LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) { - if (isLong(numBits)) - numBits = numBits.toInt(); - numBits &= 63; - if (numBits === 0) - return this; - else { - var high = this.high; - if (numBits < 32) { - var low = this.low; - return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned); - } else if (numBits === 32) - return fromBits(high, 0, this.unsigned); - else - return fromBits(high >>> (numBits - 32), 0, this.unsigned); - } - }; - - /** - * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}. - * @function - * @param {number|!Long} numBits Number of bits - * @returns {!Long} Shifted Long - */ - LongPrototype.shru = LongPrototype.shiftRightUnsigned; - - /** - * Converts this Long to signed. - * @returns {!Long} Signed long - */ - LongPrototype.toSigned = function toSigned() { - if (!this.unsigned) - return this; - return fromBits(this.low, this.high, false); - }; - - /** - * Converts this Long to unsigned. - * @returns {!Long} Unsigned long - */ - LongPrototype.toUnsigned = function toUnsigned() { - if (this.unsigned) - return this; - return fromBits(this.low, this.high, true); - }; - - /** - * Converts this Long to its byte representation. - * @param {boolean=} le Whether little or big endian, defaults to big endian - * @returns {!Array.} Byte representation - */ - LongPrototype.toBytes = function(le) { - return le ? this.toBytesLE() : this.toBytesBE(); - } - - /** - * Converts this Long to its little endian byte representation. - * @returns {!Array.} Little endian byte representation - */ - LongPrototype.toBytesLE = function() { - var hi = this.high, - lo = this.low; - return [ - lo & 0xff, - (lo >>> 8) & 0xff, - (lo >>> 16) & 0xff, - (lo >>> 24) & 0xff, - hi & 0xff, - (hi >>> 8) & 0xff, - (hi >>> 16) & 0xff, - (hi >>> 24) & 0xff - ]; - } - - /** - * Converts this Long to its big endian byte representation. - * @returns {!Array.} Big endian byte representation - */ - LongPrototype.toBytesBE = function() { - var hi = this.high, - lo = this.low; - return [ - (hi >>> 24) & 0xff, - (hi >>> 16) & 0xff, - (hi >>> 8) & 0xff, - hi & 0xff, - (lo >>> 24) & 0xff, - (lo >>> 16) & 0xff, - (lo >>> 8) & 0xff, - lo & 0xff - ]; - } - - return Long; -}); - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/md5.js/index.js":[function(require,module,exports){ -(function (Buffer){ -'use strict' -var inherits = require('inherits') -var HashBase = require('hash-base') - -var ARRAY16 = new Array(16) - -function MD5 () { - HashBase.call(this, 64) - - // state - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 -} - -inherits(MD5, HashBase) - -MD5.prototype._update = function () { - var M = ARRAY16 - for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4) - - var a = this._a - var b = this._b - var c = this._c - var d = this._d - - a = fnF(a, b, c, d, M[0], 0xd76aa478, 7) - d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12) - c = fnF(c, d, a, b, M[2], 0x242070db, 17) - b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22) - a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7) - d = fnF(d, a, b, c, M[5], 0x4787c62a, 12) - c = fnF(c, d, a, b, M[6], 0xa8304613, 17) - b = fnF(b, c, d, a, M[7], 0xfd469501, 22) - a = fnF(a, b, c, d, M[8], 0x698098d8, 7) - d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12) - c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17) - b = fnF(b, c, d, a, M[11], 0x895cd7be, 22) - a = fnF(a, b, c, d, M[12], 0x6b901122, 7) - d = fnF(d, a, b, c, M[13], 0xfd987193, 12) - c = fnF(c, d, a, b, M[14], 0xa679438e, 17) - b = fnF(b, c, d, a, M[15], 0x49b40821, 22) - - a = fnG(a, b, c, d, M[1], 0xf61e2562, 5) - d = fnG(d, a, b, c, M[6], 0xc040b340, 9) - c = fnG(c, d, a, b, M[11], 0x265e5a51, 14) - b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20) - a = fnG(a, b, c, d, M[5], 0xd62f105d, 5) - d = fnG(d, a, b, c, M[10], 0x02441453, 9) - c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14) - b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20) - a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5) - d = fnG(d, a, b, c, M[14], 0xc33707d6, 9) - c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14) - b = fnG(b, c, d, a, M[8], 0x455a14ed, 20) - a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5) - d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9) - c = fnG(c, d, a, b, M[7], 0x676f02d9, 14) - b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20) - - a = fnH(a, b, c, d, M[5], 0xfffa3942, 4) - d = fnH(d, a, b, c, M[8], 0x8771f681, 11) - c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16) - b = fnH(b, c, d, a, M[14], 0xfde5380c, 23) - a = fnH(a, b, c, d, M[1], 0xa4beea44, 4) - d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11) - c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16) - b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23) - a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4) - d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11) - c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16) - b = fnH(b, c, d, a, M[6], 0x04881d05, 23) - a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4) - d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11) - c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16) - b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23) - - a = fnI(a, b, c, d, M[0], 0xf4292244, 6) - d = fnI(d, a, b, c, M[7], 0x432aff97, 10) - c = fnI(c, d, a, b, M[14], 0xab9423a7, 15) - b = fnI(b, c, d, a, M[5], 0xfc93a039, 21) - a = fnI(a, b, c, d, M[12], 0x655b59c3, 6) - d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10) - c = fnI(c, d, a, b, M[10], 0xffeff47d, 15) - b = fnI(b, c, d, a, M[1], 0x85845dd1, 21) - a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6) - d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10) - c = fnI(c, d, a, b, M[6], 0xa3014314, 15) - b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21) - a = fnI(a, b, c, d, M[4], 0xf7537e82, 6) - d = fnI(d, a, b, c, M[11], 0xbd3af235, 10) - c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15) - b = fnI(b, c, d, a, M[9], 0xeb86d391, 21) - - this._a = (this._a + a) | 0 - this._b = (this._b + b) | 0 - this._c = (this._c + c) | 0 - this._d = (this._d + d) | 0 -} - -MD5.prototype._digest = function () { - // create padding and handle blocks - this._block[this._blockOffset++] = 0x80 - if (this._blockOffset > 56) { - this._block.fill(0, this._blockOffset, 64) - this._update() - this._blockOffset = 0 - } - - this._block.fill(0, this._blockOffset, 56) - this._block.writeUInt32LE(this._length[0], 56) - this._block.writeUInt32LE(this._length[1], 60) - this._update() - - // produce result - var buffer = new Buffer(16) - buffer.writeInt32LE(this._a, 0) - buffer.writeInt32LE(this._b, 4) - buffer.writeInt32LE(this._c, 8) - buffer.writeInt32LE(this._d, 12) - return buffer -} - -function rotl (x, n) { - return (x << n) | (x >>> (32 - n)) -} - -function fnF (a, b, c, d, m, k, s) { - return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0 -} - -function fnG (a, b, c, d, m, k, s) { - return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0 -} - -function fnH (a, b, c, d, m, k, s) { - return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0 -} - -function fnI (a, b, c, d, m, k, s) { - return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0 -} - -module.exports = MD5 - -}).call(this,require("buffer").Buffer) - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","hash-base":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/md5.js/node_modules/hash-base/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/md5.js/node_modules/hash-base/index.js":[function(require,module,exports){ -'use strict' -var Buffer = require('safe-buffer').Buffer -var Transform = require('stream').Transform -var inherits = require('inherits') - -function throwIfNotStringOrBuffer (val, prefix) { - if (!Buffer.isBuffer(val) && typeof val !== 'string') { - throw new TypeError(prefix + ' must be a string or a buffer') - } -} - -function HashBase (blockSize) { - Transform.call(this) - - this._block = Buffer.allocUnsafe(blockSize) - this._blockSize = blockSize - this._blockOffset = 0 - this._length = [0, 0, 0, 0] - - this._finalized = false -} - -inherits(HashBase, Transform) - -HashBase.prototype._transform = function (chunk, encoding, callback) { - var error = null - try { - this.update(chunk, encoding) - } catch (err) { - error = err - } - - callback(error) -} - -HashBase.prototype._flush = function (callback) { - var error = null - try { - this.push(this.digest()) - } catch (err) { - error = err - } - - callback(error) -} - -HashBase.prototype.update = function (data, encoding) { - throwIfNotStringOrBuffer(data, 'Data') - if (this._finalized) throw new Error('Digest already called') - if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding) - - // consume data - var block = this._block - var offset = 0 - while (this._blockOffset + data.length - offset >= this._blockSize) { - for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++] - this._update() - this._blockOffset = 0 - } - while (offset < data.length) block[this._blockOffset++] = data[offset++] - - // update length - for (var j = 0, carry = data.length * 8; carry > 0; ++j) { - this._length[j] += carry - carry = (this._length[j] / 0x0100000000) | 0 - if (carry > 0) this._length[j] -= 0x0100000000 * carry - } - - return this -} - -HashBase.prototype._update = function () { - throw new Error('_update is not implemented') -} - -HashBase.prototype.digest = function (encoding) { - if (this._finalized) throw new Error('Digest already called') - this._finalized = true - - var digest = this._digest() - if (encoding !== undefined) digest = digest.toString(encoding) - - // reset state - this._block.fill(0) - this._blockOffset = 0 - for (var i = 0; i < 4; ++i) this._length[i] = 0 - - return digest -} - -HashBase.prototype._digest = function () { - throw new Error('_digest is not implemented') -} - -module.exports = HashBase - -},{"inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js","stream":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/stream-browserify/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process-nextick-args/index.js":[function(require,module,exports){ -(function (process){ -'use strict'; - -if (!process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = nextTick; -} else { - module.exports = process.nextTick; -} - -function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - -}).call(this,require('_process')) - -},{"_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js":[function(require,module,exports){ -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/duplex-browser.js":[function(require,module,exports){ -module.exports = require('./lib/_stream_duplex.js'); - -},{"./lib/_stream_duplex.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js":[function(require,module,exports){ -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. - -'use strict'; - -/**/ - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - keys.push(key); - }return keys; -}; -/**/ - -module.exports = Duplex; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -var Readable = require('./_stream_readable'); -var Writable = require('./_stream_writable'); - -util.inherits(Duplex, Readable); - -var keys = objectKeys(Writable.prototype); -for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; -} - -function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - - Readable.call(this, options); - Writable.call(this, options); - - if (options && options.readable === false) this.readable = false; - - if (options && options.writable === false) this.writable = false; - - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; - - this.once('end', onend); -} - -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) return; - - // no more data can be written. - // But allow more writes to happen in this tick. - processNextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} -},{"./_stream_readable":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_readable.js","./_stream_writable":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_writable.js","core-util-is":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/core-util-is/lib/util.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","process-nextick-args":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process-nextick-args/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_passthrough.js":[function(require,module,exports){ -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. - -'use strict'; - -module.exports = PassThrough; - -var Transform = require('./_stream_transform'); - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(PassThrough, Transform); - -function PassThrough(options) { - if (!(this instanceof PassThrough)) return new PassThrough(options); - - Transform.call(this, options); -} - -PassThrough.prototype._transform = function (chunk, encoding, cb) { - cb(null, chunk); -}; -},{"./_stream_transform":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_transform.js","core-util-is":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/core-util-is/lib/util.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_readable.js":[function(require,module,exports){ -(function (process){ -'use strict'; - -module.exports = Readable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var isArray = require('isarray'); -/**/ - -/**/ -var Duplex; -/**/ - -Readable.ReadableState = ReadableState; - -/**/ -var EE = require('events').EventEmitter; - -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ -var Stream = require('./internal/streams/stream'); -/**/ - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var debugUtil = require('util'); -var debug = void 0; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ - -var BufferList = require('./internal/streams/BufferList'); -var StringDecoder; - -util.inherits(Readable, Stream); - -var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; - -function prependListener(emitter, event, fn) { - // Sadly this is not cacheable as some libraries bundle their own - // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') { - return emitter.prependListener(event, fn); - } else { - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; - } -} - -function ReadableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; - - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; - - // if true, a maybeReadMore has been scheduled - this.readingMore = false; - - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -function Readable(options) { - Duplex = Duplex || require('./_stream_duplex'); - - if (!(this instanceof Readable)) return new Readable(options); - - this._readableState = new ReadableState(options, this); - - // legacy - this.readable = true; - - if (options && typeof options.read === 'function') this._read = options.read; - - Stream.call(this); -} - -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - - if (!state.objectMode && typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = bufferShim.from(chunk, encoding); - encoding = ''; - } - } - - return readableAddChunk(this, state, chunk, encoding, false); -}; - -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function (chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); -}; - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; - -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var _e = new Error('stream.unshift() after end event'); - stream.emit('error', _e); - } else { - var skipAdd; - if (state.decoder && !addToFront && !encoding) { - chunk = state.decoder.write(chunk); - skipAdd = !state.objectMode && chunk.length === 0; - } - - if (!addToFront) state.reading = false; - - // Don't add to the buffer if we've decoded to an empty string chunk and - // we're not in object mode - if (!skipAdd) { - // if we want the data now, just emit it. - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - - if (state.needReadable) emitReadable(stream); - } - } - - maybeReadMore(stream, state); - } - } else if (!addToFront) { - state.reading = false; - } - - return needMoreData(state); -} - -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); -} - -// backwards compatibility. -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; - return this; -}; - -// Don't raise the hwm > 8MB -var MAX_HWM = 0x800000; -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough - if (!state.ended) { - state.needReadable = true; - return 0; - } - return state.length; -} - -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); - - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); - - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = true; - n = 0; - } else { - state.length -= n; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - - return ret; -}; - -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - -function onEofChunk(stream, state) { - if (state.ended) return; - if (state.decoder) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; - - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); - } -} - -function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} - -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - processNextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break;else len = state.length; - } - state.readingMore = false; -} - -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function (n) { - this.emit('error', new Error('_read() is not implemented')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - case 1: - state.pipes = [state.pipes, dest]; - break; - default: - state.pipes.push(dest); - break; - } - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); - - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - debug('onunpipe'); - if (readable === src) { - cleanup(); - } - } - - function onend() { - debug('onend'); - dest.end(); - } - - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - - var cleanedUp = false; - function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', cleanup); - src.removeListener('data', ondata); - - cleanedUp = true; - - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - increasedAwaitDrain = false; - var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; - } - src.pause(); - } - } - - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } - - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } - - // tell the dest that it's being piped to - dest.emit('pipe', src); - - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function () { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) return this; - - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - - if (!dest) dest = state.pipes; - - // got a match. - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this); - return this; - } - - // slow case. multiple pipe destinations. - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this); - }return this; - } - - // try to find the right one. - var index = indexOf(state.pipes, dest); - if (index === -1) return this; - - state.pipes.splice(index, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - - dest.emit('unpipe', this); - - return this; -}; - -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - - if (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); - } else if (ev === 'readable') { - var state = this._readableState; - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.emittedReadable = false; - if (!state.reading) { - processNextTick(nReadingNextTick, this); - } else if (state.length) { - emitReadable(this, state); - } - } - } - - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function () { - var state = this._readableState; - if (!state.flowing) { - debug('resume'); - state.flowing = true; - resume(this, state); - } - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - processNextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - if (!state.reading) { - debug('resume read 0'); - stream.read(0); - } - - state.resumeScheduled = false; - state.awaitDrain = 0; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} - -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - var state = this._readableState; - var paused = false; - - var self = this; - stream.on('end', function () { - debug('wrapped end'); - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) self.push(chunk); - } - - self.push(null); - }); - - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); - - // don't skip over falsy values in objectMode - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); - - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function (method) { - return function () { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } - - // proxy certain important events. - for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); - } - - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function (n) { - debug('wrapped _read', n); - if (paused) { - paused = false; - stream.resume(); - } - }; - - return self; -}; - -// exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); - } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = bufferShim.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); - - if (!state.endEmitted) { - state.ended = true; - processNextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } -} - -function forEach(xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} -}).call(this,require('_process')) - -},{"./_stream_duplex":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js","./internal/streams/BufferList":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/internal/streams/BufferList.js","./internal/streams/stream":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/internal/streams/stream-browser.js","_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","buffer-shims":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer-shims/index.js","core-util-is":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/core-util-is/lib/util.js","events":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/events/events.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","isarray":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/isarray/index.js","process-nextick-args":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process-nextick-args/index.js","string_decoder/":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/string_decoder/lib/string_decoder.js","util":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browser-resolve/empty.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_transform.js":[function(require,module,exports){ -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - -'use strict'; - -module.exports = Transform; - -var Duplex = require('./_stream_duplex'); - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(Transform, Duplex); - -function TransformState(stream) { - this.afterTransform = function (er, data) { - return afterTransform(stream, er, data); - }; - - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; - this.writeencoding = null; -} - -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; - - var cb = ts.writecb; - - if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); - - ts.writechunk = null; - ts.writecb = null; - - if (data !== null && data !== undefined) stream.push(data); - - cb(er); - - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} - -function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - - Duplex.call(this, options); - - this._transformState = new TransformState(this); - - var stream = this; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; - - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; - - if (options) { - if (typeof options.transform === 'function') this._transform = options.transform; - - if (typeof options.flush === 'function') this._flush = options.flush; - } - - // When the writable side finishes, then flush out anything remaining. - this.once('prefinish', function () { - if (typeof this._flush === 'function') this._flush(function (er, data) { - done(stream, er, data); - });else done(stream); - }); -} - -Transform.prototype.push = function (chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('_transform() is not implemented'); -}; - -Transform.prototype._write = function (chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); - } -}; - -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function (n) { - var ts = this._transformState; - - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } -}; - -function done(stream, er, data) { - if (er) return stream.emit('error', er); - - if (data !== null && data !== undefined) stream.push(data); - - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var ts = stream._transformState; - - if (ws.length) throw new Error('Calling transform done when ws.length != 0'); - - if (ts.transforming) throw new Error('Calling transform done when still transforming'); - - return stream.push(null); -} -},{"./_stream_duplex":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js","core-util-is":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/core-util-is/lib/util.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_writable.js":[function(require,module,exports){ -(function (process,setImmediate){ -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. - -'use strict'; - -module.exports = Writable; - -/**/ -var processNextTick = require('process-nextick-args'); -/**/ - -/**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; -/**/ - -/**/ -var Duplex; -/**/ - -Writable.WritableState = WritableState; - -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -/**/ -var internalUtil = { - deprecate: require('util-deprecate') -}; -/**/ - -/**/ -var Stream = require('./internal/streams/stream'); -/**/ - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -util.inherits(Writable, Stream); - -function nop() {} - -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} - -function WritableState(options, stream) { - Duplex = Duplex || require('./_stream_duplex'); - - options = options || {}; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; - - if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; - - // drain event flag. - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; - - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; - - // a flag to see when we're in the middle of a write. - this.writing = false; - - // when true all writes will be buffered until .uncork() call - this.corked = 0; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // the callback that's passed to _write(chunk,cb) - this.onwrite = function (er) { - onwrite(stream, er); - }; - - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - - // the amount that is being written when _write is called. - this.writelen = 0; - - this.bufferedRequest = null; - this.lastBufferedRequest = null; - - // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - - // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - this.prefinished = false; - - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; - - // count buffered requests - this.bufferedRequestCount = 0; - - // allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - this.corkedRequestsFree = new CorkedRequest(this); -} - -WritableState.prototype.getBuffer = function getBuffer() { - var current = this.bufferedRequest; - var out = []; - while (current) { - out.push(current); - current = current.next; - } - return out; -}; - -(function () { - try { - Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function () { - return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') - }); - } catch (_) {} -})(); - -// Test _writableState for inheritance to account for Duplex streams, -// whose prototype chain only points to Readable. -var realHasInstance; -if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { - realHasInstance = Function.prototype[Symbol.hasInstance]; - Object.defineProperty(Writable, Symbol.hasInstance, { - value: function (object) { - if (realHasInstance.call(this, object)) return true; - - return object && object._writableState instanceof WritableState; - } - }); -} else { - realHasInstance = function (object) { - return object instanceof this; - }; -} - -function Writable(options) { - Duplex = Duplex || require('./_stream_duplex'); - - // Writable ctor is applied to Duplexes, too. - // `realHasInstance` is necessary because using plain `instanceof` - // would return false, as no `_writableState` property is attached. - - // Trying to use the custom `instanceof` for Writable here will also break the - // Node.js LazyTransform implementation, which has a non-trivial getter for - // `_writableState` that would lead to infinite recursion. - if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { - return new Writable(options); - } - - this._writableState = new WritableState(options, this); - - // legacy. - this.writable = true; - - if (options) { - if (typeof options.write === 'function') this._write = options.write; - - if (typeof options.writev === 'function') this._writev = options.writev; - } - - Stream.call(this); -} - -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function () { - this.emit('error', new Error('Cannot pipe, not readable')); -}; - -function writeAfterEnd(stream, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - processNextTick(cb, er); -} - -// Checks that a user-supplied chunk is valid, especially for the particular -// mode the stream is in. Currently this means that `null` is never accepted -// and undefined/non-string values are only allowed in object mode. -function validChunk(stream, state, chunk, cb) { - var valid = true; - var er = false; - - if (chunk === null) { - er = new TypeError('May not write null values to stream'); - } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - if (er) { - stream.emit('error', er); - processNextTick(cb, er); - valid = false; - } - return valid; -} - -Writable.prototype.write = function (chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - var isBuf = Buffer.isBuffer(chunk); - - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; - - if (typeof cb !== 'function') cb = nop; - - if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { - state.pendingcb++; - ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); - } - - return ret; -}; - -Writable.prototype.cork = function () { - var state = this._writableState; - - state.corked++; -}; - -Writable.prototype.uncork = function () { - var state = this._writableState; - - if (state.corked) { - state.corked--; - - if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); - } -}; - -Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { - // node::ParseEncoding() requires lower case. - if (typeof encoding === 'string') encoding = encoding.toLowerCase(); - if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); - this._writableState.defaultEncoding = encoding; - return this; -}; - -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = bufferShim.from(chunk, encoding); - } - return chunk; -} - -// if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { - if (!isBuf) { - chunk = decodeChunk(state, chunk, encoding); - if (Buffer.isBuffer(chunk)) encoding = 'buffer'; - } - var len = state.objectMode ? 1 : chunk.length; - - state.length += len; - - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. - if (!ret) state.needDrain = true; - - if (state.writing || state.corked) { - var last = state.lastBufferedRequest; - state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); - if (last) { - last.next = state.lastBufferedRequest; - } else { - state.bufferedRequest = state.lastBufferedRequest; - } - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - if (sync) processNextTick(cb, er);else cb(er); - - stream._writableState.errorEmitted = true; - stream.emit('error', er); -} - -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} - -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; - - onwriteStateUpdate(state); - - if (er) onwriteError(stream, state, sync, er, cb);else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(state); - - if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { - clearBuffer(stream, state); - } - - if (sync) { - /**/ - asyncWrite(afterWrite, stream, state, finished, cb); - /**/ - } else { - afterWrite(stream, state, finished, cb); - } - } -} - -function afterWrite(stream, state, finished, cb) { - if (!finished) onwriteDrain(stream, state); - state.pendingcb--; - cb(); - finishMaybe(stream, state); -} - -// Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } -} - -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; - var entry = state.bufferedRequest; - - if (stream._writev && entry && entry.next) { - // Fast case, write everything using _writev() - var l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - - var count = 0; - while (entry) { - buffer[count] = entry; - entry = entry.next; - count += 1; - } - - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - state.corkedRequestsFree = new CorkedRequest(state); - } - } else { - // Slow case, write chunks one-by-one - while (entry) { - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, false, len, chunk, encoding, cb); - entry = entry.next; - // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - break; - } - } - - if (entry === null) state.lastBufferedRequest = null; - } - - state.bufferedRequestCount = 0; - state.bufferedRequest = entry; - state.bufferProcessing = false; -} - -Writable.prototype._write = function (chunk, encoding, cb) { - cb(new Error('_write() is not implemented')); -}; - -Writable.prototype._writev = null; - -Writable.prototype.end = function (chunk, encoding, cb) { - var state = this._writableState; - - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); - - // .end() fully uncorks - if (state.corked) { - state.corked = 1; - this.uncork(); - } - - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) endWritable(this, state, cb); -}; - -function needFinish(state) { - return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; -} - -function prefinish(stream, state) { - if (!state.prefinished) { - state.prefinished = true; - stream.emit('prefinish'); - } -} - -function finishMaybe(stream, state) { - var need = needFinish(state); - if (need) { - if (state.pendingcb === 0) { - prefinish(stream, state); - state.finished = true; - stream.emit('finish'); - } else { - prefinish(stream, state); - } - } - return need; -} - -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) processNextTick(cb);else stream.once('finish', cb); - } - state.ended = true; - stream.writable = false; -} - -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - this.finish = function (err) { - var entry = _this.entry; - _this.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = _this; - } else { - state.corkedRequestsFree = _this; - } - }; -} -}).call(this,require('_process'),require("timers").setImmediate) - -},{"./_stream_duplex":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js","./internal/streams/stream":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/internal/streams/stream-browser.js","_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","buffer-shims":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer-shims/index.js","core-util-is":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/core-util-is/lib/util.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","process-nextick-args":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process-nextick-args/index.js","timers":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/timers-browserify/main.js","util-deprecate":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util-deprecate/browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/internal/streams/BufferList.js":[function(require,module,exports){ -'use strict'; - -var Buffer = require('buffer').Buffer; -/**/ -var bufferShim = require('buffer-shims'); -/**/ - -module.exports = BufferList; - -function BufferList() { - this.head = null; - this.tail = null; - this.length = 0; -} - -BufferList.prototype.push = function (v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; -}; - -BufferList.prototype.unshift = function (v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; -}; - -BufferList.prototype.shift = function () { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; -}; - -BufferList.prototype.clear = function () { - this.head = this.tail = null; - this.length = 0; -}; - -BufferList.prototype.join = function (s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; -}; - -BufferList.prototype.concat = function (n) { - if (this.length === 0) return bufferShim.alloc(0); - if (this.length === 1) return this.head.data; - var ret = bufferShim.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - p.data.copy(ret, i); - i += p.data.length; - p = p.next; - } - return ret; -}; -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","buffer-shims":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer-shims/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/internal/streams/stream-browser.js":[function(require,module,exports){ -module.exports = require('events').EventEmitter; - -},{"events":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/events/events.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/passthrough.js":[function(require,module,exports){ -module.exports = require('./readable').PassThrough - -},{"./readable":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js":[function(require,module,exports){ -exports = module.exports = require('./lib/_stream_readable.js'); -exports.Stream = exports; -exports.Readable = exports; -exports.Writable = require('./lib/_stream_writable.js'); -exports.Duplex = require('./lib/_stream_duplex.js'); -exports.Transform = require('./lib/_stream_transform.js'); -exports.PassThrough = require('./lib/_stream_passthrough.js'); - -},{"./lib/_stream_duplex.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js","./lib/_stream_passthrough.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_passthrough.js","./lib/_stream_readable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_readable.js","./lib/_stream_transform.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_transform.js","./lib/_stream_writable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_writable.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/transform.js":[function(require,module,exports){ -module.exports = require('./readable').Transform - -},{"./readable":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/writable-browser.js":[function(require,module,exports){ -module.exports = require('./lib/_stream_writable.js'); - -},{"./lib/_stream_writable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_writable.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ripemd160/index.js":[function(require,module,exports){ -(function (Buffer){ -'use strict' -var inherits = require('inherits') -var HashBase = require('hash-base') - -function RIPEMD160 () { - HashBase.call(this, 64) - - // state - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 -} - -inherits(RIPEMD160, HashBase) - -RIPEMD160.prototype._update = function () { - var m = new Array(16) - for (var i = 0; i < 16; ++i) m[i] = this._block.readInt32LE(i * 4) - - var al = this._a - var bl = this._b - var cl = this._c - var dl = this._d - var el = this._e - - // Mj = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 - // K = 0x00000000 - // Sj = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8 - al = fn1(al, bl, cl, dl, el, m[0], 0x00000000, 11); cl = rotl(cl, 10) - el = fn1(el, al, bl, cl, dl, m[1], 0x00000000, 14); bl = rotl(bl, 10) - dl = fn1(dl, el, al, bl, cl, m[2], 0x00000000, 15); al = rotl(al, 10) - cl = fn1(cl, dl, el, al, bl, m[3], 0x00000000, 12); el = rotl(el, 10) - bl = fn1(bl, cl, dl, el, al, m[4], 0x00000000, 5); dl = rotl(dl, 10) - al = fn1(al, bl, cl, dl, el, m[5], 0x00000000, 8); cl = rotl(cl, 10) - el = fn1(el, al, bl, cl, dl, m[6], 0x00000000, 7); bl = rotl(bl, 10) - dl = fn1(dl, el, al, bl, cl, m[7], 0x00000000, 9); al = rotl(al, 10) - cl = fn1(cl, dl, el, al, bl, m[8], 0x00000000, 11); el = rotl(el, 10) - bl = fn1(bl, cl, dl, el, al, m[9], 0x00000000, 13); dl = rotl(dl, 10) - al = fn1(al, bl, cl, dl, el, m[10], 0x00000000, 14); cl = rotl(cl, 10) - el = fn1(el, al, bl, cl, dl, m[11], 0x00000000, 15); bl = rotl(bl, 10) - dl = fn1(dl, el, al, bl, cl, m[12], 0x00000000, 6); al = rotl(al, 10) - cl = fn1(cl, dl, el, al, bl, m[13], 0x00000000, 7); el = rotl(el, 10) - bl = fn1(bl, cl, dl, el, al, m[14], 0x00000000, 9); dl = rotl(dl, 10) - al = fn1(al, bl, cl, dl, el, m[15], 0x00000000, 8); cl = rotl(cl, 10) - - // Mj = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8 - // K = 0x5a827999 - // Sj = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12 - el = fn2(el, al, bl, cl, dl, m[7], 0x5a827999, 7); bl = rotl(bl, 10) - dl = fn2(dl, el, al, bl, cl, m[4], 0x5a827999, 6); al = rotl(al, 10) - cl = fn2(cl, dl, el, al, bl, m[13], 0x5a827999, 8); el = rotl(el, 10) - bl = fn2(bl, cl, dl, el, al, m[1], 0x5a827999, 13); dl = rotl(dl, 10) - al = fn2(al, bl, cl, dl, el, m[10], 0x5a827999, 11); cl = rotl(cl, 10) - el = fn2(el, al, bl, cl, dl, m[6], 0x5a827999, 9); bl = rotl(bl, 10) - dl = fn2(dl, el, al, bl, cl, m[15], 0x5a827999, 7); al = rotl(al, 10) - cl = fn2(cl, dl, el, al, bl, m[3], 0x5a827999, 15); el = rotl(el, 10) - bl = fn2(bl, cl, dl, el, al, m[12], 0x5a827999, 7); dl = rotl(dl, 10) - al = fn2(al, bl, cl, dl, el, m[0], 0x5a827999, 12); cl = rotl(cl, 10) - el = fn2(el, al, bl, cl, dl, m[9], 0x5a827999, 15); bl = rotl(bl, 10) - dl = fn2(dl, el, al, bl, cl, m[5], 0x5a827999, 9); al = rotl(al, 10) - cl = fn2(cl, dl, el, al, bl, m[2], 0x5a827999, 11); el = rotl(el, 10) - bl = fn2(bl, cl, dl, el, al, m[14], 0x5a827999, 7); dl = rotl(dl, 10) - al = fn2(al, bl, cl, dl, el, m[11], 0x5a827999, 13); cl = rotl(cl, 10) - el = fn2(el, al, bl, cl, dl, m[8], 0x5a827999, 12); bl = rotl(bl, 10) - - // Mj = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12 - // K = 0x6ed9eba1 - // Sj = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5 - dl = fn3(dl, el, al, bl, cl, m[3], 0x6ed9eba1, 11); al = rotl(al, 10) - cl = fn3(cl, dl, el, al, bl, m[10], 0x6ed9eba1, 13); el = rotl(el, 10) - bl = fn3(bl, cl, dl, el, al, m[14], 0x6ed9eba1, 6); dl = rotl(dl, 10) - al = fn3(al, bl, cl, dl, el, m[4], 0x6ed9eba1, 7); cl = rotl(cl, 10) - el = fn3(el, al, bl, cl, dl, m[9], 0x6ed9eba1, 14); bl = rotl(bl, 10) - dl = fn3(dl, el, al, bl, cl, m[15], 0x6ed9eba1, 9); al = rotl(al, 10) - cl = fn3(cl, dl, el, al, bl, m[8], 0x6ed9eba1, 13); el = rotl(el, 10) - bl = fn3(bl, cl, dl, el, al, m[1], 0x6ed9eba1, 15); dl = rotl(dl, 10) - al = fn3(al, bl, cl, dl, el, m[2], 0x6ed9eba1, 14); cl = rotl(cl, 10) - el = fn3(el, al, bl, cl, dl, m[7], 0x6ed9eba1, 8); bl = rotl(bl, 10) - dl = fn3(dl, el, al, bl, cl, m[0], 0x6ed9eba1, 13); al = rotl(al, 10) - cl = fn3(cl, dl, el, al, bl, m[6], 0x6ed9eba1, 6); el = rotl(el, 10) - bl = fn3(bl, cl, dl, el, al, m[13], 0x6ed9eba1, 5); dl = rotl(dl, 10) - al = fn3(al, bl, cl, dl, el, m[11], 0x6ed9eba1, 12); cl = rotl(cl, 10) - el = fn3(el, al, bl, cl, dl, m[5], 0x6ed9eba1, 7); bl = rotl(bl, 10) - dl = fn3(dl, el, al, bl, cl, m[12], 0x6ed9eba1, 5); al = rotl(al, 10) - - // Mj = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 - // K = 0x8f1bbcdc - // Sj = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 - cl = fn4(cl, dl, el, al, bl, m[1], 0x8f1bbcdc, 11); el = rotl(el, 10) - bl = fn4(bl, cl, dl, el, al, m[9], 0x8f1bbcdc, 12); dl = rotl(dl, 10) - al = fn4(al, bl, cl, dl, el, m[11], 0x8f1bbcdc, 14); cl = rotl(cl, 10) - el = fn4(el, al, bl, cl, dl, m[10], 0x8f1bbcdc, 15); bl = rotl(bl, 10) - dl = fn4(dl, el, al, bl, cl, m[0], 0x8f1bbcdc, 14); al = rotl(al, 10) - cl = fn4(cl, dl, el, al, bl, m[8], 0x8f1bbcdc, 15); el = rotl(el, 10) - bl = fn4(bl, cl, dl, el, al, m[12], 0x8f1bbcdc, 9); dl = rotl(dl, 10) - al = fn4(al, bl, cl, dl, el, m[4], 0x8f1bbcdc, 8); cl = rotl(cl, 10) - el = fn4(el, al, bl, cl, dl, m[13], 0x8f1bbcdc, 9); bl = rotl(bl, 10) - dl = fn4(dl, el, al, bl, cl, m[3], 0x8f1bbcdc, 14); al = rotl(al, 10) - cl = fn4(cl, dl, el, al, bl, m[7], 0x8f1bbcdc, 5); el = rotl(el, 10) - bl = fn4(bl, cl, dl, el, al, m[15], 0x8f1bbcdc, 6); dl = rotl(dl, 10) - al = fn4(al, bl, cl, dl, el, m[14], 0x8f1bbcdc, 8); cl = rotl(cl, 10) - el = fn4(el, al, bl, cl, dl, m[5], 0x8f1bbcdc, 6); bl = rotl(bl, 10) - dl = fn4(dl, el, al, bl, cl, m[6], 0x8f1bbcdc, 5); al = rotl(al, 10) - cl = fn4(cl, dl, el, al, bl, m[2], 0x8f1bbcdc, 12); el = rotl(el, 10) - - // Mj = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 - // K = 0xa953fd4e - // Sj = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 - bl = fn5(bl, cl, dl, el, al, m[4], 0xa953fd4e, 9); dl = rotl(dl, 10) - al = fn5(al, bl, cl, dl, el, m[0], 0xa953fd4e, 15); cl = rotl(cl, 10) - el = fn5(el, al, bl, cl, dl, m[5], 0xa953fd4e, 5); bl = rotl(bl, 10) - dl = fn5(dl, el, al, bl, cl, m[9], 0xa953fd4e, 11); al = rotl(al, 10) - cl = fn5(cl, dl, el, al, bl, m[7], 0xa953fd4e, 6); el = rotl(el, 10) - bl = fn5(bl, cl, dl, el, al, m[12], 0xa953fd4e, 8); dl = rotl(dl, 10) - al = fn5(al, bl, cl, dl, el, m[2], 0xa953fd4e, 13); cl = rotl(cl, 10) - el = fn5(el, al, bl, cl, dl, m[10], 0xa953fd4e, 12); bl = rotl(bl, 10) - dl = fn5(dl, el, al, bl, cl, m[14], 0xa953fd4e, 5); al = rotl(al, 10) - cl = fn5(cl, dl, el, al, bl, m[1], 0xa953fd4e, 12); el = rotl(el, 10) - bl = fn5(bl, cl, dl, el, al, m[3], 0xa953fd4e, 13); dl = rotl(dl, 10) - al = fn5(al, bl, cl, dl, el, m[8], 0xa953fd4e, 14); cl = rotl(cl, 10) - el = fn5(el, al, bl, cl, dl, m[11], 0xa953fd4e, 11); bl = rotl(bl, 10) - dl = fn5(dl, el, al, bl, cl, m[6], 0xa953fd4e, 8); al = rotl(al, 10) - cl = fn5(cl, dl, el, al, bl, m[15], 0xa953fd4e, 5); el = rotl(el, 10) - bl = fn5(bl, cl, dl, el, al, m[13], 0xa953fd4e, 6); dl = rotl(dl, 10) - - var ar = this._a - var br = this._b - var cr = this._c - var dr = this._d - var er = this._e - - // M'j = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12 - // K' = 0x50a28be6 - // S'j = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6 - ar = fn5(ar, br, cr, dr, er, m[5], 0x50a28be6, 8); cr = rotl(cr, 10) - er = fn5(er, ar, br, cr, dr, m[14], 0x50a28be6, 9); br = rotl(br, 10) - dr = fn5(dr, er, ar, br, cr, m[7], 0x50a28be6, 9); ar = rotl(ar, 10) - cr = fn5(cr, dr, er, ar, br, m[0], 0x50a28be6, 11); er = rotl(er, 10) - br = fn5(br, cr, dr, er, ar, m[9], 0x50a28be6, 13); dr = rotl(dr, 10) - ar = fn5(ar, br, cr, dr, er, m[2], 0x50a28be6, 15); cr = rotl(cr, 10) - er = fn5(er, ar, br, cr, dr, m[11], 0x50a28be6, 15); br = rotl(br, 10) - dr = fn5(dr, er, ar, br, cr, m[4], 0x50a28be6, 5); ar = rotl(ar, 10) - cr = fn5(cr, dr, er, ar, br, m[13], 0x50a28be6, 7); er = rotl(er, 10) - br = fn5(br, cr, dr, er, ar, m[6], 0x50a28be6, 7); dr = rotl(dr, 10) - ar = fn5(ar, br, cr, dr, er, m[15], 0x50a28be6, 8); cr = rotl(cr, 10) - er = fn5(er, ar, br, cr, dr, m[8], 0x50a28be6, 11); br = rotl(br, 10) - dr = fn5(dr, er, ar, br, cr, m[1], 0x50a28be6, 14); ar = rotl(ar, 10) - cr = fn5(cr, dr, er, ar, br, m[10], 0x50a28be6, 14); er = rotl(er, 10) - br = fn5(br, cr, dr, er, ar, m[3], 0x50a28be6, 12); dr = rotl(dr, 10) - ar = fn5(ar, br, cr, dr, er, m[12], 0x50a28be6, 6); cr = rotl(cr, 10) - - // M'j = 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2 - // K' = 0x5c4dd124 - // S'j = 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11 - er = fn4(er, ar, br, cr, dr, m[6], 0x5c4dd124, 9); br = rotl(br, 10) - dr = fn4(dr, er, ar, br, cr, m[11], 0x5c4dd124, 13); ar = rotl(ar, 10) - cr = fn4(cr, dr, er, ar, br, m[3], 0x5c4dd124, 15); er = rotl(er, 10) - br = fn4(br, cr, dr, er, ar, m[7], 0x5c4dd124, 7); dr = rotl(dr, 10) - ar = fn4(ar, br, cr, dr, er, m[0], 0x5c4dd124, 12); cr = rotl(cr, 10) - er = fn4(er, ar, br, cr, dr, m[13], 0x5c4dd124, 8); br = rotl(br, 10) - dr = fn4(dr, er, ar, br, cr, m[5], 0x5c4dd124, 9); ar = rotl(ar, 10) - cr = fn4(cr, dr, er, ar, br, m[10], 0x5c4dd124, 11); er = rotl(er, 10) - br = fn4(br, cr, dr, er, ar, m[14], 0x5c4dd124, 7); dr = rotl(dr, 10) - ar = fn4(ar, br, cr, dr, er, m[15], 0x5c4dd124, 7); cr = rotl(cr, 10) - er = fn4(er, ar, br, cr, dr, m[8], 0x5c4dd124, 12); br = rotl(br, 10) - dr = fn4(dr, er, ar, br, cr, m[12], 0x5c4dd124, 7); ar = rotl(ar, 10) - cr = fn4(cr, dr, er, ar, br, m[4], 0x5c4dd124, 6); er = rotl(er, 10) - br = fn4(br, cr, dr, er, ar, m[9], 0x5c4dd124, 15); dr = rotl(dr, 10) - ar = fn4(ar, br, cr, dr, er, m[1], 0x5c4dd124, 13); cr = rotl(cr, 10) - er = fn4(er, ar, br, cr, dr, m[2], 0x5c4dd124, 11); br = rotl(br, 10) - - // M'j = 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13 - // K' = 0x6d703ef3 - // S'j = 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5 - dr = fn3(dr, er, ar, br, cr, m[15], 0x6d703ef3, 9); ar = rotl(ar, 10) - cr = fn3(cr, dr, er, ar, br, m[5], 0x6d703ef3, 7); er = rotl(er, 10) - br = fn3(br, cr, dr, er, ar, m[1], 0x6d703ef3, 15); dr = rotl(dr, 10) - ar = fn3(ar, br, cr, dr, er, m[3], 0x6d703ef3, 11); cr = rotl(cr, 10) - er = fn3(er, ar, br, cr, dr, m[7], 0x6d703ef3, 8); br = rotl(br, 10) - dr = fn3(dr, er, ar, br, cr, m[14], 0x6d703ef3, 6); ar = rotl(ar, 10) - cr = fn3(cr, dr, er, ar, br, m[6], 0x6d703ef3, 6); er = rotl(er, 10) - br = fn3(br, cr, dr, er, ar, m[9], 0x6d703ef3, 14); dr = rotl(dr, 10) - ar = fn3(ar, br, cr, dr, er, m[11], 0x6d703ef3, 12); cr = rotl(cr, 10) - er = fn3(er, ar, br, cr, dr, m[8], 0x6d703ef3, 13); br = rotl(br, 10) - dr = fn3(dr, er, ar, br, cr, m[12], 0x6d703ef3, 5); ar = rotl(ar, 10) - cr = fn3(cr, dr, er, ar, br, m[2], 0x6d703ef3, 14); er = rotl(er, 10) - br = fn3(br, cr, dr, er, ar, m[10], 0x6d703ef3, 13); dr = rotl(dr, 10) - ar = fn3(ar, br, cr, dr, er, m[0], 0x6d703ef3, 13); cr = rotl(cr, 10) - er = fn3(er, ar, br, cr, dr, m[4], 0x6d703ef3, 7); br = rotl(br, 10) - dr = fn3(dr, er, ar, br, cr, m[13], 0x6d703ef3, 5); ar = rotl(ar, 10) - - // M'j = 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 - // K' = 0x7a6d76e9 - // S'j = 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 - cr = fn2(cr, dr, er, ar, br, m[8], 0x7a6d76e9, 15); er = rotl(er, 10) - br = fn2(br, cr, dr, er, ar, m[6], 0x7a6d76e9, 5); dr = rotl(dr, 10) - ar = fn2(ar, br, cr, dr, er, m[4], 0x7a6d76e9, 8); cr = rotl(cr, 10) - er = fn2(er, ar, br, cr, dr, m[1], 0x7a6d76e9, 11); br = rotl(br, 10) - dr = fn2(dr, er, ar, br, cr, m[3], 0x7a6d76e9, 14); ar = rotl(ar, 10) - cr = fn2(cr, dr, er, ar, br, m[11], 0x7a6d76e9, 14); er = rotl(er, 10) - br = fn2(br, cr, dr, er, ar, m[15], 0x7a6d76e9, 6); dr = rotl(dr, 10) - ar = fn2(ar, br, cr, dr, er, m[0], 0x7a6d76e9, 14); cr = rotl(cr, 10) - er = fn2(er, ar, br, cr, dr, m[5], 0x7a6d76e9, 6); br = rotl(br, 10) - dr = fn2(dr, er, ar, br, cr, m[12], 0x7a6d76e9, 9); ar = rotl(ar, 10) - cr = fn2(cr, dr, er, ar, br, m[2], 0x7a6d76e9, 12); er = rotl(er, 10) - br = fn2(br, cr, dr, er, ar, m[13], 0x7a6d76e9, 9); dr = rotl(dr, 10) - ar = fn2(ar, br, cr, dr, er, m[9], 0x7a6d76e9, 12); cr = rotl(cr, 10) - er = fn2(er, ar, br, cr, dr, m[7], 0x7a6d76e9, 5); br = rotl(br, 10) - dr = fn2(dr, er, ar, br, cr, m[10], 0x7a6d76e9, 15); ar = rotl(ar, 10) - cr = fn2(cr, dr, er, ar, br, m[14], 0x7a6d76e9, 8); er = rotl(er, 10) - - // M'j = 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 - // K' = 0x00000000 - // S'j = 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 - br = fn1(br, cr, dr, er, ar, m[12], 0x00000000, 8); dr = rotl(dr, 10) - ar = fn1(ar, br, cr, dr, er, m[15], 0x00000000, 5); cr = rotl(cr, 10) - er = fn1(er, ar, br, cr, dr, m[10], 0x00000000, 12); br = rotl(br, 10) - dr = fn1(dr, er, ar, br, cr, m[4], 0x00000000, 9); ar = rotl(ar, 10) - cr = fn1(cr, dr, er, ar, br, m[1], 0x00000000, 12); er = rotl(er, 10) - br = fn1(br, cr, dr, er, ar, m[5], 0x00000000, 5); dr = rotl(dr, 10) - ar = fn1(ar, br, cr, dr, er, m[8], 0x00000000, 14); cr = rotl(cr, 10) - er = fn1(er, ar, br, cr, dr, m[7], 0x00000000, 6); br = rotl(br, 10) - dr = fn1(dr, er, ar, br, cr, m[6], 0x00000000, 8); ar = rotl(ar, 10) - cr = fn1(cr, dr, er, ar, br, m[2], 0x00000000, 13); er = rotl(er, 10) - br = fn1(br, cr, dr, er, ar, m[13], 0x00000000, 6); dr = rotl(dr, 10) - ar = fn1(ar, br, cr, dr, er, m[14], 0x00000000, 5); cr = rotl(cr, 10) - er = fn1(er, ar, br, cr, dr, m[0], 0x00000000, 15); br = rotl(br, 10) - dr = fn1(dr, er, ar, br, cr, m[3], 0x00000000, 13); ar = rotl(ar, 10) - cr = fn1(cr, dr, er, ar, br, m[9], 0x00000000, 11); er = rotl(er, 10) - br = fn1(br, cr, dr, er, ar, m[11], 0x00000000, 11); dr = rotl(dr, 10) - - // change state - var t = (this._b + cl + dr) | 0 - this._b = (this._c + dl + er) | 0 - this._c = (this._d + el + ar) | 0 - this._d = (this._e + al + br) | 0 - this._e = (this._a + bl + cr) | 0 - this._a = t -} - -RIPEMD160.prototype._digest = function () { - // create padding and handle blocks - this._block[this._blockOffset++] = 0x80 - if (this._blockOffset > 56) { - this._block.fill(0, this._blockOffset, 64) - this._update() - this._blockOffset = 0 - } - - this._block.fill(0, this._blockOffset, 56) - this._block.writeUInt32LE(this._length[0], 56) - this._block.writeUInt32LE(this._length[1], 60) - this._update() - - // produce result - var buffer = new Buffer(20) - buffer.writeInt32LE(this._a, 0) - buffer.writeInt32LE(this._b, 4) - buffer.writeInt32LE(this._c, 8) - buffer.writeInt32LE(this._d, 12) - buffer.writeInt32LE(this._e, 16) - return buffer -} - -function rotl (x, n) { - return (x << n) | (x >>> (32 - n)) -} - -function fn1 (a, b, c, d, e, m, k, s) { - return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0 -} - -function fn2 (a, b, c, d, e, m, k, s) { - return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0 -} - -function fn3 (a, b, c, d, e, m, k, s) { - return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0 -} - -function fn4 (a, b, c, d, e, m, k, s) { - return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0 -} - -function fn5 (a, b, c, d, e, m, k, s) { - return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0 -} - -module.exports = RIPEMD160 - -}).call(this,require("buffer").Buffer) - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","hash-base":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/hash-base/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js":[function(require,module,exports){ -arguments[4]["/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browserify/node_modules/safe-buffer/index.js"][0].apply(exports,arguments) -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/secure-random/lib/secure-random.js":[function(require,module,exports){ -(function (process,Buffer){ -!function(globals){ -'use strict' - -//*** UMD BEGIN -if (typeof define !== 'undefined' && define.amd) { //require.js / AMD - define([], function() { - return secureRandom - }) -} else if (typeof module !== 'undefined' && module.exports) { //CommonJS - module.exports = secureRandom -} else { //script / browser - globals.secureRandom = secureRandom -} -//*** UMD END - -//options.type is the only valid option -function secureRandom(count, options) { - options = options || {type: 'Array'} - //we check for process.pid to prevent browserify from tricking us - if (typeof process != 'undefined' && typeof process.pid == 'number') { - return nodeRandom(count, options) - } else { - var crypto = window.crypto || window.msCrypto - if (!crypto) throw new Error("Your browser does not support window.crypto.") - return browserRandom(count, options) - } -} - -function nodeRandom(count, options) { - var crypto = require('crypto') - var buf = crypto.randomBytes(count) - - switch (options.type) { - case 'Array': - return [].slice.call(buf) - case 'Buffer': - return buf - case 'Uint8Array': - var arr = new Uint8Array(count) - for (var i = 0; i < count; ++i) { arr[i] = buf.readUInt8(i) } - return arr - default: - throw new Error(options.type + " is unsupported.") - } -} - -function browserRandom(count, options) { - var nativeArr = new Uint8Array(count) - var crypto = window.crypto || window.msCrypto - crypto.getRandomValues(nativeArr) - - switch (options.type) { - case 'Array': - return [].slice.call(nativeArr) - case 'Buffer': - try { var b = new Buffer(1) } catch(e) { throw new Error('Buffer not supported in this environment. Use Node.js or Browserify for browser support.')} - return new Buffer(nativeArr) - case 'Uint8Array': - return nativeArr - default: - throw new Error(options.type + " is unsupported.") - } -} - -secureRandom.randomArray = function(byteCount) { - return secureRandom(byteCount, {type: 'Array'}) -} - -secureRandom.randomUint8Array = function(byteCount) { - return secureRandom(byteCount, {type: 'Uint8Array'}) -} - -secureRandom.randomBuffer = function(byteCount) { - return secureRandom(byteCount, {type: 'Buffer'}) -} - - -}(this); - -}).call(this,require('_process'),require("buffer").Buffer) - -},{"_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","crypto":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/browser-resolve/empty.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js":[function(require,module,exports){ -(function (Buffer){ -// prototype class for hash functions -function Hash (blockSize, finalSize) { - this._block = new Buffer(blockSize) - this._finalSize = finalSize - this._blockSize = blockSize - this._len = 0 - this._s = 0 -} - -Hash.prototype.update = function (data, enc) { - if (typeof data === 'string') { - enc = enc || 'utf8' - data = new Buffer(data, enc) - } - - var l = this._len += data.length - var s = this._s || 0 - var f = 0 - var buffer = this._block - - while (s < l) { - var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize)) - var ch = (t - f) - - for (var i = 0; i < ch; i++) { - buffer[(s % this._blockSize) + i] = data[i + f] - } - - s += ch - f += ch - - if ((s % this._blockSize) === 0) { - this._update(buffer) - } - } - this._s = s - - return this -} - -Hash.prototype.digest = function (enc) { - // Suppose the length of the message M, in bits, is l - var l = this._len * 8 - - // Append the bit 1 to the end of the message - this._block[this._len % this._blockSize] = 0x80 - - // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize - this._block.fill(0, this._len % this._blockSize + 1) - - if (l % (this._blockSize * 8) >= this._finalSize * 8) { - this._update(this._block) - this._block.fill(0) - } - - // to this append the block which is equal to the number l written in binary - // TODO: handle case where l is > Math.pow(2, 29) - this._block.writeInt32BE(l, this._blockSize - 4) - - var hash = this._update(this._block) || this._hash() - - return enc ? hash.toString(enc) : hash -} - -Hash.prototype._update = function () { - throw new Error('_update must be implemented by subclass') -} - -module.exports = Hash - -}).call(this,require("buffer").Buffer) - -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/index.js":[function(require,module,exports){ -var exports = module.exports = function SHA (algorithm) { - algorithm = algorithm.toLowerCase() - - var Algorithm = exports[algorithm] - if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)') - - return new Algorithm() -} - -exports.sha = require('./sha') -exports.sha1 = require('./sha1') -exports.sha224 = require('./sha224') -exports.sha256 = require('./sha256') -exports.sha384 = require('./sha384') -exports.sha512 = require('./sha512') - -},{"./sha":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha.js","./sha1":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha1.js","./sha224":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha224.js","./sha256":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha256.js","./sha384":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha384.js","./sha512":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha512.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha.js":[function(require,module,exports){ -(function (Buffer){ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined - * in FIPS PUB 180-1 - * This source code is derived from sha1.js of the same repository. - * The difference between SHA-0 and SHA-1 is just a bitwise rotate left - * operation was added. - */ - -var inherits = require('inherits') -var Hash = require('./hash') - -var K = [ - 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 -] - -var W = new Array(80) - -function Sha () { - this.init() - this._w = W - - Hash.call(this, 64, 56) -} - -inherits(Sha, Hash) - -Sha.prototype.init = function () { - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 - - return this -} - -function rotl5 (num) { - return (num << 5) | (num >>> 27) -} - -function rotl30 (num) { - return (num << 30) | (num >>> 2) -} - -function ft (s, b, c, d) { - if (s === 0) return (b & c) | ((~b) & d) - if (s === 2) return (b & c) | (b & d) | (c & d) - return b ^ c ^ d -} - -Sha.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16] - - for (var j = 0; j < 80; ++j) { - var s = ~~(j / 20) - var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 - - e = d - d = c - c = rotl30(b) - b = a - a = t - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 -} - -Sha.prototype._hash = function () { - var H = new Buffer(20) - - H.writeInt32BE(this._a | 0, 0) - H.writeInt32BE(this._b | 0, 4) - H.writeInt32BE(this._c | 0, 8) - H.writeInt32BE(this._d | 0, 12) - H.writeInt32BE(this._e | 0, 16) - - return H -} - -module.exports = Sha - -}).call(this,require("buffer").Buffer) - -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha1.js":[function(require,module,exports){ -(function (Buffer){ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined - * in FIPS PUB 180-1 - * Version 2.1a Copyright Paul Johnston 2000 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for details. - */ - -var inherits = require('inherits') -var Hash = require('./hash') - -var K = [ - 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0 -] - -var W = new Array(80) - -function Sha1 () { - this.init() - this._w = W - - Hash.call(this, 64, 56) -} - -inherits(Sha1, Hash) - -Sha1.prototype.init = function () { - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 - - return this -} - -function rotl1 (num) { - return (num << 1) | (num >>> 31) -} - -function rotl5 (num) { - return (num << 5) | (num >>> 27) -} - -function rotl30 (num) { - return (num << 30) | (num >>> 2) -} - -function ft (s, b, c, d) { - if (s === 0) return (b & c) | ((~b) & d) - if (s === 2) return (b & c) | (b & d) | (c & d) - return b ^ c ^ d -} - -Sha1.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]) - - for (var j = 0; j < 80; ++j) { - var s = ~~(j / 20) - var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0 - - e = d - d = c - c = rotl30(b) - b = a - a = t - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 -} - -Sha1.prototype._hash = function () { - var H = new Buffer(20) - - H.writeInt32BE(this._a | 0, 0) - H.writeInt32BE(this._b | 0, 4) - H.writeInt32BE(this._c | 0, 8) - H.writeInt32BE(this._d | 0, 12) - H.writeInt32BE(this._e | 0, 16) - - return H -} - -module.exports = Sha1 - -}).call(this,require("buffer").Buffer) - -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha224.js":[function(require,module,exports){ -(function (Buffer){ -/** - * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined - * in FIPS 180-2 - * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * - */ - -var inherits = require('inherits') -var Sha256 = require('./sha256') -var Hash = require('./hash') - -var W = new Array(64) - -function Sha224 () { - this.init() - - this._w = W // new Array(64) - - Hash.call(this, 64, 56) -} - -inherits(Sha224, Sha256) - -Sha224.prototype.init = function () { - this._a = 0xc1059ed8 - this._b = 0x367cd507 - this._c = 0x3070dd17 - this._d = 0xf70e5939 - this._e = 0xffc00b31 - this._f = 0x68581511 - this._g = 0x64f98fa7 - this._h = 0xbefa4fa4 - - return this -} - -Sha224.prototype._hash = function () { - var H = new Buffer(28) - - H.writeInt32BE(this._a, 0) - H.writeInt32BE(this._b, 4) - H.writeInt32BE(this._c, 8) - H.writeInt32BE(this._d, 12) - H.writeInt32BE(this._e, 16) - H.writeInt32BE(this._f, 20) - H.writeInt32BE(this._g, 24) - - return H -} - -module.exports = Sha224 - -}).call(this,require("buffer").Buffer) - -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","./sha256":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha256.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha256.js":[function(require,module,exports){ -(function (Buffer){ -/** - * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined - * in FIPS 180-2 - * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * - */ - -var inherits = require('inherits') -var Hash = require('./hash') - -var K = [ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 -] - -var W = new Array(64) - -function Sha256 () { - this.init() - - this._w = W // new Array(64) - - Hash.call(this, 64, 56) -} - -inherits(Sha256, Hash) - -Sha256.prototype.init = function () { - this._a = 0x6a09e667 - this._b = 0xbb67ae85 - this._c = 0x3c6ef372 - this._d = 0xa54ff53a - this._e = 0x510e527f - this._f = 0x9b05688c - this._g = 0x1f83d9ab - this._h = 0x5be0cd19 - - return this -} - -function ch (x, y, z) { - return z ^ (x & (y ^ z)) -} - -function maj (x, y, z) { - return (x & y) | (z & (x | y)) -} - -function sigma0 (x) { - return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10) -} - -function sigma1 (x) { - return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7) -} - -function gamma0 (x) { - return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3) -} - -function gamma1 (x) { - return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10) -} - -Sha256.prototype._update = function (M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - var f = this._f | 0 - var g = this._g | 0 - var h = this._h | 0 - - for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4) - for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0 - - for (var j = 0; j < 64; ++j) { - var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0 - var T2 = (sigma0(a) + maj(a, b, c)) | 0 - - h = g - g = f - f = e - e = (d + T1) | 0 - d = c - c = b - b = a - a = (T1 + T2) | 0 - } - - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 - this._f = (f + this._f) | 0 - this._g = (g + this._g) | 0 - this._h = (h + this._h) | 0 -} - -Sha256.prototype._hash = function () { - var H = new Buffer(32) - - H.writeInt32BE(this._a, 0) - H.writeInt32BE(this._b, 4) - H.writeInt32BE(this._c, 8) - H.writeInt32BE(this._d, 12) - H.writeInt32BE(this._e, 16) - H.writeInt32BE(this._f, 20) - H.writeInt32BE(this._g, 24) - H.writeInt32BE(this._h, 28) - - return H -} - -module.exports = Sha256 - -}).call(this,require("buffer").Buffer) - -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha384.js":[function(require,module,exports){ -(function (Buffer){ -var inherits = require('inherits') -var SHA512 = require('./sha512') -var Hash = require('./hash') - -var W = new Array(160) - -function Sha384 () { - this.init() - this._w = W - - Hash.call(this, 128, 112) -} - -inherits(Sha384, SHA512) - -Sha384.prototype.init = function () { - this._ah = 0xcbbb9d5d - this._bh = 0x629a292a - this._ch = 0x9159015a - this._dh = 0x152fecd8 - this._eh = 0x67332667 - this._fh = 0x8eb44a87 - this._gh = 0xdb0c2e0d - this._hh = 0x47b5481d - - this._al = 0xc1059ed8 - this._bl = 0x367cd507 - this._cl = 0x3070dd17 - this._dl = 0xf70e5939 - this._el = 0xffc00b31 - this._fl = 0x68581511 - this._gl = 0x64f98fa7 - this._hl = 0xbefa4fa4 - - return this -} - -Sha384.prototype._hash = function () { - var H = new Buffer(48) - - function writeInt64BE (h, l, offset) { - H.writeInt32BE(h, offset) - H.writeInt32BE(l, offset + 4) - } - - writeInt64BE(this._ah, this._al, 0) - writeInt64BE(this._bh, this._bl, 8) - writeInt64BE(this._ch, this._cl, 16) - writeInt64BE(this._dh, this._dl, 24) - writeInt64BE(this._eh, this._el, 32) - writeInt64BE(this._fh, this._fl, 40) - - return H -} - -module.exports = Sha384 - -}).call(this,require("buffer").Buffer) - -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","./sha512":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha512.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha512.js":[function(require,module,exports){ -(function (Buffer){ -var inherits = require('inherits') -var Hash = require('./hash') - -var K = [ - 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, - 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, - 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, - 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, - 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, - 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, - 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, - 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, - 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, - 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, - 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, - 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, - 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, - 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, - 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, - 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, - 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, - 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, - 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, - 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, - 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, - 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, - 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, - 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, - 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, - 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, - 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, - 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, - 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, - 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, - 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, - 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, - 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, - 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, - 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, - 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, - 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, - 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, - 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, - 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 -] - -var W = new Array(160) - -function Sha512 () { - this.init() - this._w = W - - Hash.call(this, 128, 112) -} - -inherits(Sha512, Hash) - -Sha512.prototype.init = function () { - this._ah = 0x6a09e667 - this._bh = 0xbb67ae85 - this._ch = 0x3c6ef372 - this._dh = 0xa54ff53a - this._eh = 0x510e527f - this._fh = 0x9b05688c - this._gh = 0x1f83d9ab - this._hh = 0x5be0cd19 - - this._al = 0xf3bcc908 - this._bl = 0x84caa73b - this._cl = 0xfe94f82b - this._dl = 0x5f1d36f1 - this._el = 0xade682d1 - this._fl = 0x2b3e6c1f - this._gl = 0xfb41bd6b - this._hl = 0x137e2179 - - return this -} - -function Ch (x, y, z) { - return z ^ (x & (y ^ z)) -} - -function maj (x, y, z) { - return (x & y) | (z & (x | y)) -} - -function sigma0 (x, xl) { - return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25) -} - -function sigma1 (x, xl) { - return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23) -} - -function Gamma0 (x, xl) { - return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7) -} - -function Gamma0l (x, xl) { - return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25) -} - -function Gamma1 (x, xl) { - return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6) -} - -function Gamma1l (x, xl) { - return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26) -} - -function getCarry (a, b) { - return (a >>> 0) < (b >>> 0) ? 1 : 0 -} - -Sha512.prototype._update = function (M) { - var W = this._w - - var ah = this._ah | 0 - var bh = this._bh | 0 - var ch = this._ch | 0 - var dh = this._dh | 0 - var eh = this._eh | 0 - var fh = this._fh | 0 - var gh = this._gh | 0 - var hh = this._hh | 0 - - var al = this._al | 0 - var bl = this._bl | 0 - var cl = this._cl | 0 - var dl = this._dl | 0 - var el = this._el | 0 - var fl = this._fl | 0 - var gl = this._gl | 0 - var hl = this._hl | 0 - - for (var i = 0; i < 32; i += 2) { - W[i] = M.readInt32BE(i * 4) - W[i + 1] = M.readInt32BE(i * 4 + 4) - } - for (; i < 160; i += 2) { - var xh = W[i - 15 * 2] - var xl = W[i - 15 * 2 + 1] - var gamma0 = Gamma0(xh, xl) - var gamma0l = Gamma0l(xl, xh) - - xh = W[i - 2 * 2] - xl = W[i - 2 * 2 + 1] - var gamma1 = Gamma1(xh, xl) - var gamma1l = Gamma1l(xl, xh) - - // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] - var Wi7h = W[i - 7 * 2] - var Wi7l = W[i - 7 * 2 + 1] - - var Wi16h = W[i - 16 * 2] - var Wi16l = W[i - 16 * 2 + 1] - - var Wil = (gamma0l + Wi7l) | 0 - var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0 - Wil = (Wil + gamma1l) | 0 - Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0 - Wil = (Wil + Wi16l) | 0 - Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0 - - W[i] = Wih - W[i + 1] = Wil - } - - for (var j = 0; j < 160; j += 2) { - Wih = W[j] - Wil = W[j + 1] - - var majh = maj(ah, bh, ch) - var majl = maj(al, bl, cl) - - var sigma0h = sigma0(ah, al) - var sigma0l = sigma0(al, ah) - var sigma1h = sigma1(eh, el) - var sigma1l = sigma1(el, eh) - - // t1 = h + sigma1 + ch + K[j] + W[j] - var Kih = K[j] - var Kil = K[j + 1] - - var chh = Ch(eh, fh, gh) - var chl = Ch(el, fl, gl) - - var t1l = (hl + sigma1l) | 0 - var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0 - t1l = (t1l + chl) | 0 - t1h = (t1h + chh + getCarry(t1l, chl)) | 0 - t1l = (t1l + Kil) | 0 - t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0 - t1l = (t1l + Wil) | 0 - t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0 - - // t2 = sigma0 + maj - var t2l = (sigma0l + majl) | 0 - var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0 - - hh = gh - hl = gl - gh = fh - gl = fl - fh = eh - fl = el - el = (dl + t1l) | 0 - eh = (dh + t1h + getCarry(el, dl)) | 0 - dh = ch - dl = cl - ch = bh - cl = bl - bh = ah - bl = al - al = (t1l + t2l) | 0 - ah = (t1h + t2h + getCarry(al, t1l)) | 0 - } - - this._al = (this._al + al) | 0 - this._bl = (this._bl + bl) | 0 - this._cl = (this._cl + cl) | 0 - this._dl = (this._dl + dl) | 0 - this._el = (this._el + el) | 0 - this._fl = (this._fl + fl) | 0 - this._gl = (this._gl + gl) | 0 - this._hl = (this._hl + hl) | 0 - - this._ah = (this._ah + ah + getCarry(this._al, al)) | 0 - this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0 - this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0 - this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0 - this._eh = (this._eh + eh + getCarry(this._el, el)) | 0 - this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0 - this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0 - this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0 -} - -Sha512.prototype._hash = function () { - var H = new Buffer(64) - - function writeInt64BE (h, l, offset) { - H.writeInt32BE(h, offset) - H.writeInt32BE(l, offset + 4) - } - - writeInt64BE(this._ah, this._al, 0) - writeInt64BE(this._bh, this._bl, 8) - writeInt64BE(this._ch, this._cl, 16) - writeInt64BE(this._dh, this._dl, 24) - writeInt64BE(this._eh, this._el, 32) - writeInt64BE(this._fh, this._fl, 40) - writeInt64BE(this._gh, this._gl, 48) - writeInt64BE(this._hh, this._hl, 56) - - return H -} - -module.exports = Sha512 - -}).call(this,require("buffer").Buffer) - -},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/stream-browserify/index.js":[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -module.exports = Stream; - -var EE = require('events').EventEmitter; -var inherits = require('inherits'); - -inherits(Stream, EE); -Stream.Readable = require('readable-stream/readable.js'); -Stream.Writable = require('readable-stream/writable.js'); -Stream.Duplex = require('readable-stream/duplex.js'); -Stream.Transform = require('readable-stream/transform.js'); -Stream.PassThrough = require('readable-stream/passthrough.js'); - -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; - - - -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. - -function Stream() { - EE.call(this); -} - -Stream.prototype.pipe = function(dest, options) { - var source = this; - - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } - - source.on('data', ondata); - - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } - - dest.on('drain', ondrain); - - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); - } - - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - - dest.end(); - } - - - function onclose() { - if (didOnEnd) return; - didOnEnd = true; - - if (typeof dest.destroy === 'function') dest.destroy(); - } - - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } - } - - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); - - source.removeListener('end', onend); - source.removeListener('close', onclose); - - source.removeListener('error', onerror); - dest.removeListener('error', onerror); - - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); - - dest.removeListener('close', cleanup); - } - - source.on('end', cleanup); - source.on('close', cleanup); - - dest.on('close', cleanup); - - dest.emit('pipe', source); - - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; - -},{"events":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/events/events.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","readable-stream/duplex.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/duplex-browser.js","readable-stream/passthrough.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/passthrough.js","readable-stream/readable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js","readable-stream/transform.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/transform.js","readable-stream/writable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/writable-browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/string_decoder/lib/string_decoder.js":[function(require,module,exports){ -'use strict'; - -var Buffer = require('buffer').Buffer; -var bufferShim = require('buffer-shims'); - -var isEncoding = Buffer.isEncoding || function (encoding) { - encoding = '' + encoding; - switch (encoding && encoding.toLowerCase()) { - case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': - return true; - default: - return false; - } -}; - -function _normalizeEncoding(enc) { - if (!enc) return 'utf8'; - var retried; - while (true) { - switch (enc) { - case 'utf8': - case 'utf-8': - return 'utf8'; - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return 'utf16le'; - case 'latin1': - case 'binary': - return 'latin1'; - case 'base64': - case 'ascii': - case 'hex': - return enc; - default: - if (retried) return; // undefined - enc = ('' + enc).toLowerCase(); - retried = true; - } - } -}; - -// Do not cache `Buffer.isEncoding` when checking encoding names as some -// modules monkey-patch it to support additional encodings -function normalizeEncoding(enc) { - var nenc = _normalizeEncoding(enc); - if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); - return nenc || enc; -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. -exports.StringDecoder = StringDecoder; -function StringDecoder(encoding) { - this.encoding = normalizeEncoding(encoding); - var nb; - switch (this.encoding) { - case 'utf16le': - this.text = utf16Text; - this.end = utf16End; - nb = 4; - break; - case 'utf8': - this.fillLast = utf8FillLast; - nb = 4; - break; - case 'base64': - this.text = base64Text; - this.end = base64End; - nb = 3; - break; - default: - this.write = simpleWrite; - this.end = simpleEnd; - return; - } - this.lastNeed = 0; - this.lastTotal = 0; - this.lastChar = bufferShim.allocUnsafe(nb); -} - -StringDecoder.prototype.write = function (buf) { - if (buf.length === 0) return ''; - var r; - var i; - if (this.lastNeed) { - r = this.fillLast(buf); - if (r === undefined) return ''; - i = this.lastNeed; - this.lastNeed = 0; - } else { - i = 0; - } - if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); - return r || ''; -}; - -StringDecoder.prototype.end = utf8End; - -// Returns only complete characters in a Buffer -StringDecoder.prototype.text = utf8Text; - -// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer -StringDecoder.prototype.fillLast = function (buf) { - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); - this.lastNeed -= buf.length; -}; - -// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a -// continuation byte. -function utf8CheckByte(byte) { - if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; - return -1; -} - -// Checks at most 3 bytes at the end of a Buffer in order to detect an -// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) -// needed to complete the UTF-8 character (if applicable) are returned. -function utf8CheckIncomplete(self, buf, i) { - var j = buf.length - 1; - if (j < i) return 0; - var nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 1; - return nb; - } - if (--j < i) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 2; - return nb; - } - if (--j < i) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) { - if (nb === 2) nb = 0;else self.lastNeed = nb - 3; - } - return nb; - } - return 0; -} - -// Validates as many continuation bytes for a multi-byte UTF-8 character as -// needed or are available. If we see a non-continuation byte where we expect -// one, we "replace" the validated continuation bytes we've seen so far with -// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding -// behavior. The continuation byte check is included three times in the case -// where all of the continuation bytes for a character exist in the same buffer. -// It is also done this way as a slight performance increase instead of using a -// loop. -function utf8CheckExtraBytes(self, buf, p) { - if ((buf[0] & 0xC0) !== 0x80) { - self.lastNeed = 0; - return '\ufffd'.repeat(p); - } - if (self.lastNeed > 1 && buf.length > 1) { - if ((buf[1] & 0xC0) !== 0x80) { - self.lastNeed = 1; - return '\ufffd'.repeat(p + 1); - } - if (self.lastNeed > 2 && buf.length > 2) { - if ((buf[2] & 0xC0) !== 0x80) { - self.lastNeed = 2; - return '\ufffd'.repeat(p + 2); - } - } - } -} - -// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. -function utf8FillLast(buf) { - var p = this.lastTotal - this.lastNeed; - var r = utf8CheckExtraBytes(this, buf, p); - if (r !== undefined) return r; - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, p, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, p, 0, buf.length); - this.lastNeed -= buf.length; -} - -// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a -// partial character, the character's bytes are buffered until the required -// number of bytes are available. -function utf8Text(buf, i) { - var total = utf8CheckIncomplete(this, buf, i); - if (!this.lastNeed) return buf.toString('utf8', i); - this.lastTotal = total; - var end = buf.length - (total - this.lastNeed); - buf.copy(this.lastChar, 0, end); - return buf.toString('utf8', i, end); -} - -// For UTF-8, a replacement character for each buffered byte of a (partial) -// character needs to be added to the output. -function utf8End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed); - return r; -} - -// UTF-16LE typically needs two bytes per character, but even if we have an even -// number of bytes available, we need to check if we end on a leading/high -// surrogate. In that case, we need to wait for the next two bytes in order to -// decode the last character properly. -function utf16Text(buf, i) { - if ((buf.length - i) % 2 === 0) { - var r = buf.toString('utf16le', i); - if (r) { - var c = r.charCodeAt(r.length - 1); - if (c >= 0xD800 && c <= 0xDBFF) { - this.lastNeed = 2; - this.lastTotal = 4; - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - return r.slice(0, -1); - } - } - return r; - } - this.lastNeed = 1; - this.lastTotal = 2; - this.lastChar[0] = buf[buf.length - 1]; - return buf.toString('utf16le', i, buf.length - 1); -} - -// For UTF-16LE we do not explicitly append special replacement characters if we -// end on a partial character, we simply let v8 handle that. -function utf16End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) { - var end = this.lastTotal - this.lastNeed; - return r + this.lastChar.toString('utf16le', 0, end); - } - return r; -} - -function base64Text(buf, i) { - var n = (buf.length - i) % 3; - if (n === 0) return buf.toString('base64', i); - this.lastNeed = 3 - n; - this.lastTotal = 3; - if (n === 1) { - this.lastChar[0] = buf[buf.length - 1]; - } else { - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - } - return buf.toString('base64', i, buf.length - n); -} - -function base64End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); - return r; -} - -// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) -function simpleWrite(buf) { - return buf.toString(this.encoding); -} - -function simpleEnd(buf) { - return buf && buf.length ? this.write(buf) : ''; -} -},{"buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","buffer-shims":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer-shims/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/timers-browserify/main.js":[function(require,module,exports){ -(function (setImmediate,clearImmediate){ -var nextTick = require('process/browser.js').nextTick; -var apply = Function.prototype.apply; -var slice = Array.prototype.slice; -var immediateIds = {}; -var nextImmediateId = 0; - -// DOM APIs, for completeness - -exports.setTimeout = function() { - return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); -}; -exports.setInterval = function() { - return new Timeout(apply.call(setInterval, window, arguments), clearInterval); -}; -exports.clearTimeout = -exports.clearInterval = function(timeout) { timeout.close(); }; - -function Timeout(id, clearFn) { - this._id = id; - this._clearFn = clearFn; -} -Timeout.prototype.unref = Timeout.prototype.ref = function() {}; -Timeout.prototype.close = function() { - this._clearFn.call(window, this._id); -}; - -// Does not start the time, just sets up the members needed. -exports.enroll = function(item, msecs) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = msecs; -}; - -exports.unenroll = function(item) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = -1; -}; - -exports._unrefActive = exports.active = function(item) { - clearTimeout(item._idleTimeoutId); - - var msecs = item._idleTimeout; - if (msecs >= 0) { - item._idleTimeoutId = setTimeout(function onTimeout() { - if (item._onTimeout) - item._onTimeout(); - }, msecs); - } -}; - -// That's not how node.js implements it but the exposed api is the same. -exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { - var id = nextImmediateId++; - var args = arguments.length < 2 ? false : slice.call(arguments, 1); - - immediateIds[id] = true; - - nextTick(function onNextTick() { - if (immediateIds[id]) { - // fn.call() is faster so we optimize for the common use-case - // @see http://jsperf.com/call-apply-segu - if (args) { - fn.apply(null, args); - } else { - fn.call(null); - } - // Prevent ids from leaking - exports.clearImmediate(id); - } - }); - - return id; -}; - -exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { - delete immediateIds[id]; -}; -}).call(this,require("timers").setImmediate,require("timers").clearImmediate) - -},{"process/browser.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","timers":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/timers-browserify/main.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util-deprecate/browser.js":[function(require,module,exports){ -(function (global){ - -/** - * Module exports. - */ - -module.exports = deprecate; - -/** - * Mark that a method should not be used. - * Returns a modified function which warns once by default. - * - * If `localStorage.noDeprecation = true` is set, then it is a no-op. - * - * If `localStorage.throwDeprecation = true` is set, then deprecated functions - * will throw an Error when invoked. - * - * If `localStorage.traceDeprecation = true` is set, then deprecated functions - * will invoke `console.trace()` instead of `console.error()`. - * - * @param {Function} fn - the function to deprecate - * @param {String} msg - the string to print to the console when `fn` is invoked - * @returns {Function} a new "deprecated" version of `fn` - * @api public - */ - -function deprecate (fn, msg) { - if (config('noDeprecation')) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (config('throwDeprecation')) { - throw new Error(msg); - } else if (config('traceDeprecation')) { - console.trace(msg); - } else { - console.warn(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -} - -/** - * Checks `localStorage` for boolean values for the given `name`. - * - * @param {String} name - * @returns {Boolean} - * @api private - */ - -function config (name) { - // accessing global.localStorage can trigger a DOMException in sandboxed iframes - try { - if (!global.localStorage) return false; - } catch (_) { - return false; - } - var val = global.localStorage[name]; - if (null == val) return false; - return String(val).toLowerCase() === 'true'; -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util/node_modules/inherits/inherits_browser.js":[function(require,module,exports){ -arguments[4]["/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"][0].apply(exports,arguments) -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util/support/isBufferBrowser.js":[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util/util.js":[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"./support/isBuffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util/support/isBufferBrowser.js","_process":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/process/browser.js","inherits":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/util/node_modules/inherits/inherits_browser.js"}]},{},["/home/sigve/Dev/Bitshares/bitsharesjs/dist/browser.js"])("/home/sigve/Dev/Bitshares/bitsharesjs/dist/browser.js") -}); - -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJkaXN0L2Jyb3dzZXIuanMiLCJkaXN0L2NoYWluL3NyYy9BY2NvdW50TG9naW4uanMiLCJkaXN0L2NoYWluL3NyYy9DaGFpblR5cGVzLmpzIiwiZGlzdC9jaGFpbi9zcmMvT2JqZWN0SWQuanMiLCJkaXN0L2NoYWluL3NyYy9UcmFuc2FjdGlvbkJ1aWxkZXIuanMiLCJkaXN0L2NoYWluL3NyYy9zdGF0ZS5qcyIsImRpc3QvZWNjL2luZGV4LmpzIiwiZGlzdC9lY2Mvc3JjL0JyYWluS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL0tleVV0aWxzLmpzIiwiZGlzdC9lY2Mvc3JjL1ByaXZhdGVLZXkuanMiLCJkaXN0L2VjYy9zcmMvUHVibGljS2V5LmpzIiwiZGlzdC9lY2Mvc3JjL2FkZHJlc3MuanMiLCJkaXN0L2VjYy9zcmMvYWVzLmpzIiwiZGlzdC9lY2Mvc3JjL2VjZHNhLmpzIiwiZGlzdC9lY2Mvc3JjL2Vjc2lnbmF0dXJlLmpzIiwiZGlzdC9lY2Mvc3JjL2VuZm9yY2VfdHlwZXMuanMiLCJkaXN0L2VjYy9zcmMvaGFzaC5qcyIsImRpc3QvZWNjL3NyYy9zaWduYXR1cmUuanMiLCJkaXN0L3NlcmlhbGl6ZXIvaW5kZXguanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL0Zhc3RQYXJzZXIuanMiLCJkaXN0L3NlcmlhbGl6ZXIvc3JjL1NlcmlhbGl6ZXJWYWxpZGF0aW9uLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9lcnJvcl93aXRoX2NhdXNlLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9vcGVyYXRpb25zLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy9zZXJpYWxpemVyLmpzIiwiZGlzdC9zZXJpYWxpemVyL3NyYy90ZW1wbGF0ZS5qcyIsImRpc3Qvc2VyaWFsaXplci9zcmMvdHlwZXMuanMiLCJub2RlX21vZHVsZXMvYXNzZXJ0L2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlLXgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JpZ2kvbGliL2JpZ2kuanMiLCJub2RlX21vZHVsZXMvYmlnaS9saWIvY29udmVydC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9iaWdpL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy9iaXRzaGFyZXNqcy13cy9janMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYml0c2hhcmVzanMtd3MvY2pzL3NyYy9BcGlJbnN0YW5jZXMuanMiLCJub2RlX21vZHVsZXMvYml0c2hhcmVzanMtd3MvY2pzL3NyYy9DaGFpbkNvbmZpZy5qcyIsIm5vZGVfbW9kdWxlcy9iaXRzaGFyZXNqcy13cy9janMvc3JjL0NoYWluV2ViU29ja2V0LmpzIiwibm9kZV9tb2R1bGVzL2JpdHNoYXJlc2pzLXdzL2Nqcy9zcmMvQ29ubmVjdGlvbk1hbmFnZXIuanMiLCJub2RlX21vZHVsZXMvYml0c2hhcmVzanMtd3MvY2pzL3NyYy9HcmFwaGVuZUFwaS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyLXJlc29sdmUvZW1wdHkuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvc2FmZS1idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JzNTgvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnVmZmVyLXNoaW1zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9ieXRlYnVmZmVyL2Rpc3QvYnl0ZWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9jaXBoZXItYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLXV0aWwtaXMvbGliL3V0aWwuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9tZDUuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhtYWMvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9jcmVhdGUtaG1hYy9sZWdhY3kuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2Flcy5qcyIsIm5vZGVfbW9kdWxlcy9jcnlwdG8tanMvY2lwaGVyLWNvcmUuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2NvcmUuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2VuYy1iYXNlNjQuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2VuYy1oZXguanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWpzL2V2cGtkZi5qcyIsIm5vZGVfbW9kdWxlcy9jcnlwdG8tanMvaG1hYy5qcyIsIm5vZGVfbW9kdWxlcy9jcnlwdG8tanMvbWQ1LmpzIiwibm9kZV9tb2R1bGVzL2NyeXB0by1qcy9zaGExLmpzIiwibm9kZV9tb2R1bGVzL2RlZXAtZXF1YWwvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZGVlcC1lcXVhbC9saWIvaXNfYXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL2RlZXAtZXF1YWwvbGliL2tleXMuanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9jdXJ2ZS5qcyIsIm5vZGVfbW9kdWxlcy9lY3VydmUvbGliL2N1cnZlcy5qc29uIiwibm9kZV9tb2R1bGVzL2VjdXJ2ZS9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZWN1cnZlL2xpYi9uYW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9lY3VydmUvbGliL3BvaW50LmpzIiwibm9kZV9tb2R1bGVzL2V2ZW50cy9ldmVudHMuanMiLCJub2RlX21vZHVsZXMvaGFzaC1iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9pcy1idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb25nL2Rpc3QvbG9uZy5qcyIsIm5vZGVfbW9kdWxlcy9tZDUuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbWQ1LmpzL25vZGVfbW9kdWxlcy9oYXNoLWJhc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcHJvY2Vzcy1uZXh0aWNrLWFyZ3MvaW5kZXguanMiLCJub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9kdXBsZXgtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fZHVwbGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fcmVhZGFibGUuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fd3JpdGFibGUuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QuanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9pbnRlcm5hbC9zdHJlYW1zL3N0cmVhbS1icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS93cml0YWJsZS1icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3JpcGVtZDE2MC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zZWN1cmUtcmFuZG9tL2xpYi9zZWN1cmUtcmFuZG9tLmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9oYXNoLmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhLmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGExLmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEyMjQuanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYTI1Ni5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMzg0LmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGE1MTIuanMiLCJub2RlX21vZHVsZXMvc3RyZWFtLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc3RyaW5nX2RlY29kZXIvbGliL3N0cmluZ19kZWNvZGVyLmpzIiwibm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCJub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy91dGlsL3N1cHBvcnQvaXNCdWZmZXJCcm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3V0aWwvdXRpbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyeUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM09BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDajJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3QrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDcitDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3ZPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNscUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvMkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3Z2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3pyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQy9GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeExBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3Q2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDckxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTs7QUNEQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTs7QUNEQTtBQUNBOzs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ25TQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzdGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN0SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDblFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDaFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFByaXZhdGVLZXk6IHJlcXVpcmUoXCIuL2VjYy9zcmMvUHJpdmF0ZUtleVwiKSxcbiAgICBQdWJsaWNLZXk6IHJlcXVpcmUoXCIuL2VjYy9zcmMvUHVibGljS2V5XCIpLFxuICAgIFNpZ25hdHVyZTogcmVxdWlyZShcIi4vZWNjL3NyYy9zaWduYXR1cmVcIiksXG4gICAga2V5OiByZXF1aXJlKFwiLi9lY2Mvc3JjL0tleVV0aWxzXCIpLFxuICAgIFRyYW5zYWN0aW9uQnVpbGRlcjogcmVxdWlyZShcIi4vY2hhaW4vc3JjL1RyYW5zYWN0aW9uQnVpbGRlclwiKSxcbiAgICBMb2dpbjogcmVxdWlyZShcIi4vY2hhaW4vc3JjL0FjY291bnRMb2dpblwiKSxcbiAgICBiaXRzaGFyZXNfd3M6IHJlcXVpcmUoXCJiaXRzaGFyZXNqcy13c1wiKSxcbiAgICBhZXM6IHJlcXVpcmUoXCIuL2VjYy9zcmMvYWVzXCIpXG59OyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX1ByaXZhdGVLZXkgPSByZXF1aXJlKFwiLi4vLi4vZWNjL3NyYy9Qcml2YXRlS2V5XCIpO1xuXG52YXIgX1ByaXZhdGVLZXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUHJpdmF0ZUtleSk7XG5cbnZhciBfS2V5VXRpbHMgPSByZXF1aXJlKFwiLi4vLi4vZWNjL3NyYy9LZXlVdGlsc1wiKTtcblxudmFyIF9LZXlVdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9LZXlVdGlscyk7XG5cbnZhciBfc3RhdGUgPSByZXF1aXJlKFwiLi9zdGF0ZVwiKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIF9rZXlDYWNoZVByaXYgPSB7fTtcbnZhciBfa2V5Q2FjaGVQdWIgPSB7fTtcblxudmFyIEFjY291bnRMb2dpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBBY2NvdW50TG9naW4oKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBY2NvdW50TG9naW4pO1xuXG4gICAgICAgIHZhciBzdGF0ZSA9IHsgbG9nZ2VkSW46IGZhbHNlLCByb2xlczogW1wiYWN0aXZlXCIsIFwib3duZXJcIiwgXCJtZW1vXCJdIH07XG4gICAgICAgIHRoaXMuZ2V0ID0gKDAsIF9zdGF0ZS5nZXQpKHN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXQgPSAoMCwgX3N0YXRlLnNldCkoc3RhdGUpO1xuXG4gICAgICAgIHRoaXMuc3VicyA9IHt9O1xuICAgIH1cblxuICAgIEFjY291bnRMb2dpbi5wcm90b3R5cGUuYWRkU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24gYWRkU3Vic2NyaXB0aW9uKGNiKSB7XG4gICAgICAgIHRoaXMuc3Vic1tjYl0gPSBjYjtcbiAgICB9O1xuXG4gICAgQWNjb3VudExvZ2luLnByb3RvdHlwZS5zZXRSb2xlcyA9IGZ1bmN0aW9uIHNldFJvbGVzKHJvbGVzKSB7XG4gICAgICAgIHRoaXMuc2V0KFwicm9sZXNcIiwgcm9sZXMpO1xuICAgIH07XG5cbiAgICBBY2NvdW50TG9naW4ucHJvdG90eXBlLmdlbmVyYXRlS2V5cyA9IGZ1bmN0aW9uIGdlbmVyYXRlS2V5cyhhY2NvdW50TmFtZSwgcGFzc3dvcmQsIHJvbGVzLCBwcmVmaXgpIHtcbiAgICAgICAgdmFyIHN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIGlmICghYWNjb3VudE5hbWUgfHwgIXBhc3N3b3JkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBY2NvdW50IG5hbWUgb3IgcGFzc3dvcmQgcmVxdWlyZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhc3N3b3JkLmxlbmd0aCA8IDEyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXNzd29yZCBtdXN0IGhhdmUgYXQgbGVhc3QgMTIgY2hhcmFjdGVyc1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwcml2S2V5cyA9IHt9O1xuICAgICAgICB2YXIgcHViS2V5cyA9IHt9O1xuXG4gICAgICAgIChyb2xlcyB8fCB0aGlzLmdldChcInJvbGVzXCIpKS5mb3JFYWNoKGZ1bmN0aW9uIChyb2xlKSB7XG4gICAgICAgICAgICB2YXIgc2VlZCA9IGFjY291bnROYW1lICsgcm9sZSArIHBhc3N3b3JkO1xuICAgICAgICAgICAgdmFyIHBrZXkgPSBfa2V5Q2FjaGVQcml2W3NlZWRdID8gX2tleUNhY2hlUHJpdltzZWVkXSA6IF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21TZWVkKF9LZXlVdGlsczIuZGVmYXVsdC5ub3JtYWxpemVfYnJhaW5LZXkoc2VlZCkpO1xuICAgICAgICAgICAgX2tleUNhY2hlUHJpdltzZWVkXSA9IHBrZXk7XG5cbiAgICAgICAgICAgIHByaXZLZXlzW3JvbGVdID0gcGtleTtcbiAgICAgICAgICAgIHB1YktleXNbcm9sZV0gPSBfa2V5Q2FjaGVQdWJbc2VlZF0gPyBfa2V5Q2FjaGVQdWJbc2VlZF0gOiBwa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcocHJlZml4KTtcblxuICAgICAgICAgICAgX2tleUNhY2hlUHViW3NlZWRdID0gcHViS2V5c1tyb2xlXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHsgcHJpdktleXM6IHByaXZLZXlzLCBwdWJLZXlzOiBwdWJLZXlzIH07XG4gICAgfTtcblxuICAgIEFjY291bnRMb2dpbi5wcm90b3R5cGUuY2hlY2tLZXlzID0gZnVuY3Rpb24gY2hlY2tLZXlzKF9yZWYpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgYWNjb3VudE5hbWUgPSBfcmVmLmFjY291bnROYW1lLFxuICAgICAgICAgICAgcGFzc3dvcmQgPSBfcmVmLnBhc3N3b3JkLFxuICAgICAgICAgICAgYXV0aHMgPSBfcmVmLmF1dGhzO1xuXG4gICAgICAgIGlmICghYWNjb3VudE5hbWUgfHwgIXBhc3N3b3JkIHx8ICFhdXRocykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2hlY2tLZXlzOiBNaXNzaW5nIGlucHV0c1wiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaGFzS2V5ID0gZmFsc2U7XG5cbiAgICAgICAgdmFyIF9sb29wID0gZnVuY3Rpb24gX2xvb3Aocm9sZSkge1xuICAgICAgICAgICAgdmFyIF9nZW5lcmF0ZUtleXMgPSBfdGhpcy5nZW5lcmF0ZUtleXMoYWNjb3VudE5hbWUsIHBhc3N3b3JkLCBbcm9sZV0pLFxuICAgICAgICAgICAgICAgIHByaXZLZXlzID0gX2dlbmVyYXRlS2V5cy5wcml2S2V5cyxcbiAgICAgICAgICAgICAgICBwdWJLZXlzID0gX2dlbmVyYXRlS2V5cy5wdWJLZXlzO1xuXG4gICAgICAgICAgICBhdXRoc1tyb2xlXS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgICBpZiAoa2V5WzBdID09PSBwdWJLZXlzW3JvbGVdKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldChyb2xlLCB7IHByaXY6IHByaXZLZXlzW3JvbGVdLCBwdWI6IHB1YktleXNbcm9sZV0gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yICh2YXIgcm9sZSBpbiBhdXRocykge1xuICAgICAgICAgICAgX2xvb3Aocm9sZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzS2V5KSB7XG4gICAgICAgICAgICB0aGlzLnNldChcIm5hbWVcIiwgYWNjb3VudE5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXQoXCJsb2dnZWRJblwiLCBoYXNLZXkpO1xuXG4gICAgICAgIHJldHVybiBoYXNLZXk7XG4gICAgfTtcblxuICAgIEFjY291bnRMb2dpbi5wcm90b3R5cGUuc2lnblRyYW5zYWN0aW9uID0gZnVuY3Rpb24gc2lnblRyYW5zYWN0aW9uKHRyKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBteUtleXMgPSB7fTtcbiAgICAgICAgdmFyIGhhc0tleSA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMuZ2V0KFwicm9sZXNcIikuZm9yRWFjaChmdW5jdGlvbiAocm9sZSkge1xuICAgICAgICAgICAgdmFyIG15S2V5ID0gX3RoaXMyLmdldChyb2xlKTtcbiAgICAgICAgICAgIGlmIChteUtleSkge1xuICAgICAgICAgICAgICAgIGhhc0tleSA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJhZGRpbmcgc2lnbmVyOlwiLCBteUtleS5wdWIpO1xuICAgICAgICAgICAgICAgIHRyLmFkZF9zaWduZXIobXlLZXkucHJpdiwgbXlLZXkucHViKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFoYXNLZXkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIllvdSBkbyBub3QgaGF2ZSBhbnkgcHJpdmF0ZSBrZXlzIHRvIHNpZ24gdGhpcyB0cmFuc2FjdGlvblwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQWNjb3VudExvZ2luO1xufSgpO1xuXG52YXIgYWNjb3VudExvZ2luID0gbmV3IEFjY291bnRMb2dpbigpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBhY2NvdW50TG9naW47XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xudmFyIENoYWluVHlwZXMgPSB7fTtcblxuQ2hhaW5UeXBlcy5yZXNlcnZlZF9zcGFjZXMgPSB7XG4gICAgcmVsYXRpdmVfcHJvdG9jb2xfaWRzOiAwLFxuICAgIHByb3RvY29sX2lkczogMSxcbiAgICBpbXBsZW1lbnRhdGlvbl9pZHM6IDJcbn07XG5cbkNoYWluVHlwZXMub2JqZWN0X3R5cGUgPSB7XG4gICAgbnVsbDogMCxcbiAgICBiYXNlOiAxLFxuICAgIGFjY291bnQ6IDIsXG4gICAgYXNzZXQ6IDMsXG4gICAgZm9yY2Vfc2V0dGxlbWVudDogNCxcbiAgICBjb21taXR0ZWVfbWVtYmVyOiA1LFxuICAgIHdpdG5lc3M6IDYsXG4gICAgbGltaXRfb3JkZXI6IDcsXG4gICAgY2FsbF9vcmRlcjogOCxcbiAgICBjdXN0b206IDksXG4gICAgcHJvcG9zYWw6IDEwLFxuICAgIG9wZXJhdGlvbl9oaXN0b3J5OiAxMSxcbiAgICB3aXRoZHJhd19wZXJtaXNzaW9uOiAxMixcbiAgICB2ZXN0aW5nX2JhbGFuY2U6IDEzLFxuICAgIHdvcmtlcjogMTQsXG4gICAgYmFsYW5jZTogMTVcbn07XG5cbkNoYWluVHlwZXMuaW1wbF9vYmplY3RfdHlwZSA9IHtcbiAgICBnbG9iYWxfcHJvcGVydHk6IDAsXG4gICAgZHluYW1pY19nbG9iYWxfcHJvcGVydHk6IDEsXG4gICAgaW5kZXhfbWV0YTogMixcbiAgICBhc3NldF9keW5hbWljX2RhdGE6IDMsXG4gICAgYXNzZXRfYml0YXNzZXRfZGF0YTogNCxcbiAgICBhY2NvdW50X2JhbGFuY2U6IDUsXG4gICAgYWNjb3VudF9zdGF0aXN0aWNzOiA2LFxuICAgIHRyYW5zYWN0aW9uOiA3LFxuICAgIGJsb2NrX3N1bW1hcnk6IDgsXG4gICAgYWNjb3VudF90cmFuc2FjdGlvbl9oaXN0b3J5OiA5LFxuICAgIGJsaW5kZWRfYmFsYW5jZTogMTAsXG4gICAgY2hhaW5fcHJvcGVydHk6IDExLFxuICAgIHdpdG5lc3Nfc2NoZWR1bGU6IDEyLFxuICAgIGJ1ZGdldF9yZWNvcmQ6IDEzXG59O1xuXG5DaGFpblR5cGVzLnZvdGVfdHlwZSA9IHtcbiAgICBjb21taXR0ZWU6IDAsXG4gICAgd2l0bmVzczogMSxcbiAgICB3b3JrZXI6IDJcbn07XG5cbkNoYWluVHlwZXMub3BlcmF0aW9ucyA9IHtcbiAgICB0cmFuc2ZlcjogMCxcbiAgICBsaW1pdF9vcmRlcl9jcmVhdGU6IDEsXG4gICAgbGltaXRfb3JkZXJfY2FuY2VsOiAyLFxuICAgIGNhbGxfb3JkZXJfdXBkYXRlOiAzLFxuICAgIGZpbGxfb3JkZXI6IDQsXG4gICAgYWNjb3VudF9jcmVhdGU6IDUsXG4gICAgYWNjb3VudF91cGRhdGU6IDYsXG4gICAgYWNjb3VudF93aGl0ZWxpc3Q6IDcsXG4gICAgYWNjb3VudF91cGdyYWRlOiA4LFxuICAgIGFjY291bnRfdHJhbnNmZXI6IDksXG4gICAgYXNzZXRfY3JlYXRlOiAxMCxcbiAgICBhc3NldF91cGRhdGU6IDExLFxuICAgIGFzc2V0X3VwZGF0ZV9iaXRhc3NldDogMTIsXG4gICAgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzOiAxMyxcbiAgICBhc3NldF9pc3N1ZTogMTQsXG4gICAgYXNzZXRfcmVzZXJ2ZTogMTUsXG4gICAgYXNzZXRfZnVuZF9mZWVfcG9vbDogMTYsXG4gICAgYXNzZXRfc2V0dGxlOiAxNyxcbiAgICBhc3NldF9nbG9iYWxfc2V0dGxlOiAxOCxcbiAgICBhc3NldF9wdWJsaXNoX2ZlZWQ6IDE5LFxuICAgIHdpdG5lc3NfY3JlYXRlOiAyMCxcbiAgICB3aXRuZXNzX3VwZGF0ZTogMjEsXG4gICAgcHJvcG9zYWxfY3JlYXRlOiAyMixcbiAgICBwcm9wb3NhbF91cGRhdGU6IDIzLFxuICAgIHByb3Bvc2FsX2RlbGV0ZTogMjQsXG4gICAgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGU6IDI1LFxuICAgIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlOiAyNixcbiAgICB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltOiAyNyxcbiAgICB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZTogMjgsXG4gICAgY29tbWl0dGVlX21lbWJlcl9jcmVhdGU6IDI5LFxuICAgIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlOiAzMCxcbiAgICBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyczogMzEsXG4gICAgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZTogMzIsXG4gICAgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3OiAzMyxcbiAgICB3b3JrZXJfY3JlYXRlOiAzNCxcbiAgICBjdXN0b206IDM1LFxuICAgIGFzc2VydDogMzYsXG4gICAgYmFsYW5jZV9jbGFpbTogMzcsXG4gICAgb3ZlcnJpZGVfdHJhbnNmZXI6IDM4LFxuICAgIHRyYW5zZmVyX3RvX2JsaW5kOiAzOSxcbiAgICBibGluZF90cmFuc2ZlcjogNDAsXG4gICAgdHJhbnNmZXJfZnJvbV9ibGluZDogNDEsXG4gICAgYXNzZXRfc2V0dGxlX2NhbmNlbDogNDIsXG4gICAgYXNzZXRfY2xhaW1fZmVlczogNDMsXG4gICAgZmJhX2Rpc3RyaWJ1dGU6IDQ0LFxuICAgIGJpZF9jb2xsYXRlcmFsOiA0NSxcbiAgICBleGVjdXRlX2JpZDogNDYsXG4gICAgYXNzZXRfY2xhaW1fcG9vbDogNDcsXG4gICAgYXNzZXRfdXBkYXRlX2lzc3VlcjogNDhcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IENoYWluVHlwZXM7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2J5dGVidWZmZXIgPSByZXF1aXJlKFwiYnl0ZWJ1ZmZlclwiKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbiA9IHJlcXVpcmUoXCIuLi8uLi9zZXJpYWxpemVyL3NyYy9TZXJpYWxpemVyVmFsaWRhdGlvblwiKTtcblxudmFyIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZXJpYWxpemVyVmFsaWRhdGlvbik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBEQl9NQVhfSU5TVEFOQ0VfSUQgPSBfYnl0ZWJ1ZmZlci5Mb25nLmZyb21OdW1iZXIoTWF0aC5wb3coMiwgNDgpIC0gMSk7XG5cbnZhciBPYmplY3RJZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBPYmplY3RJZChzcGFjZSwgdHlwZSwgaW5zdGFuY2UpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIE9iamVjdElkKTtcblxuICAgICAgICB0aGlzLnNwYWNlID0gc3BhY2U7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuaW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgICAgdmFyIGluc3RhbmNlX3N0cmluZyA9IHRoaXMuaW5zdGFuY2UudG9TdHJpbmcoKTtcbiAgICAgICAgdmFyIF9PYmplY3RJZCA9IHRoaXMuc3BhY2UgKyBcIi5cIiArIHRoaXMudHlwZSArIFwiLlwiICsgaW5zdGFuY2Vfc3RyaW5nO1xuICAgICAgICBpZiAoIV9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5pc19kaWdpdHMoaW5zdGFuY2Vfc3RyaW5nKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IChcIkludmFsaWQgb2JqZWN0IGlkIFwiICsgX09iamVjdElkKSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgT2JqZWN0SWQuZnJvbVN0cmluZyA9IGZ1bmN0aW9uIGZyb21TdHJpbmcodmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlLnNwYWNlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUudHlwZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLmluc3RhbmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBwYXJhbXMgPSBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9tYXRjaCgvXihbMC05XSspXFwuKFswLTldKylcXC4oWzAtOV0rKSQvLCBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQodmFsdWUsIFwiT2JqZWN0SWRcIiksIFwiT2JqZWN0SWRcIik7XG4gICAgICAgIHJldHVybiBuZXcgT2JqZWN0SWQocGFyc2VJbnQocGFyYW1zWzFdKSwgcGFyc2VJbnQocGFyYW1zWzJdKSwgX2J5dGVidWZmZXIuTG9uZy5mcm9tU3RyaW5nKHBhcmFtc1szXSkpO1xuICAgIH07XG5cbiAgICBPYmplY3RJZC5mcm9tTG9uZyA9IGZ1bmN0aW9uIGZyb21Mb25nKGxvbmcpIHtcbiAgICAgICAgdmFyIHNwYWNlID0gbG9uZy5zaGlmdFJpZ2h0KDU2KS50b0ludCgpO1xuICAgICAgICB2YXIgdHlwZSA9IGxvbmcuc2hpZnRSaWdodCg0OCkudG9JbnQoKSAmIDB4MDBmZjtcbiAgICAgICAgdmFyIGluc3RhbmNlID0gbG9uZy5hbmQoREJfTUFYX0lOU1RBTkNFX0lEKTtcbiAgICAgICAgcmV0dXJuIG5ldyBPYmplY3RJZChzcGFjZSwgdHlwZSwgaW5zdGFuY2UpO1xuICAgIH07XG5cbiAgICBPYmplY3RJZC5mcm9tQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdElkLmZyb21Mb25nKGIucmVhZFVpbnQ2NCgpKTtcbiAgICB9O1xuXG4gICAgT2JqZWN0SWQucHJvdG90eXBlLnRvTG9uZyA9IGZ1bmN0aW9uIHRvTG9uZygpIHtcbiAgICAgICAgcmV0dXJuIF9ieXRlYnVmZmVyLkxvbmcuZnJvbU51bWJlcih0aGlzLnNwYWNlKS5zaGlmdExlZnQoNTYpLm9yKF9ieXRlYnVmZmVyLkxvbmcuZnJvbU51bWJlcih0aGlzLnR5cGUpLnNoaWZ0TGVmdCg0OCkub3IodGhpcy5pbnN0YW5jZSkpO1xuICAgIH07XG5cbiAgICBPYmplY3RJZC5wcm90b3R5cGUuYXBwZW5kQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gYi53cml0ZVVpbnQ2NCh0aGlzLnRvTG9uZygpKTtcbiAgICB9O1xuXG4gICAgT2JqZWN0SWQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwYWNlICsgXCIuXCIgKyB0aGlzLnR5cGUgKyBcIi5cIiArIHRoaXMuaW5zdGFuY2UudG9TdHJpbmcoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIE9iamVjdElkO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBPYmplY3RJZDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZShcImFzc2VydFwiKTtcblxudmFyIF9hc3NlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0KTtcblxudmFyIF9lY2MgPSByZXF1aXJlKFwiLi4vLi4vZWNjXCIpO1xuXG52YXIgX3NlcmlhbGl6ZXIgPSByZXF1aXJlKFwiLi4vLi4vc2VyaWFsaXplclwiKTtcblxudmFyIF9iaXRzaGFyZXNqc1dzID0gcmVxdWlyZShcImJpdHNoYXJlc2pzLXdzXCIpO1xuXG52YXIgX0NoYWluVHlwZXMgPSByZXF1aXJlKFwiLi9DaGFpblR5cGVzXCIpO1xuXG52YXIgX0NoYWluVHlwZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5UeXBlcyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKFwic2FmZS1idWZmZXJcIikuQnVmZmVyO1xuXG52YXIgaGVhZF9ibG9ja190aW1lX3N0cmluZywgY29tbWl0dGVlX21pbl9yZXZpZXc7XG5cbnZhciBUcmFuc2FjdGlvbkJ1aWxkZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVHJhbnNhY3Rpb25CdWlsZGVyKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVHJhbnNhY3Rpb25CdWlsZGVyKTtcblxuICAgICAgICB0aGlzLnJlZl9ibG9ja19udW0gPSAwO1xuICAgICAgICB0aGlzLnJlZl9ibG9ja19wcmVmaXggPSAwO1xuICAgICAgICB0aGlzLmV4cGlyYXRpb24gPSAwO1xuICAgICAgICB0aGlzLm9wZXJhdGlvbnMgPSBbXTtcbiAgICAgICAgdGhpcy5zaWduYXR1cmVzID0gW107XG4gICAgICAgIHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5cyA9IFtdO1xuXG4gICAgICAgIC8vIHNlbWktcHJpdmF0ZSBtZXRob2QgYmluZGluZ3NcbiAgICAgICAgdGhpcy5fYnJvYWRjYXN0ID0gX2Jyb2FkY2FzdC5iaW5kKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAgICBAYXJnIHtzdHJpbmd9IG5hbWUgLSBsaWtlIFwidHJhbnNmZXJcIlxuICAgICAgICBAYXJnIHtvYmplY3R9IG9wZXJhdGlvbiAtIEpTT04gbWF0Y2hjaGluZyB0aGUgb3BlcmF0aW9uJ3MgZm9ybWF0XG4gICAgKi9cblxuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5hZGRfdHlwZV9vcGVyYXRpb24gPSBmdW5jdGlvbiBhZGRfdHlwZV9vcGVyYXRpb24obmFtZSwgb3BlcmF0aW9uKSB7XG4gICAgICAgIHRoaXMuYWRkX29wZXJhdGlvbih0aGlzLmdldF90eXBlX29wZXJhdGlvbihuYW1lLCBvcGVyYXRpb24pKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgICAgVGhpcyBkb2VzIGl0IGFsbDogc2V0IGZlZXMsIGZpbmFsaXplLCBzaWduLCBhbmQgYnJvYWRjYXN0IChpZiB3YW50ZWQpLlxuICAgICAgICAgQGFyZyB7Q29uZmlkZW50aWFsV2FsbGV0fSBjd2FsbGV0IC0gbXVzdCBiZSB1bmxvY2tlZCwgdXNlZCB0byBnYXRoZXIgc2lnbmluZyBrZXlzXG4gICAgICAgICBAYXJnIHthcnJheTxzdHJpbmc+fSBbc2lnbmVyX3B1YmtleXMgPSBudWxsXSAtIE9wdGlvbmFsIFtcIkdQSEFiYzlEZWYwLi4uXCIsIC4uLl0uICBUaGVzZSBhcmUgYWRkaXRpb25hbCBzaWduaW5nIGtleXMuICBTb21lIGJhbGFuY2UgY2xhaW1zIHJlcXVpcmUgcHJvcHJpdGFyeSBhZGRyZXNzIGZvcm1hdHMsIHRoZSB3aXRuZXNzIG5vZGUgY2FuJ3QgdGVsbCB1cyB3aGljaCBvbmVzIGFyZSBuZWVkZWQgc28gdGhleSBtdXN0IGJlIHBhc3NlZCBpbi4gIElmIHRoZSB3aXRuZXNzIG5vZGUgY2FuIGZpZ3VyZSBvdXQgYSBzaWduaW5nIGtleSAobW9zdGx5IGFsbCBvdGhlciB0cmFuc2FjdGlvbnMpLCBpdCBzaG91bGQgbm90IGJlIHBhc3NlZCBpbiBoZXJlLlxuICAgICAgICAgQGFyZyB7Ym9vbGVhbn0gW2Jyb2FkY2FzdCA9IGZhbHNlXVxuICAgICovXG5cblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUucHJvY2Vzc190cmFuc2FjdGlvbiA9IGZ1bmN0aW9uIHByb2Nlc3NfdHJhbnNhY3Rpb24oY3dhbGxldCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBzaWduZXJfcHVia2V5cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogbnVsbDtcbiAgICAgICAgdmFyIGJyb2FkY2FzdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG5cbiAgICAgICAgdmFyIHdhbGxldF9vYmplY3QgPSBjd2FsbGV0LndhbGxldC53YWxsZXRfb2JqZWN0O1xuICAgICAgICBpZiAoX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkICE9PSB3YWxsZXRfb2JqZWN0LmdldChcImNoYWluX2lkXCIpKSByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJNaXNtYXRjaGVkIGNoYWluX2lkOyBleHBlY3RpbmcgXCIgKyB3YWxsZXRfb2JqZWN0LmdldChcImNoYWluX2lkXCIpICsgXCIsIGJ1dCBnb3QgXCIgKyBfYml0c2hhcmVzanNXcy5BcGlzLmluc3RhbmNlKCkuY2hhaW5faWQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnNldF9yZXF1aXJlZF9mZWVzKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgc2lnbmVyX3B1YmtleXNfYWRkZWQgPSB7fTtcbiAgICAgICAgICAgIGlmIChzaWduZXJfcHVia2V5cykge1xuICAgICAgICAgICAgICAgIC8vIEJhbGFuY2UgY2xhaW1zIGFyZSBieSBhZGRyZXNzLCBvbmx5IHRoZSBwcml2YXRlXG4gICAgICAgICAgICAgICAgLy8ga2V5IGhvbGRlciBjYW4ga25vdyBhYm91dCB0aGVzZSBhZGRpdGlvbmFsXG4gICAgICAgICAgICAgICAgLy8gcG90ZW50aWFsIGtleXMuXG4gICAgICAgICAgICAgICAgdmFyIHB1YmtleXMgPSBjd2FsbGV0LmdldFB1YmtleXNfaGF2aW5nX1ByaXZhdGVLZXkoc2lnbmVyX3B1YmtleXMpO1xuICAgICAgICAgICAgICAgIGlmICghcHVia2V5cy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcihcIk1pc3Npbmcgc2lnbmluZyBrZXlcIik7XG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBwdWJrZXlzLCBfaXNBcnJheSA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yKSwgX2kgPSAwLCBfaXRlcmF0b3IgPSBfaXNBcnJheSA/IF9pdGVyYXRvciA6IF9pdGVyYXRvcltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgX3JlZjtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQXJyYXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaSA+PSBfaXRlcmF0b3IubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIF9yZWYgPSBfaXRlcmF0b3JbX2krK107XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfaSA9IF9pdGVyYXRvci5uZXh0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2kuZG9uZSkgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBfcmVmID0gX2kudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB2YXIgcHVia2V5X3N0cmluZyA9IF9yZWY7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIHByaXZhdGVfa2V5ID0gY3dhbGxldC5nZXRQcml2YXRlS2V5KHB1YmtleV9zdHJpbmcpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5hZGRfc2lnbmVyKHByaXZhdGVfa2V5LCBwdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgc2lnbmVyX3B1YmtleXNfYWRkZWRbcHVia2V5X3N0cmluZ10gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmdldF9wb3RlbnRpYWxfc2lnbmF0dXJlcygpLnRoZW4oZnVuY3Rpb24gKF9yZWYyKSB7XG4gICAgICAgICAgICAgICAgdmFyIHB1YmtleXMgPSBfcmVmMi5wdWJrZXlzLFxuICAgICAgICAgICAgICAgICAgICBhZGR5cyA9IF9yZWYyLmFkZHlzO1xuXG4gICAgICAgICAgICAgICAgdmFyIG15X3B1YmtleXMgPSBjd2FsbGV0LmdldFB1YmtleXNfaGF2aW5nX1ByaXZhdGVLZXkocHVia2V5cywgYWRkeXMpO1xuXG4gICAgICAgICAgICAgICAgLy97Ly9UZXN0aW5nIG9ubHksIGRvbid0IHNlbmQgQWxsIHB1YmxpYyBrZXlzIVxuICAgICAgICAgICAgICAgIC8vICAgIHZhciBwdWJrZXlzX2FsbCA9IFByaXZhdGVLZXlTdG9yZS5nZXRQdWJrZXlzKCkgLy8gQWxsIHB1YmxpYyBrZXlzXG4gICAgICAgICAgICAgICAgLy8gICAgdGhpcy5nZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyhwdWJrZXlzX2FsbCkudGhlbiggcmVxdWlyZWRfcHVia2V5X3N0cmluZ3MgPT5cbiAgICAgICAgICAgICAgICAvLyAgICAgICAgY29uc29sZS5sb2coJ2dldF9yZXF1aXJlZF9zaWduYXR1cmVzIGFsbFxcdCcscmVxdWlyZWRfcHVia2V5X3N0cmluZ3Muc29ydCgpLCBwdWJrZXlzX2FsbCkpXG4gICAgICAgICAgICAgICAgLy8gICAgdGhpcy5nZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyhteV9wdWJrZXlzKS50aGVuKCByZXF1aXJlZF9wdWJrZXlfc3RyaW5ncyA9PlxuICAgICAgICAgICAgICAgIC8vICAgICAgICBjb25zb2xlLmxvZygnZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMgbm9ybWFsXFx0JyxyZXF1aXJlZF9wdWJrZXlfc3RyaW5ncy5zb3J0KCksIHB1YmtleXMpKVxuICAgICAgICAgICAgICAgIC8vfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLmdldF9yZXF1aXJlZF9zaWduYXR1cmVzKG15X3B1YmtleXMpLnRoZW4oZnVuY3Rpb24gKHJlcXVpcmVkX3B1YmtleXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IHJlcXVpcmVkX3B1YmtleXMsIF9pc0FycmF5MiA9IEFycmF5LmlzQXJyYXkoX2l0ZXJhdG9yMiksIF9pMiA9IDAsIF9pdGVyYXRvcjIgPSBfaXNBcnJheTIgPyBfaXRlcmF0b3IyIDogX2l0ZXJhdG9yMltTeW1ib2wuaXRlcmF0b3JdKCk7Oykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9yZWYzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQXJyYXkyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pMiA+PSBfaXRlcmF0b3IyLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3JlZjMgPSBfaXRlcmF0b3IyW19pMisrXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2kyID0gX2l0ZXJhdG9yMi5uZXh0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pMi5kb25lKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcmVmMyA9IF9pMi52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9wdWJrZXlfc3RyaW5nID0gX3JlZjM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaWduZXJfcHVia2V5c19hZGRlZFtfcHVia2V5X3N0cmluZ10pIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByaXZhdGVfa2V5ID0gY3dhbGxldC5nZXRQcml2YXRlS2V5KF9wdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcHJpdmF0ZV9rZXkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBzaG91bGQgbm90IGhhcHBlbiwgZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMgd2lsbCBvbmx5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJuZWQga2V5cyBmcm9tIG15X3B1YmtleXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIHNpZ25pbmcga2V5IGZvciBcIiArIF9wdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLmFkZF9zaWduZXIocHJpdmF0ZV9rZXksIF9wdWJrZXlfc3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJyb2FkY2FzdCA/IF90aGlzLmJyb2FkY2FzdCgpIDogX3RoaXMuc2VyaWFsaXplKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKiBUeXBpY2FsbHkgdGhpcyBpcyBjYWxsZWQgYXV0b21hdGljYWxseSBqdXN0IHByaW9yIHRvIHNpZ25pbmcuICBPbmNlIGZpbmFsaXplZCB0aGlzIHRyYW5zYWN0aW9uIGNhbiBub3QgYmUgY2hhbmdlZC4gKi9cblxuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5maW5hbGl6ZSA9IGZ1bmN0aW9uIGZpbmFsaXplKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgaWYgKF90aGlzMi50cl9idWZmZXIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhbHJlYWR5IGZpbmFsaXplZFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzb2x2ZShfYml0c2hhcmVzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9vYmplY3RzXCIsIFtbXCIyLjEuMFwiXV0pLnRoZW4oZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgICAgICAgICBoZWFkX2Jsb2NrX3RpbWVfc3RyaW5nID0gclswXS50aW1lO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpczIuZXhwaXJhdGlvbiA9PT0gMCkgX3RoaXMyLmV4cGlyYXRpb24gPSBiYXNlX2V4cGlyYXRpb25fc2VjKCkgKyBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5leHBpcmVfaW5fc2VjcztcbiAgICAgICAgICAgICAgICBfdGhpczIucmVmX2Jsb2NrX251bSA9IHJbMF0uaGVhZF9ibG9ja19udW1iZXIgJiAweGZmZmY7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnJlZl9ibG9ja19wcmVmaXggPSBuZXcgQnVmZmVyKHJbMF0uaGVhZF9ibG9ja19pZCwgXCJoZXhcIikucmVhZFVJbnQzMkxFKDQpO1xuICAgICAgICAgICAgICAgIC8vREVCVUcgY29uc29sZS5sb2coXCJyZWZfYmxvY2tcIixAcmVmX2Jsb2NrX251bSxAcmVmX2Jsb2NrX3ByZWZpeCxyKVxuXG4gICAgICAgICAgICAgICAgdmFyIGl0ZXJhYmxlID0gX3RoaXMyLm9wZXJhdGlvbnM7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG9wOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgb3AgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzFdW1wiZmluYWxpemVcIl0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wWzFdLmZpbmFsaXplKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgX3RoaXMyLnRyX2J1ZmZlciA9IF9zZXJpYWxpemVyLm9wcy50cmFuc2FjdGlvbi50b0J1ZmZlcihfdGhpczIpO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqIEByZXR1cm4ge3N0cmluZ30gaGV4IHRyYW5zYWN0aW9uIElEICovXG5cblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuaWQgPSBmdW5jdGlvbiBpZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm90IGZpbmFsaXplZFwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX2VjYy5oYXNoLnNoYTI1Nih0aGlzLnRyX2J1ZmZlcikudG9TdHJpbmcoXCJoZXhcIikuc3Vic3RyaW5nKDAsIDQwKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICAgIFR5cGljYWxseSBvbmUgd2lsbCB1c2Uge0BsaW5rIHRoaXMuYWRkX3R5cGVfb3BlcmF0aW9ufSBpbnN0ZWFkLlxuICAgICAgICBAYXJnIHthcnJheX0gb3BlcmF0aW9uIC0gW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uXVxuICAgICovXG5cblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuYWRkX29wZXJhdGlvbiA9IGZ1bmN0aW9uIGFkZF9vcGVyYXRpb24ob3BlcmF0aW9uKSB7XG4gICAgICAgIGlmICh0aGlzLnRyX2J1ZmZlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWxyZWFkeSBmaW5hbGl6ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKG9wZXJhdGlvbiwgXCJvcGVyYXRpb25cIik7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvcGVyYXRpb24pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RpbmcgYXJyYXkgW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uXVwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wZXJhdGlvbnMucHVzaChvcGVyYXRpb24pO1xuICAgICAgICByZXR1cm47XG4gICAgfTtcblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuZ2V0X3R5cGVfb3BlcmF0aW9uID0gZnVuY3Rpb24gZ2V0X3R5cGVfb3BlcmF0aW9uKG5hbWUsIG9wZXJhdGlvbikge1xuICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFscmVhZHkgZmluYWxpemVkXCIpO1xuICAgICAgICB9XG4gICAgICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShuYW1lLCBcIm5hbWVcIik7XG4gICAgICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShvcGVyYXRpb24sIFwib3BlcmF0aW9uXCIpO1xuICAgICAgICB2YXIgX3R5cGUgPSBfc2VyaWFsaXplci5vcHNbbmFtZV07XG4gICAgICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShfdHlwZSwgXCJVbmtub3duIG9wZXJhdGlvbiBcIiArIG5hbWUpO1xuICAgICAgICB2YXIgb3BlcmF0aW9uX2lkID0gX0NoYWluVHlwZXMyLmRlZmF1bHQub3BlcmF0aW9uc1tfdHlwZS5vcGVyYXRpb25fbmFtZV07XG4gICAgICAgIGlmIChvcGVyYXRpb25faWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biBvcGVyYXRpb246IFwiICsgX3R5cGUub3BlcmF0aW9uX25hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghb3BlcmF0aW9uLmZlZSkge1xuICAgICAgICAgICAgb3BlcmF0aW9uLmZlZSA9IHsgYW1vdW50OiAwLCBhc3NldF9pZDogMCB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYW1lID09PSBcInByb3Bvc2FsX2NyZWF0ZVwiKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgKiBQcm9wb3NhbHMgaW52b2x2aW5nIHRoZSBjb21taXR0ZWUgYWNjb3VudCByZXF1aXJlIGEgcmV2aWV3XG4gICAgICAgICAgICAqIHBlcmlvZCB0byBiZSBzZXQsIGxvb2sgZm9yIHRoZW0gaGVyZVxuICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHZhciByZXF1aXJlc1JldmlldyA9IGZhbHNlLFxuICAgICAgICAgICAgICAgIGV4dHJhUmV2aWV3ID0gMDtcbiAgICAgICAgICAgIG9wZXJhdGlvbi5wcm9wb3NlZF9vcHMuZm9yRWFjaChmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgICAgICB2YXIgQ09NTUlUVEVfQUNDT1VOVCA9IDA7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IHZvaWQgMDtcblxuICAgICAgICAgICAgICAgIHN3aXRjaCAob3Aub3BbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJhbnNmZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFwiZnJvbVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSA2OiAvL2FjY291bnRfdXBkYXRlXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTc6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhc3NldF9zZXR0bGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFwiYWNjb3VudFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogLy8gYXNzZXRfY3JlYXRlXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTE6IC8vIGFzc2V0X3VwZGF0ZVxuICAgICAgICAgICAgICAgICAgICBjYXNlIDEyOiAvLyBhc3NldF91cGRhdGVfYml0YXNzZXRcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxMzogLy8gYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ6IC8vIGFzc2V0X2lzc3VlXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTg6IC8vIGFzc2V0X2dsb2JhbF9zZXR0bGVcbiAgICAgICAgICAgICAgICAgICAgY2FzZSA0MzpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzc2V0X2NsYWltX2ZlZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFwiaXNzdWVyXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIDE1OlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXNzZXRfcmVzZXJ2ZVxuICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gXCJwYXllclwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFzc2V0X2Z1bmRfZmVlX3Bvb2xcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFwiZnJvbV9hY2NvdW50XCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIDIyOiAvLyBwcm9wb3NhbF9jcmVhdGVcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyMzogLy8gcHJvcG9zYWxfdXBkYXRlXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9wb3NhbF9kZWxldGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFwiZmVlX3BheWluZ19hY2NvdW50XCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICBjYXNlIDMxOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVzUmV2aWV3ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dHJhUmV2aWV3ID0gNjAgKiA2MCAqIDI0ICogMTM7IC8vIE1ha2UgdGhlIHJldmlldyBwZXJpb2QgMiB3ZWVrcyB0b3RhbFxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChrZXkgaW4gb3Aub3BbMV0gJiYgb3Aub3BbMV1ba2V5XSA9PT0gQ09NTUlUVEVfQUNDT1VOVCkge1xuICAgICAgICAgICAgICAgICAgICByZXF1aXJlc1JldmlldyA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lIHx8IChvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lID0gYmFzZV9leHBpcmF0aW9uX3NlYygpICsgX2JpdHNoYXJlc2pzV3MuQ2hhaW5Db25maWcuZXhwaXJlX2luX3NlY3NfcHJvcG9zYWwpO1xuICAgICAgICAgICAgaWYgKHJlcXVpcmVzUmV2aWV3KSB7XG4gICAgICAgICAgICAgICAgb3BlcmF0aW9uLnJldmlld19wZXJpb2Rfc2Vjb25kcyA9IGV4dHJhUmV2aWV3ICsgTWF0aC5tYXgoY29tbWl0dGVlX21pbl9yZXZpZXcsIDI0ICogNjAgKiA2MCB8fCBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5yZXZpZXdfaW5fc2Vjc19jb21taXR0ZWUpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgKiBFeHBpcmF0aW9uIHRpbWUgbXVzdCBiZSBhdCBsZWFzdCBlcXVhbCB0b1xuICAgICAgICAgICAgICAgICogbm93ICsgcmV2aWV3X3BlcmlvZF9zZWNvbmRzLCBzbyB3ZSBhZGQgb25lIGhvdXIgdG8gbWFrZSBzdXJlXG4gICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBvcGVyYXRpb24uZXhwaXJhdGlvbl90aW1lICs9IDYwICogNjAgKyBleHRyYVJldmlldztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgb3BlcmF0aW9uX2luc3RhbmNlID0gX3R5cGUuZnJvbU9iamVjdChvcGVyYXRpb24pO1xuICAgICAgICByZXR1cm4gW29wZXJhdGlvbl9pZCwgb3BlcmF0aW9uX2luc3RhbmNlXTtcbiAgICB9O1xuXG4gICAgLyogb3B0aW9uYWw6IGZldGNoIHRoZSBjdXJyZW50IGhlYWQgYmxvY2sgKi9cblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUudXBkYXRlX2hlYWRfYmxvY2sgPSBmdW5jdGlvbiB1cGRhdGVfaGVhZF9ibG9jaygpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtfYml0c2hhcmVzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9vYmplY3RzXCIsIFtbXCIyLjAuMFwiXV0pLCBfYml0c2hhcmVzanNXcy5BcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcImdldF9vYmplY3RzXCIsIFtbXCIyLjEuMFwiXV0pXSkudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICB2YXIgZyA9IHJlc1swXSxcbiAgICAgICAgICAgICAgICByID0gcmVzWzFdO1xuXG4gICAgICAgICAgICBoZWFkX2Jsb2NrX3RpbWVfc3RyaW5nID0gclswXS50aW1lO1xuICAgICAgICAgICAgY29tbWl0dGVlX21pbl9yZXZpZXcgPSBnWzBdLnBhcmFtZXRlcnMuY29tbWl0dGVlX3Byb3Bvc2FsX3Jldmlld19wZXJpb2Q7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKiogb3B0aW9uYWw6IHRoZXJlIGlzIGEgZGVhZnVsdCBleHBpcmF0aW9uICovXG5cblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuc2V0X2V4cGlyZV9zZWNvbmRzID0gZnVuY3Rpb24gc2V0X2V4cGlyZV9zZWNvbmRzKHNlYykge1xuICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFscmVhZHkgZmluYWxpemVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmV4cGlyYXRpb24gPSBiYXNlX2V4cGlyYXRpb25fc2VjKCkgKyBzZWM7XG4gICAgfTtcblxuICAgIC8qIFdyYXBzIHRoaXMgdHJhbnNhY3Rpb24gaW4gYSBwcm9wb3NhbF9jcmVhdGUgdHJhbnNhY3Rpb24gKi9cblxuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5wcm9wb3NlID0gZnVuY3Rpb24gcHJvcG9zZShwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucykge1xuICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFscmVhZHkgZmluYWxpemVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5vcGVyYXRpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWRkIG9wZXJhdGlvbiBmaXJzdFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucywgXCJwcm9wb3NhbF9jcmVhdGVfb3B0aW9uc1wiKTtcbiAgICAgICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHByb3Bvc2FsX2NyZWF0ZV9vcHRpb25zLmZlZV9wYXlpbmdfYWNjb3VudCwgXCJwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucy5mZWVfcGF5aW5nX2FjY291bnRcIik7XG5cbiAgICAgICAgdmFyIHByb3Bvc2VkX29wcyA9IHRoaXMub3BlcmF0aW9ucy5tYXAoZnVuY3Rpb24gKG9wKSB7XG4gICAgICAgICAgICByZXR1cm4geyBvcDogb3AgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5vcGVyYXRpb25zID0gW107XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlcyA9IFtdO1xuICAgICAgICB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMgPSBbXTtcbiAgICAgICAgcHJvcG9zYWxfY3JlYXRlX29wdGlvbnMucHJvcG9zZWRfb3BzID0gcHJvcG9zZWRfb3BzO1xuICAgICAgICB0aGlzLmFkZF90eXBlX29wZXJhdGlvbihcInByb3Bvc2FsX2NyZWF0ZVwiLCBwcm9wb3NhbF9jcmVhdGVfb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBUcmFuc2FjdGlvbkJ1aWxkZXIucHJvdG90eXBlLmhhc19wcm9wb3NlZF9vcGVyYXRpb24gPSBmdW5jdGlvbiBoYXNfcHJvcG9zZWRfb3BlcmF0aW9uKCkge1xuICAgICAgICB2YXIgaGFzUHJvcG9zZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm9wZXJhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChcInByb3Bvc2VkX29wc1wiIGluIHRoaXMub3BlcmF0aW9uc1tpXVsxXSkge1xuICAgICAgICAgICAgICAgIGhhc1Byb3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBoYXNQcm9wb3NlZDtcbiAgICB9O1xuXG4gICAgLyoqIG9wdGlvbmFsOiB0aGUgZmVlcyBjYW4gYmUgb2J0YWluZWQgZnJvbSB0aGUgd2l0bmVzcyBub2RlICovXG5cblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuc2V0X3JlcXVpcmVkX2ZlZXMgPSBmdW5jdGlvbiBzZXRfcmVxdWlyZWRfZmVlcyhhc3NldF9pZCwgcmVtb3ZlRHVwbGljYXRlcykge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFscmVhZHkgZmluYWxpemVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5vcGVyYXRpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYWRkIG9wZXJhdGlvbnMgZmlyc3RcIik7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpc1Byb3Bvc2FsKG9wKSB7XG4gICAgICAgICAgICByZXR1cm4gb3BbMF0gPT09IDIyO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9wZXJhdGlvbnMgPSBbXTtcbiAgICAgICAgdmFyIHByb3Bvc2VkX29wcyA9IFtdO1xuICAgICAgICB2YXIgZmVlQXNzZXRzID0gW107XG4gICAgICAgIHZhciBwcm9wb3NhbEZlZUFzc2V0cyA9IFtdO1xuICAgICAgICB2YXIgcG90ZW50aWFsRHVwbGljYXRlcyA9IHt9O1xuICAgICAgICBmdW5jdGlvbiBnZXREdXBsaWNhdGVPcmlnaW5hbEluZGV4KG9wLCBpbmRleCkge1xuICAgICAgICAgICAgdmFyIGtleSA9IGdldE9wZXJhdGlvbktleShvcCk7XG4gICAgICAgICAgICB2YXIgZHVwbGljYXRlID0gcG90ZW50aWFsRHVwbGljYXRlc1trZXldO1xuICAgICAgICAgICAgaWYgKCEhZHVwbGljYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGR1cGxpY2F0ZS5vcmlnaW5hbCA9PT0gaW5kZXgpIHJldHVybiBpbmRleDtlbHNlIGlmIChkdXBsaWNhdGUuZHVwbGljYXRlcy5pbmRleE9mKGluZGV4KSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZS5vcmlnaW5hbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gZ2V0T3BlcmF0aW9uS2V5KG9wKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gbnVsbDtcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW1vRHVtbXkgPSBuZXcgQXJyYXkob3BbMV0ubWVtby5tZXNzYWdlLmxlbmd0aCArIDEpLmpvaW4oXCJhXCIpO1xuICAgICAgICAgICAgICAgICAgICBrZXkgPSBvcFswXSArIFwiX1wiICsgb3BbMV0uYW1vdW50LmFzc2V0X2lkICsgXCJfXCIgKyBtZW1vRHVtbXk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBvcDsgaSA8IHRoaXMub3BlcmF0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgb3AgPSB0aGlzLm9wZXJhdGlvbnNbaV07XG4gICAgICAgICAgICB2YXIgb3BPYmplY3QgPSBfc2VyaWFsaXplci5vcHMub3BlcmF0aW9uLnRvT2JqZWN0KG9wKTtcbiAgICAgICAgICAgIHZhciBpc0R1cGxpY2F0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHJlbW92ZUR1cGxpY2F0ZXMpIHtcbiAgICAgICAgICAgICAgICB2YXIga2V5ID0gZ2V0T3BlcmF0aW9uS2V5KG9wT2JqZWN0KTtcbiAgICAgICAgICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcG90ZW50aWFsRHVwbGljYXRlc1trZXldKSBwb3RlbnRpYWxEdXBsaWNhdGVzW2tleV0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogaSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cGxpY2F0ZXM6IFtdXG4gICAgICAgICAgICAgICAgICAgIH07ZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3RlbnRpYWxEdXBsaWNhdGVzW2tleV0uZHVwbGljYXRlcy5wdXNoKGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNEdXBsaWNhdGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICogSWYgdGhlIG9wZXJhdGlvbiBjcmVhdGVzIGEgcHJvcG9zYWwsIHdlIHNob3VsZCBjaGVjayB0aGUgZmVlIHBvb2xcbiAgICAgICAgICAgICogb2YgdGhlIHN1Z2dlc3RlZCBwcm9wb3NhbCBmZWUgYXNzZXRzIHRvIHByZXZlbnQgdXNlcnMgZnJvbSBjcmVhdGluZ1xuICAgICAgICAgICAgKiBwcm9wb3NhbHMgdGhhdCB3aWxsIG1vc3QgbGlrZWx5IGZhaWwgZHVlIHRvIGVtcHR5IGZlZSBwb29sc1xuICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChpc1Byb3Bvc2FsKG9wKSkge1xuICAgICAgICAgICAgICAgIG9wWzFdLnByb3Bvc2VkX29wcy5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wb3NhbCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcInByb3Bvc2VkIG9wXCIsIHByb3Bvc2FsLm9wWzFdLmZlZSk7XG4gICAgICAgICAgICAgICAgICAgIHByb3Bvc2VkX29wcy5wdXNoKHByb3Bvc2FsKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3Bvc2FsRmVlQXNzZXRzLmluZGV4T2YocHJvcG9zYWwub3BbMV0uZmVlLmFzc2V0X2lkKSA9PT0gLTEpIHByb3Bvc2FsRmVlQXNzZXRzLnB1c2goXCIxLjMuXCIgKyBwcm9wb3NhbC5vcFsxXS5mZWUuYXNzZXRfaWQpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0R1cGxpY2F0ZSkge1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbnMucHVzaChvcE9iamVjdCk7XG4gICAgICAgICAgICAgICAgaWYgKGZlZUFzc2V0cy5pbmRleE9mKG9wZXJhdGlvbnNbaV1bMV0uZmVlLmFzc2V0X2lkKSA9PT0gLTEpIGZlZUFzc2V0cy5wdXNoKG9wZXJhdGlvbnNbaV1bMV0uZmVlLmFzc2V0X2lkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghYXNzZXRfaWQpIHtcbiAgICAgICAgICAgIHZhciBvcDFfZmVlID0gb3BlcmF0aW9uc1swXVsxXS5mZWU7XG4gICAgICAgICAgICBpZiAob3AxX2ZlZSAmJiBvcDFfZmVlLmFzc2V0X2lkICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgYXNzZXRfaWQgPSBvcDFfZmVlLmFzc2V0X2lkO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NldF9pZCA9IFwiMS4zLjBcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qXG4gICAgICAgICogQWRkIHRoZSBwcm9wb3NhbCBmZWUgYXNzZXQgaWRzIHRvIGZlZUFzc2V0cyBoZXJlIHRvIGZldGNoIHRoZWlyXG4gICAgICAgICogZmVlcyBhbmQgZHluYW1pYyBvYmplY3RzXG4gICAgICAgICovXG4gICAgICAgIGlmIChwcm9wb3NhbEZlZUFzc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHByb3Bvc2FsRmVlQXNzZXRzLmZvckVhY2goZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZlZUFzc2V0cy5pbmRleE9mKGlkKSA9PT0gLTEpIGZlZUFzc2V0cy5wdXNoKGlkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcm9taXNlcyA9IFtdO1xuICAgICAgICBwcm9taXNlcy5wdXNoKFByb21pc2UuYWxsKGZlZUFzc2V0cy5tYXAoZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJnZXRfcmVxdWlyZWRfZmVlc1wiLCBbb3BlcmF0aW9ucywgaWRdKTtcbiAgICAgICAgfSkpLmNhdGNoKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJnZXRfcmVxdWlyZWRfZmVlcyBBUEkgZXJyb3I6IFwiLCBlcnIubWVzc2FnZSk7XG4gICAgICAgIH0pKTtcblxuICAgICAgICBpZiAoZmVlQXNzZXRzLmxlbmd0aCA+IDEgfHwgZmVlQXNzZXRzWzBdICE9PSBcIjEuMy4wXCIpIHtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAqIElmIHdlJ3JlIHBheWluZyB3aXRoIGFueSBhc3NldHMgb3RoZXIgdGhhbiBDT1JFLCB3ZSBuZWVkIHRvIGZldGNoXG4gICAgICAgICAgICAqIHRoZSBkeW5hbWljIGFzc2V0IG9iamVjdCBhbmQgY2hlY2sgdGhlIGZlZSBwb29sIG9mIHRob3NlIGFzc2V0cy5cbiAgICAgICAgICAgICogVGhlIGR5bmFtaWMgYXNzZXQgb2JqZWN0IGlkIGlzIGVxdWFsIHRvIHRoZSBhc3NldCBpZCBidXQgd2l0aFxuICAgICAgICAgICAgKiAyLjMueCBpbnN0ZWFkIG9mIDEuMy54XG4gICAgICAgICAgICAqL1xuICAgICAgICAgICAgdmFyIGR5bmFtaWNPYmplY3RJZHMgPSBmZWVBc3NldHMubWFwKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGEucmVwbGFjZSgvXjFcXC4vLCBcIjIuXCIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwcm9taXNlcy5wdXNoKF9iaXRzaGFyZXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKFwiZ2V0X3JlcXVpcmVkX2ZlZXNcIiwgW29wZXJhdGlvbnMsIFwiMS4zLjBcIl0pKTtcbiAgICAgICAgICAgIHByb21pc2VzLnB1c2goX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJnZXRfb2JqZWN0c1wiLCBbZHluYW1pY09iamVjdElkc10pKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihmdW5jdGlvbiAocmVzdWx0cykge1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICogYWxsRmVlcyBhbmQgY29yZUZlZXMgYXJlIGFycmF5cyBjb250YWluZyBmZWUgYW1vdW50cyBncm91cGVkIGJ5XG4gICAgICAgICAgICAqIGFzc2V0IGFuZCBmb3IgZWFjaCBvcGVyYXRpb24gaW4gb3BlcmF0aW9uc1xuICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHZhciBhbGxGZWVzID0gcmVzdWx0c1swXSxcbiAgICAgICAgICAgICAgICBjb3JlRmVlcyA9IHJlc3VsdHNbMV0sXG4gICAgICAgICAgICAgICAgZHluYW1pY09iamVjdHMgPSByZXN1bHRzWzJdO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICogSWYgb25lIG9mIHRoZSBkZXNpcmVkIGZlZSBhc3NldHMgaGFzIGFuIGludmFsaWQgY29yZSBleGNoYW5nZSByYXRlXG4gICAgICAgICAgICAqIGdldF9yZXF1aXJlZF9zaWduYXR1cmVzIHdpbGwgZmFpbCBhbmQgdGhlIHJlc3VsdCBmb3IgYWxsIGFzc2V0c1xuICAgICAgICAgICAgKiB3aWxsIGJlIHVuZGVmaW5lZCwgaWYgc28gd2UganVzdCBkZWZhdWx0IHRvIGNvcmVGZWVzXG4gICAgICAgICAgICAqL1xuXG4gICAgICAgICAgICBpZiAoYWxsRmVlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgYWxsRmVlcyA9IGNvcmVGZWVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICogSWYgdGhlIG9ubHkgZGVzaXJlZCBmZWUgYXNzZXQgaXMgQ09SRSwgY29yZUZlZXMgYXJlIG5vdCBmZXRjaGVkXG4gICAgICAgICAgICAqIGJ1dCBhcmUgZXF1YWwgdG8gYWxsRmVlc1xuICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICghY29yZUZlZXMpIHtcbiAgICAgICAgICAgICAgICBjb3JlRmVlcyA9IGFsbEZlZXNbMF07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qIENyZWF0ZSBhIG1hcCBvZiBmZWVzIGFuZCBwcm9wb3NhbCBmZWVzIGJ5IGFzc2V0IGlkICovXG4gICAgICAgICAgICB2YXIgZmVlc0J5QXNzZXQgPSB7fTtcbiAgICAgICAgICAgIHZhciBwcm9wb3NhbEZlZXNCeUFzc2V0ID0ge307XG4gICAgICAgICAgICBhbGxGZWVzLmZvckVhY2goZnVuY3Rpb24gKGZlZVNldCkge1xuICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJlZEZlZVNldCA9IGZlZVNldC5tYXAoZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgb3BlcmF0aW9uIGluY2x1ZGVzIGEgcHJvcG9zYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3Bvc2FsRmVlc0J5QXNzZXRbZlsxXVswXS5hc3NldF9pZF0gPSBmWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZbMF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGY7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRBc3NldElkID0gZmlsdGVyZWRGZWVTZXRbMF0uYXNzZXRfaWQ7XG5cbiAgICAgICAgICAgICAgICBmZWVzQnlBc3NldFtjdXJyZW50QXNzZXRJZF0gPSBmaWx0ZXJlZEZlZVNldDtcbiAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgLyogQ3JlYXRlIGEgbWFwIG9mIGZlZSBwb29scyBieSBhc3NldCBpZCovXG4gICAgICAgICAgICB2YXIgZmVlUG9vbE1hcCA9ICEhZHluYW1pY09iamVjdHMgPyBkeW5hbWljT2JqZWN0cy5yZWR1Y2UoZnVuY3Rpb24gKG1hcCwgb2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgbWFwW29iamVjdC5pZC5yZXBsYWNlKC9eMlxcLi8sIFwiMS5cIildID0gb2JqZWN0O1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXA7XG4gICAgICAgICAgICB9LCB7fSkgOiB7fTtcblxuICAgICAgICAgICAgdmFyIGZlZU1hcCA9IHt9O1xuICAgICAgICAgICAgdmFyIHByb3Bvc2FsRmVlTWFwID0ge307XG4gICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVGZWVNYXAobWFwLCBhc3NldF9pZCwgb3BJbmRleCwgY29yZV9mZWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXBbYXNzZXRfaWRdKSBtYXBbYXNzZXRfaWRdID0geyB0b3RhbDogMCwgb3BzOiBbXSB9O1xuICAgICAgICAgICAgICAgIGlmIChtYXBbYXNzZXRfaWRdLnByb3BJZHgpIG1hcFthc3NldF9pZF0ucHJvcElkeC5wdXNoKG9wSW5kZXgpO2Vsc2UgbWFwW2Fzc2V0X2lkXS5vcHMucHVzaChvcEluZGV4KTtcblxuICAgICAgICAgICAgICAgIGlmIChhc3NldF9pZCAhPT0gXCIxLjMuMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcFthc3NldF9pZF0udG90YWwgKz0gY29yZV9mZWVzLmxlbmd0aCA/IGNvcmVfZmVlc1tvcEluZGV4XS5hbW91bnQgOiBjb3JlX2ZlZXMuYW1vdW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiBfbG9vcChfaTMpIHtcbiAgICAgICAgICAgICAgICB2YXIgb3AgPSBvcGVyYXRpb25zW19pM107XG4gICAgICAgICAgICAgICAgdmFyIGZlZUFzc2V0SWQgPSBvcFsxXS5mZWUuYXNzZXRfaWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoaXNQcm9wb3NhbChvcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZmVlTWFwID0gdXBkYXRlRmVlTWFwKGZlZU1hcCwgZmVlQXNzZXRJZCwgX2kzLCBjb3JlRmVlc1tfaTNdWzBdKTtcblxuICAgICAgICAgICAgICAgICAgICBvcFsxXS5wcm9wb3NlZF9vcHMuZm9yRWFjaChmdW5jdGlvbiAocHJvcCwgeSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BGZWVBc3NldCA9IHByb3Aub3BbMV0uZmVlLmFzc2V0X2lkO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwcm9wb3NhbEZlZU1hcFtfaTNdKSBwcm9wb3NhbEZlZU1hcFtfaTNdID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXByb3Bvc2FsRmVlTWFwW19pM11bcHJvcEZlZUFzc2V0XSkgcHJvcG9zYWxGZWVNYXBbX2kzXVtwcm9wRmVlQXNzZXRdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wczogW19pM10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcElkeDogW11cbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3Bvc2FsRmVlTWFwW19pM10gPSB1cGRhdGVGZWVNYXAocHJvcG9zYWxGZWVNYXBbX2kzXSwgcHJvcEZlZUFzc2V0LCB5LCBjb3JlRmVlc1tfaTNdWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZmVlTWFwID0gdXBkYXRlRmVlTWFwKGZlZU1hcCwgZmVlQXNzZXRJZCwgX2kzLCBjb3JlRmVlc1tfaTNdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmb3IgKHZhciBfaTMgPSAwOyBfaTMgPCBvcGVyYXRpb25zLmxlbmd0aDsgX2kzKyspIHtcbiAgICAgICAgICAgICAgICBfbG9vcChfaTMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKiBDaGVjayBmZWUgcG9vbCBiYWxhbmNlcyBmb3IgcmVndWxhciBvcHMgKi9cbiAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrUG9vbEJhbGFuY2UoZmVlTWFwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFPYmplY3Qua2V5cyhmZWVNYXApLmxlbmd0aCkgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIHZhciBmaW5hbF9mZWVzID0gW107XG5cbiAgICAgICAgICAgICAgICB2YXIgX2xvb3AyID0gZnVuY3Rpb24gX2xvb3AyKGFzc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmZWVQb29sQmFsYW5jZSA9IGZlZVBvb2xNYXBbYXNzZXRdID8gcGFyc2VJbnQoZmVlUG9vbE1hcFthc3NldF0uZmVlX3Bvb2wsIDEwKSA6IDA7XG4gICAgICAgICAgICAgICAgICAgIC8qIEZlZSBwb29sIGJhbGFuY2UgaW5zdWZmaWNpZW50LCBkZWZhdWx0IHRvIGNvcmUqL1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmVlTWFwW2Fzc2V0XS50b3RhbCA+IGZlZVBvb2xCYWxhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmZWVNYXBbYXNzZXRdLm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChvcEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvcmVGZWVzW29wSW5kZXhdLmxlbmd0aCA9PT0gMiAmJiBcInByb3BJZHhcIiBpbiBmZWVNYXBbYXNzZXRdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFByb3Bvc2FsIG9wICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlZU1hcFthc3NldF0ucHJvcElkeC5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wX2lkeCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfZmVlc1twcm9wX2lkeF0gPSBjb3JlRmVlc1tvcEluZGV4XVsxXVtwcm9wX2lkeF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29yZUZlZXNbb3BJbmRleF0ubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX2ZlZXNbb3BJbmRleF0gPSBjb3JlRmVlc1tvcEluZGV4XVswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF9mZWVzW29wSW5kZXhdID0gY29yZUZlZXNbb3BJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBVc2UgdGhlIGRlc2lyZWQgZmVlIGFzc2V0ICovXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmZWVNYXBbYXNzZXRdLm9wcy5mb3JFYWNoKGZ1bmN0aW9uIChvcEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvcmVGZWVzW29wSW5kZXhdLmxlbmd0aCA9PT0gMiAmJiBcInByb3BJZHhcIiBpbiBmZWVNYXBbYXNzZXRdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlZU1hcFthc3NldF0ucHJvcElkeC5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wX2lkeCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfZmVlc1twcm9wX2lkeF0gPSBwcm9wb3NhbEZlZXNCeUFzc2V0W2Fzc2V0XVtwcm9wX2lkeF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsX2ZlZXNbb3BJbmRleF0gPSBmZWVzQnlBc3NldFthc3NldF1bb3BJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgYXNzZXQgaW4gZmVlTWFwKSB7XG4gICAgICAgICAgICAgICAgICAgIF9sb29wMihhc3NldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmaW5hbF9mZWVzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZmluYWxGZWVzID0gY2hlY2tQb29sQmFsYW5jZShmZWVNYXApO1xuXG4gICAgICAgICAgICB2YXIgZmluYWxQcm9wb3NhbEZlZXMgPSB7fTtcbiAgICAgICAgICAgIGZvciAodmFyIF9rZXkgaW4gcHJvcG9zYWxGZWVNYXApIHtcbiAgICAgICAgICAgICAgICBmaW5hbFByb3Bvc2FsRmVlc1tfa2V5XSA9IGNoZWNrUG9vbEJhbGFuY2UocHJvcG9zYWxGZWVNYXBbX2tleV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc2V0X2ZlZSA9IGZ1bmN0aW9uIHNldF9mZWUob3BlcmF0aW9uLCBvcEluZGV4KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvcGVyYXRpb24uZmVlIHx8IG9wZXJhdGlvbi5mZWUuYW1vdW50ID09PSAwIHx8IG9wZXJhdGlvbi5mZWUuYW1vdW50LnRvU3RyaW5nICYmIG9wZXJhdGlvbi5mZWUuYW1vdW50LnRvU3RyaW5nKCkgPT09IFwiMFwiIC8vIExvbmdcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmVEdXBsaWNhdGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9vcCA9IF9zZXJpYWxpemVyLm9wcy5vcGVyYXRpb24udG9PYmplY3QoX3RoaXMzLm9wZXJhdGlvbnNbb3BJbmRleF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbEluZGV4ID0gZ2V0RHVwbGljYXRlT3JpZ2luYWxJbmRleChfb3AsIG9wSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbEluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXQncyBhIGR1cGxpY2F0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24uZmVlID0gZmluYWxGZWVzW29yaWdpbmFsSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbi5mZWUgPSBmaW5hbEZlZXNbb3BJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24uZmVlID0gZmluYWxGZWVzW29wSW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9wZXJhdGlvbi5wcm9wb3NlZF9vcHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAgICAqIExvb3Agb3ZlciBwcm9wb3NlZF9vcHMgYW5kIGFzc2lnbiBmZWUgYXNzZXQgaWRzIGFzXG4gICAgICAgICAgICAgICAgICAgICogZGV0ZXJtaW5lZCBieSB0aGUgZmVlIHBvb2wgYmFsYW5jZSBjaGVjay4gSWYgdGhlIGJhbGFuY2VcbiAgICAgICAgICAgICAgICAgICAgKiBpcyBzdWZmaWNpZW50IHRoZSBhc3NldF9pZCBpcyBrZXB0LCBpZiBub3QgaXQgZGVmYXVsdHMgdG9cbiAgICAgICAgICAgICAgICAgICAgKiBcIjEuMy4wXCJcbiAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCBvcGVyYXRpb24ucHJvcG9zZWRfb3BzLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24ucHJvcG9zZWRfb3BzW3ldLm9wWzFdLmZlZS5hc3NldF9pZCA9IGZpbmFsUHJvcG9zYWxGZWVzW29wSW5kZXhdW3ldLmFzc2V0X2lkO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLyogV2UgYXBwbHkgdGhlIGZpbmFsIGZlZXMgdGhlIHRoZSBvcGVyYXRpb25zICovXG4gICAgICAgICAgICBmb3IgKHZhciBfaTQgPSAwOyBfaTQgPCBfdGhpczMub3BlcmF0aW9ucy5sZW5ndGg7IF9pNCsrKSB7XG4gICAgICAgICAgICAgICAgc2V0X2ZlZShfdGhpczMub3BlcmF0aW9uc1tfaTRdWzFdLCBfaTQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy9ERUJVRyBjb25zb2xlLmxvZygnLi4uIGdldF9yZXF1aXJlZF9mZWVzJyxvcGVyYXRpb25zLGFzc2V0X2lkLGZsYXRfZmVlcylcbiAgICB9O1xuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5nZXRfcG90ZW50aWFsX3NpZ25hdHVyZXMgPSBmdW5jdGlvbiBnZXRfcG90ZW50aWFsX3NpZ25hdHVyZXMoKSB7XG4gICAgICAgIHZhciB0cl9vYmplY3QgPSBfc2VyaWFsaXplci5vcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KHRoaXMpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW19iaXRzaGFyZXNqc1dzLkFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKFwiZ2V0X3BvdGVudGlhbF9zaWduYXR1cmVzXCIsIFt0cl9vYmplY3RdKSwgX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJnZXRfcG90ZW50aWFsX2FkZHJlc3Nfc2lnbmF0dXJlc1wiLCBbdHJfb2JqZWN0XSldKS50aGVuKGZ1bmN0aW9uIChyZXN1bHRzKSB7XG4gICAgICAgICAgICByZXR1cm4geyBwdWJrZXlzOiByZXN1bHRzWzBdLCBhZGR5czogcmVzdWx0c1sxXSB9O1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5nZXRfcmVxdWlyZWRfc2lnbmF0dXJlcyA9IGZ1bmN0aW9uIGdldF9yZXF1aXJlZF9zaWduYXR1cmVzKGF2YWlsYWJsZV9rZXlzKSB7XG4gICAgICAgIGlmICghYXZhaWxhYmxlX2tleXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdHJfb2JqZWN0ID0gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdCh0aGlzKTtcbiAgICAgICAgLy9ERUJVRyBjb25zb2xlLmxvZygnLi4uIHRyX29iamVjdCcsdHJfb2JqZWN0KVxuICAgICAgICByZXR1cm4gX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLmRiX2FwaSgpLmV4ZWMoXCJnZXRfcmVxdWlyZWRfc2lnbmF0dXJlc1wiLCBbdHJfb2JqZWN0LCBhdmFpbGFibGVfa2V5c10pLnRoZW4oZnVuY3Rpb24gKHJlcXVpcmVkX3B1YmxpY19rZXlzKSB7XG4gICAgICAgICAgICAvL0RFQlVHIGNvbnNvbGUubG9nKCcuLi4gZ2V0X3JlcXVpcmVkX3NpZ25hdHVyZXMnLHJlcXVpcmVkX3B1YmxpY19rZXlzKVxuICAgICAgICAgICAgcmV0dXJuIHJlcXVpcmVkX3B1YmxpY19rZXlzO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5hZGRfc2lnbmVyID0gZnVuY3Rpb24gYWRkX3NpZ25lcihwcml2YXRlX2tleSkge1xuICAgICAgICB2YXIgcHVibGljX2tleSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKTtcblxuICAgICAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkocHJpdmF0ZV9rZXkuZCwgXCJyZXF1aXJlZCBQcml2YXRlS2V5IG9iamVjdFwiKTtcblxuICAgICAgICBpZiAodGhpcy5zaWduZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImFscmVhZHkgc2lnbmVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcHVibGljX2tleS5RKSB7XG4gICAgICAgICAgICBwdWJsaWNfa2V5ID0gX2VjYy5QdWJsaWNLZXkuZnJvbVB1YmxpY0tleVN0cmluZyhwdWJsaWNfa2V5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBwcmV2ZW50IGR1cGxpY2F0ZXNcbiAgICAgICAgdmFyIHNwSGV4ID0gcHJpdmF0ZV9rZXkudG9IZXgoKTtcbiAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMyA9IHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5cywgX2lzQXJyYXkzID0gQXJyYXkuaXNBcnJheShfaXRlcmF0b3IzKSwgX2k1ID0gMCwgX2l0ZXJhdG9yMyA9IF9pc0FycmF5MyA/IF9pdGVyYXRvcjMgOiBfaXRlcmF0b3IzW1N5bWJvbC5pdGVyYXRvcl0oKTs7KSB7XG4gICAgICAgICAgICB2YXIgX3JlZjQ7XG5cbiAgICAgICAgICAgIGlmIChfaXNBcnJheTMpIHtcbiAgICAgICAgICAgICAgICBpZiAoX2k1ID49IF9pdGVyYXRvcjMubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICAgICAgICBfcmVmNCA9IF9pdGVyYXRvcjNbX2k1KytdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBfaTUgPSBfaXRlcmF0b3IzLm5leHQoKTtcbiAgICAgICAgICAgICAgICBpZiAoX2k1LmRvbmUpIGJyZWFrO1xuICAgICAgICAgICAgICAgIF9yZWY0ID0gX2k1LnZhbHVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgc3AgPSBfcmVmNDtcblxuICAgICAgICAgICAgaWYgKHNwWzBdLnRvSGV4KCkgPT09IHNwSGV4KSByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zaWduZXJfcHJpdmF0ZV9rZXlzLnB1c2goW3ByaXZhdGVfa2V5LCBwdWJsaWNfa2V5XSk7XG4gICAgfTtcblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24oKSB7XG4gICAgICAgIHZhciBjaGFpbl9pZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLmNoYWluX2lkO1xuXG4gICAgICAgIGlmICghdGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vdCBmaW5hbGl6ZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc2lnbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJhbHJlYWR5IHNpZ25lZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRyYW5zYWN0aW9uIHdhcyBub3Qgc2lnbmVkLiBEbyB5b3UgaGF2ZSBhIHByaXZhdGUga2V5PyBbbm9fc2lnbmVyc11cIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVuZCA9IHRoaXMuc2lnbmVyX3ByaXZhdGVfa2V5cy5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyAwIDwgZW5kID8gaSA8IGVuZCA6IGkgPiBlbmQ7IDAgPCBlbmQgPyBpKysgOiBpKyspIHtcbiAgICAgICAgICAgIHZhciBfc2lnbmVyX3ByaXZhdGVfa2V5cyQgPSB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXNbaV0sXG4gICAgICAgICAgICAgICAgcHJpdmF0ZV9rZXkgPSBfc2lnbmVyX3ByaXZhdGVfa2V5cyRbMF0sXG4gICAgICAgICAgICAgICAgcHVibGljX2tleSA9IF9zaWduZXJfcHJpdmF0ZV9rZXlzJFsxXTtcblxuICAgICAgICAgICAgdmFyIHNpZyA9IF9lY2MuU2lnbmF0dXJlLnNpZ25CdWZmZXIoQnVmZmVyLmNvbmNhdChbbmV3IEJ1ZmZlcihjaGFpbl9pZCwgXCJoZXhcIiksIHRoaXMudHJfYnVmZmVyXSksIHByaXZhdGVfa2V5LCBwdWJsaWNfa2V5KTtcbiAgICAgICAgICAgIHRoaXMuc2lnbmF0dXJlcy5wdXNoKHNpZy50b0J1ZmZlcigpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNpZ25lcl9wcml2YXRlX2tleXMgPSBbXTtcbiAgICAgICAgdGhpcy5zaWduZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgfTtcblxuICAgIFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUuc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKCkge1xuICAgICAgICByZXR1cm4gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdCh0aGlzKTtcbiAgICB9O1xuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KCkge1xuICAgICAgICByZXR1cm4gX3NlcmlhbGl6ZXIub3BzLnNpZ25lZF90cmFuc2FjdGlvbi50b09iamVjdCh0aGlzKTtcbiAgICB9O1xuXG4gICAgVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZS5icm9hZGNhc3QgPSBmdW5jdGlvbiBicm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjaykge1xuICAgICAgICB2YXIgX3RoaXM0ID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy50cl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9icm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjayk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maW5hbGl6ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczQuX2Jyb2FkY2FzdCh3YXNfYnJvYWRjYXN0X2NhbGxiYWNrKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBUcmFuc2FjdGlvbkJ1aWxkZXI7XG59KCk7XG5cbnZhciBiYXNlX2V4cGlyYXRpb25fc2VjID0gZnVuY3Rpb24gYmFzZV9leHBpcmF0aW9uX3NlYygpIHtcbiAgICB2YXIgaGVhZF9ibG9ja19zZWMgPSBNYXRoLmNlaWwoZ2V0SGVhZEJsb2NrRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApO1xuICAgIHZhciBub3dfc2VjID0gTWF0aC5jZWlsKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAvLyBUaGUgaGVhZCBibG9jayB0aW1lIHNob3VsZCBiZSB1cGRhdGVkIGV2ZXJ5IDMgc2Vjb25kcy4gIElmIGl0IGlzbid0XG4gICAgLy8gdGhlbiBoZWxwIHRoZSB0cmFuc2FjdGlvbiB0byBleHBpcmUgKHVzZSBoZWFkX2Jsb2NrX3NlYylcbiAgICBpZiAobm93X3NlYyAtIGhlYWRfYmxvY2tfc2VjID4gMzApIHtcbiAgICAgICAgcmV0dXJuIGhlYWRfYmxvY2tfc2VjO1xuICAgIH1cbiAgICAvLyBJZiB0aGUgdXNlcidzIGNsb2NrIGlzIHZlcnkgZmFyIGJlaGluZCwgdXNlIHRoZSBoZWFkIGJsb2NrIHRpbWUuXG4gICAgcmV0dXJuIE1hdGgubWF4KG5vd19zZWMsIGhlYWRfYmxvY2tfc2VjKTtcbn07XG5cbmZ1bmN0aW9uIF9icm9hZGNhc3Qod2FzX2Jyb2FkY2FzdF9jYWxsYmFjaykge1xuICAgIHZhciBfdGhpczUgPSB0aGlzO1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgaWYgKCFfdGhpczUuc2lnbmVkKSB7XG4gICAgICAgICAgICBfdGhpczUuc2lnbigpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghX3RoaXM1LnRyX2J1ZmZlcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm90IGZpbmFsaXplZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIV90aGlzNS5zaWduYXR1cmVzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm90IHNpZ25lZFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIV90aGlzNS5vcGVyYXRpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm8gb3BlcmF0aW9uc1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0cl9vYmplY3QgPSBfc2VyaWFsaXplci5vcHMuc2lnbmVkX3RyYW5zYWN0aW9uLnRvT2JqZWN0KF90aGlzNSk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCcuLi4gYnJvYWRjYXN0X3RyYW5zYWN0aW9uX3dpdGhfY2FsbGJhY2sgISEhJylcbiAgICAgICAgX2JpdHNoYXJlc2pzV3MuQXBpcy5pbnN0YW5jZSgpLm5ldHdvcmtfYXBpKCkuZXhlYyhcImJyb2FkY2FzdF90cmFuc2FjdGlvbl93aXRoX2NhbGxiYWNrXCIsIFtmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXMpO1xuICAgICAgICB9LCB0cl9vYmplY3RdKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJy4uLiBicm9hZGNhc3Qgc3VjY2Vzcywgd2FpdGluZyBmb3IgY2FsbGJhY2snKVxuICAgICAgICAgICAgaWYgKHdhc19icm9hZGNhc3RfY2FsbGJhY2spIHdhc19icm9hZGNhc3RfY2FsbGJhY2soKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyBtYXkgYmUgcmVkdW5kYW50IGZvciBuZXR3b3JrIGVycm9ycywgb3RoZXIgZXJyb3JzIGNvdWxkIG9jY3VyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICAgICAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IobWVzc2FnZSArIFwiXFxuXCIgKyBcImJpdHNoYXJlcy1jcnlwdG8gXCIgKyBcIiBkaWdlc3QgXCIgKyBfZWNjLmhhc2guc2hhMjU2KF90aGlzNS50cl9idWZmZXIpLnRvU3RyaW5nKFwiaGV4XCIpICsgXCIgdHJhbnNhY3Rpb24gXCIgKyBfdGhpczUudHJfYnVmZmVyLnRvU3RyaW5nKFwiaGV4XCIpICsgXCIgXCIgKyBKU09OLnN0cmluZ2lmeSh0cl9vYmplY3QpKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEhlYWRCbG9ja0RhdGUoKSB7XG4gICAgcmV0dXJuIHRpbWVTdHJpbmdUb0RhdGUoaGVhZF9ibG9ja190aW1lX3N0cmluZyk7XG59XG5cbmZ1bmN0aW9uIHRpbWVTdHJpbmdUb0RhdGUodGltZV9zdHJpbmcpIHtcbiAgICBpZiAoIXRpbWVfc3RyaW5nKSByZXR1cm4gbmV3IERhdGUoXCIxOTcwLTAxLTAxVDAwOjAwOjAwLjAwMFpcIik7XG4gICAgaWYgKCEvWiQvLnRlc3QodGltZV9zdHJpbmcpKVxuICAgICAgICAvL2RvZXMgbm90IGVuZCBpbiBaXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9ub21leC9ncmFwaGVuZS9pc3N1ZXMvMzY4XG4gICAgICAgIHRpbWVfc3RyaW5nID0gdGltZV9zdHJpbmcgKyBcIlpcIjtcbiAgICByZXR1cm4gbmV3IERhdGUodGltZV9zdHJpbmcpO1xufVxuXG5leHBvcnRzLmRlZmF1bHQgPSBUcmFuc2FjdGlvbkJ1aWxkZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZnVuY3Rpb24gZ2V0KHN0YXRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIHN0YXRlW2tleV0gfHwgXCJcIjtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBzZXQoc3RhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgICAgc3RhdGVba2V5XSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xufVxuXG5leHBvcnRzLmdldCA9IGdldDtcbmV4cG9ydHMuc2V0ID0gc2V0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5rZXkgPSBleHBvcnRzLmhhc2ggPSBleHBvcnRzLmJyYWluS2V5ID0gZXhwb3J0cy5TaWduYXR1cmUgPSBleHBvcnRzLlB1YmxpY0tleSA9IGV4cG9ydHMuUHJpdmF0ZUtleSA9IGV4cG9ydHMuQWVzID0gZXhwb3J0cy5BZGRyZXNzID0gdW5kZWZpbmVkO1xuXG52YXIgX2FkZHJlc3MgPSByZXF1aXJlKFwiLi9zcmMvYWRkcmVzc1wiKTtcblxudmFyIF9hZGRyZXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3MpO1xuXG52YXIgX2FlcyA9IHJlcXVpcmUoXCIuL3NyYy9hZXNcIik7XG5cbnZhciBfYWVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Flcyk7XG5cbnZhciBfUHJpdmF0ZUtleSA9IHJlcXVpcmUoXCIuL3NyYy9Qcml2YXRlS2V5XCIpO1xuXG52YXIgX1ByaXZhdGVLZXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUHJpdmF0ZUtleSk7XG5cbnZhciBfUHVibGljS2V5ID0gcmVxdWlyZShcIi4vc3JjL1B1YmxpY0tleVwiKTtcblxudmFyIF9QdWJsaWNLZXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUHVibGljS2V5KTtcblxudmFyIF9zaWduYXR1cmUgPSByZXF1aXJlKFwiLi9zcmMvc2lnbmF0dXJlXCIpO1xuXG52YXIgX3NpZ25hdHVyZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9zaWduYXR1cmUpO1xuXG52YXIgX0JyYWluS2V5ID0gcmVxdWlyZShcIi4vc3JjL0JyYWluS2V5XCIpO1xuXG52YXIgX0JyYWluS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0JyYWluS2V5KTtcblxudmFyIF9oYXNoID0gcmVxdWlyZShcIi4vc3JjL2hhc2hcIik7XG5cbnZhciBoYXNoID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX2hhc2gpO1xuXG52YXIgX0tleVV0aWxzID0gcmVxdWlyZShcIi4vc3JjL0tleVV0aWxzXCIpO1xuXG52YXIgX0tleVV0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0tleVV0aWxzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZXhwb3J0cy5BZGRyZXNzID0gX2FkZHJlc3MyLmRlZmF1bHQ7XG5leHBvcnRzLkFlcyA9IF9hZXMyLmRlZmF1bHQ7XG5leHBvcnRzLlByaXZhdGVLZXkgPSBfUHJpdmF0ZUtleTIuZGVmYXVsdDtcbmV4cG9ydHMuUHVibGljS2V5ID0gX1B1YmxpY0tleTIuZGVmYXVsdDtcbmV4cG9ydHMuU2lnbmF0dXJlID0gX3NpZ25hdHVyZTIuZGVmYXVsdDtcbmV4cG9ydHMuYnJhaW5LZXkgPSBfQnJhaW5LZXkyLmRlZmF1bHQ7XG5leHBvcnRzLmhhc2ggPSBoYXNoO1xuZXhwb3J0cy5rZXkgPSBfS2V5VXRpbHMyLmRlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzLmRlZmF1bHQgPSBub3JtYWxpemU7XG5mdW5jdGlvbiBub3JtYWxpemUoYnJhaW5LZXkpIHtcbiAgICBpZiAodHlwZW9mIGJyYWluS2V5ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInN0cmluZyByZXF1aXJlZCBmb3IgYnJhaW5LZXlcIik7XG4gICAgfVxuICAgIGJyYWluS2V5ID0gYnJhaW5LZXkudHJpbSgpO1xuICAgIHJldHVybiBicmFpbktleS5zcGxpdCgvW1xcdFxcblxcdlxcZlxcciBdKy8pLmpvaW4oXCIgXCIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9Qcml2YXRlS2V5ID0gcmVxdWlyZShcIi4vUHJpdmF0ZUtleVwiKTtcblxudmFyIF9Qcml2YXRlS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1ByaXZhdGVLZXkpO1xuXG52YXIgX1B1YmxpY0tleSA9IHJlcXVpcmUoXCIuL1B1YmxpY0tleVwiKTtcblxudmFyIF9QdWJsaWNLZXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUHVibGljS2V5KTtcblxudmFyIF9hZGRyZXNzID0gcmVxdWlyZShcIi4vYWRkcmVzc1wiKTtcblxudmFyIF9hZGRyZXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3MpO1xuXG52YXIgX2FlcyA9IHJlcXVpcmUoXCIuL2Flc1wiKTtcblxudmFyIF9hZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWVzKTtcblxudmFyIF9oYXNoID0gcmVxdWlyZShcIi4vaGFzaFwiKTtcblxudmFyIF9zZWN1cmVSYW5kb20gPSByZXF1aXJlKFwic2VjdXJlLXJhbmRvbVwiKTtcblxudmFyIF9zZWN1cmVSYW5kb20yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2VjdXJlUmFuZG9tKTtcblxudmFyIF9iaXRzaGFyZXNqc1dzID0gcmVxdWlyZShcImJpdHNoYXJlc2pzLXdzXCIpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vLyBpbXBvcnQgZGljdGlvbmFyeSBmcm9tICcuL2RpY3Rpb25hcnlfZW4nO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoXCJzYWZlLWJ1ZmZlclwiKS5CdWZmZXI7XG5cbi8vIGhhc2ggZm9yIC4yNSBzZWNvbmRcbnZhciBIQVNIX1BPV0VSX01JTExTID0gMjUwO1xuXG52YXIga2V5ID0ge1xuICAgIC8qKiBVc2VzIDEgc2Vjb25kIG9mIGhhc2hpbmcgcG93ZXIgdG8gY3JlYXRlIGEga2V5L3Bhc3N3b3JkIGNoZWNrc3VtLiAgQW5cbiAgICBpbXBsZW1lbnRhdGlvbiBjYW4gcmUtY2FsbCB0aGlzIG1ldGhvZCB3aXRoIHRoZSBzYW1lIHBhc3N3b3JkIHRvIHJlLW1hdGNoXG4gICAgdGhlIHN0cmVuZ3RoIG9mIHRoZSBDUFUgKGVpdGhlciBhZnRlciBtb3ZpbmcgZnJvbSBhIGRlc2t0b3AgdG8gYSBtb2JpbGUsXG4gICAgbW9iaWxlIHRvIGRlc2t0b3AsIG9yIE4geWVhcnMgZnJvbSBub3cgd2hlbiBDUFVzIGFyZSBwcmVzdW1hYmx5IHN0cm9uZ2VyKS5cbiAgICAgQSBzYWx0IGlzIHVzZWQgZm9yIGFsbCB0aGUgbm9ybWFsIHJlYXNvbnMuLi5cbiAgICAgQHJldHVybiBvYmplY3Qge1xuICAgICAgICBhZXNfcHJpdmF0ZTogQWVzLFxuICAgICAgICBjaGVja3N1bTogXCJ7aGFzaF9pdGVyYXRpb25fY291bnR9LHtzYWx0fSx7Y2hlY2tzdW19XCJcbiAgICB9XG4gICAgKi9cbiAgICBhZXNfY2hlY2tzdW06IGZ1bmN0aW9uIGFlc19jaGVja3N1bShwYXNzd29yZCkge1xuICAgICAgICBpZiAoISh0eXBlb2YgcGFzc3dvcmQgPT09IFwic3RyaW5nXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgXCJwYXNzd29yZCBzdHJpbmcgcmVxdWlyZWRcIigpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzYWx0ID0gX3NlY3VyZVJhbmRvbTIuZGVmYXVsdC5yYW5kb21CdWZmZXIoNCkudG9TdHJpbmcoXCJoZXhcIik7XG4gICAgICAgIHZhciBpdGVyYXRpb25zID0gMDtcbiAgICAgICAgdmFyIHNlY3JldCA9IHNhbHQgKyBwYXNzd29yZDtcbiAgICAgICAgLy8gaGFzaCBmb3IgLjEgc2Vjb25kXG4gICAgICAgIHZhciBzdGFydF90ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgd2hpbGUgKERhdGUubm93KCkgLSBzdGFydF90IDwgSEFTSF9QT1dFUl9NSUxMUykge1xuICAgICAgICAgICAgc2VjcmV0ID0gKDAsIF9oYXNoLnNoYTI1Nikoc2VjcmV0KTtcbiAgICAgICAgICAgIGl0ZXJhdGlvbnMgKz0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGVja3N1bSA9ICgwLCBfaGFzaC5zaGEyNTYpKHNlY3JldCk7XG4gICAgICAgIHZhciBjaGVja3N1bV9zdHJpbmcgPSBbaXRlcmF0aW9ucywgc2FsdC50b1N0cmluZyhcImhleFwiKSwgY2hlY2tzdW0uc2xpY2UoMCwgNCkudG9TdHJpbmcoXCJoZXhcIildLmpvaW4oXCIsXCIpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhZXNfcHJpdmF0ZTogX2FlczIuZGVmYXVsdC5mcm9tU2VlZChzZWNyZXQpLFxuICAgICAgICAgICAgY2hlY2tzdW06IGNoZWNrc3VtX3N0cmluZ1xuICAgICAgICB9O1xuICAgIH0sXG5cblxuICAgIC8qKiBQcm92aWRlIGEgbWF0Y2hpbmcgcGFzc3dvcmQgYW5kIGtleV9jaGVja3N1bS4gIEEgXCJ3cm9uZyBwYXNzd29yZFwiXG4gICAgZXJyb3IgaXMgdGhyb3duIGlmIHRoZSBwYXNzd29yZCBkb2VzIG5vdCBtYXRjaC4gIElmIHRoaXMgbWV0aG9kIHRha2VzXG4gICAgbXVjaCBtb3JlIG9yIGxlc3MgdGhhbiAxIHNlY29uZCB0byByZXR1cm4sIG9uZSBzaG91bGQgY29uc2lkZXIgdXBkYXRpbmdcbiAgICBhbGwgZW5jeXJwdGVkIGZpZWxkcyB1c2luZyBhIG5ldyBrZXkua2V5X2NoZWNrc3VtLlxuICAgICovXG4gICAgYWVzX3ByaXZhdGU6IGZ1bmN0aW9uIGFlc19wcml2YXRlKHBhc3N3b3JkLCBrZXlfY2hlY2tzdW0pIHtcbiAgICAgICAgdmFyIF9rZXlfY2hlY2tzdW0kc3BsaXQgPSBrZXlfY2hlY2tzdW0uc3BsaXQoXCIsXCIpLFxuICAgICAgICAgICAgaXRlcmF0aW9ucyA9IF9rZXlfY2hlY2tzdW0kc3BsaXRbMF0sXG4gICAgICAgICAgICBzYWx0ID0gX2tleV9jaGVja3N1bSRzcGxpdFsxXSxcbiAgICAgICAgICAgIGNoZWNrc3VtID0gX2tleV9jaGVja3N1bSRzcGxpdFsyXTtcblxuICAgICAgICB2YXIgc2VjcmV0ID0gc2FsdCArIHBhc3N3b3JkO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgMCA8IGl0ZXJhdGlvbnMgPyBpIDwgaXRlcmF0aW9ucyA6IGkgPiBpdGVyYXRpb25zOyAwIDwgaXRlcmF0aW9ucyA/IGkrKyA6IGkrKykge1xuICAgICAgICAgICAgc2VjcmV0ID0gKDAsIF9oYXNoLnNoYTI1Nikoc2VjcmV0KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3X2NoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1Nikoc2VjcmV0KTtcbiAgICAgICAgaWYgKCEobmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpLnRvU3RyaW5nKFwiaGV4XCIpID09PSBjaGVja3N1bSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIndyb25nIHBhc3N3b3JkXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfYWVzMi5kZWZhdWx0LmZyb21TZWVkKHNlY3JldCk7XG4gICAgfSxcblxuXG4gICAgLyoqXG4gICAgICAgIEEgd2VlayByYW5kb20gbnVtYmVyIGdlbmVyYXRvciBjYW4gcnVuIG91dCBvZiBlbnRyb3B5LiAgVGhpcyBzaG91bGQgZW5zdXJlIGV2ZW4gdGhlIHdvcnN0IHJhbmRvbSBudW1iZXIgaW1wbGVtZW50YXRpb24gd2lsbCBiZSByZWFzb25hYmx5IHNhZmUuXG4gICAgICAgICBAcGFyYW0xIHN0cmluZyBlbnRyb3B5IG9mIGF0IGxlYXN0IDMyIGJ5dGVzXG4gICAgKi9cbiAgICByYW5kb20zMkJ5dGVCdWZmZXI6IGZ1bmN0aW9uIHJhbmRvbTMyQnl0ZUJ1ZmZlcigpIHtcbiAgICAgICAgdmFyIGVudHJvcHkgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRoaXMuYnJvd3NlckVudHJvcHkoKTtcblxuICAgICAgICBpZiAoISh0eXBlb2YgZW50cm9weSA9PT0gXCJzdHJpbmdcIikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInN0cmluZyByZXF1aXJlZCBmb3IgZW50cm9weVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbnRyb3B5Lmxlbmd0aCA8IDMyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJleHBlY3RpbmcgYXQgbGVhc3QgMzIgYnl0ZXMgb2YgZW50cm9weVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzdGFydF90ID0gRGF0ZS5ub3coKTtcblxuICAgICAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0X3QgPCBIQVNIX1BPV0VSX01JTExTKSB7XG4gICAgICAgICAgICBlbnRyb3B5ID0gKDAsIF9oYXNoLnNoYTI1NikoZW50cm9weSk7XG4gICAgICAgIH12YXIgaGFzaF9hcnJheSA9IFtdO1xuICAgICAgICBoYXNoX2FycmF5LnB1c2goZW50cm9weSk7XG5cbiAgICAgICAgLy8gSGFzaGluZyBmb3IgMSBzZWNvbmQgbWF5IGhlbHBzIHRoZSBjb21wdXRlciBpcyBub3QgbG93IG9uIGVudHJvcHkgKHRoaXMgbWV0aG9kIG1heSBiZSBjYWxsZWQgYmFjay10by1iYWNrKS5cbiAgICAgICAgaGFzaF9hcnJheS5wdXNoKF9zZWN1cmVSYW5kb20yLmRlZmF1bHQucmFuZG9tQnVmZmVyKDMyKSk7XG5cbiAgICAgICAgcmV0dXJuICgwLCBfaGFzaC5zaGEyNTYpKEJ1ZmZlci5jb25jYXQoaGFzaF9hcnJheSkpO1xuICAgIH0sXG5cblxuICAgIHN1Z2dlc3RfYnJhaW5fa2V5OiBmdW5jdGlvbiBzdWdnZXN0X2JyYWluX2tleSgpIHtcbiAgICAgICAgdmFyIGRpY3Rpb25hcnkgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFwiLFwiO1xuICAgICAgICB2YXIgZW50cm9weSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogdGhpcy5icm93c2VyRW50cm9weSgpO1xuXG4gICAgICAgIHZhciByYW5kb21CdWZmZXIgPSB0aGlzLnJhbmRvbTMyQnl0ZUJ1ZmZlcihlbnRyb3B5KTtcblxuICAgICAgICB2YXIgd29yZF9jb3VudCA9IDE2O1xuICAgICAgICB2YXIgZGljdGlvbmFyeV9saW5lcyA9IGRpY3Rpb25hcnkuc3BsaXQoXCIsXCIpO1xuXG4gICAgICAgIGlmICghKGRpY3Rpb25hcnlfbGluZXMubGVuZ3RoID09PSA0OTc0NCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImV4cGVjdGluZyBcIiArIDQ5NzQ0ICsgXCIgYnV0IGdvdCBcIiArIGRpY3Rpb25hcnlfbGluZXMubGVuZ3RoICsgXCIgZGljdGlvbmFyeSB3b3Jkc1wiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBicmFpbmtleSA9IFtdO1xuICAgICAgICB2YXIgZW5kID0gd29yZF9jb3VudCAqIDI7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmQ7IGkgKz0gMikge1xuICAgICAgICAgICAgLy8gcmFuZG9tQnVmZmVyIGhhcyAyNTYgYml0cyAvIDE2IGJpdHMgcGVyIHdvcmQgPT0gMTYgd29yZHNcbiAgICAgICAgICAgIHZhciBudW0gPSAocmFuZG9tQnVmZmVyW2ldIDw8IDgpICsgcmFuZG9tQnVmZmVyW2kgKyAxXTtcblxuICAgICAgICAgICAgLy8gY29udmVydCBpbnRvIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSAoaW5jbHVzaXZlKVxuICAgICAgICAgICAgdmFyIHJuZE11bHRpcGxpZXIgPSBudW0gLyBNYXRoLnBvdygyLCAxNik7XG4gICAgICAgICAgICB2YXIgd29yZEluZGV4ID0gTWF0aC5yb3VuZChkaWN0aW9uYXJ5X2xpbmVzLmxlbmd0aCAqIHJuZE11bHRpcGxpZXIpO1xuXG4gICAgICAgICAgICBicmFpbmtleS5wdXNoKGRpY3Rpb25hcnlfbGluZXNbd29yZEluZGV4XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsaXplX2JyYWluS2V5KGJyYWlua2V5LmpvaW4oXCIgXCIpKTtcbiAgICB9LFxuXG4gICAgZ2V0X3JhbmRvbV9rZXk6IGZ1bmN0aW9uIGdldF9yYW5kb21fa2V5KGVudHJvcHkpIHtcbiAgICAgICAgcmV0dXJuIF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21CdWZmZXIodGhpcy5yYW5kb20zMkJ5dGVCdWZmZXIoZW50cm9weSkpO1xuICAgIH0sXG4gICAgZ2V0X2JyYWluUHJpdmF0ZUtleTogZnVuY3Rpb24gZ2V0X2JyYWluUHJpdmF0ZUtleShicmFpbktleSkge1xuICAgICAgICB2YXIgc2VxdWVuY2UgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7XG5cbiAgICAgICAgaWYgKHNlcXVlbmNlIDwgMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBzZXF1ZW5jZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnJhaW5LZXkudHJpbSgpID09PSBcIlwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJlbXB0eSBicmFpbiBrZXlcIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJhaW5LZXkgPSBrZXkubm9ybWFsaXplX2JyYWluS2V5KGJyYWluS2V5KTtcbiAgICAgICAgcmV0dXJuIF9Qcml2YXRlS2V5Mi5kZWZhdWx0LmZyb21CdWZmZXIoKDAsIF9oYXNoLnNoYTI1NikoKDAsIF9oYXNoLnNoYTUxMikoYnJhaW5LZXkgKyBcIiBcIiArIHNlcXVlbmNlKSkpO1xuICAgIH0sXG5cblxuICAgIC8vIFR1cm4gaW52aXNpYmxlIHNwYWNlIGxpa2UgY2hhcmFjdGVycyBpbnRvIGEgc2luZ2xlIHNwYWNlXG4gICAgbm9ybWFsaXplX2JyYWluS2V5OiBmdW5jdGlvbiBub3JtYWxpemVfYnJhaW5LZXkoYnJhaW5LZXkpIHtcbiAgICAgICAgaWYgKCEodHlwZW9mIGJyYWluS2V5ID09PSBcInN0cmluZ1wiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic3RyaW5nIHJlcXVpcmVkIGZvciBicmFpbktleVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyYWluS2V5ID0gYnJhaW5LZXkudHJpbSgpO1xuICAgICAgICBpZiAoYnJhaW5LZXkgPT09IFwiXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImVtcHR5IGJyYWluIGtleVwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYnJhaW5LZXkuc3BsaXQoL1tcXHRcXG5cXHZcXGZcXHIgXSsvKS5qb2luKFwiIFwiKTtcbiAgICB9LFxuICAgIGJyb3dzZXJFbnRyb3B5OiBmdW5jdGlvbiBicm93c2VyRW50cm9weSgpIHtcbiAgICAgICAgdmFyIGVudHJvcHlTdHIgPSBcIlwiO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZW50cm9weVN0ciA9IG5ldyBEYXRlKCkudG9TdHJpbmcoKSArIFwiIFwiICsgd2luZG93LnNjcmVlbi5oZWlnaHQgKyBcIiBcIiArIHdpbmRvdy5zY3JlZW4ud2lkdGggKyBcIiBcIiArIHdpbmRvdy5zY3JlZW4uY29sb3JEZXB0aCArIFwiIFwiICsgXCIgXCIgKyB3aW5kb3cuc2NyZWVuLmF2YWlsSGVpZ2h0ICsgXCIgXCIgKyB3aW5kb3cuc2NyZWVuLmF2YWlsV2lkdGggKyBcIiBcIiArIHdpbmRvdy5zY3JlZW4ucGl4ZWxEZXB0aCArIG5hdmlnYXRvci5sYW5ndWFnZSArIFwiIFwiICsgd2luZG93LmxvY2F0aW9uICsgXCIgXCIgKyB3aW5kb3cuaGlzdG9yeS5sZW5ndGg7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBtaW1lVHlwZTsgaSA8IG5hdmlnYXRvci5taW1lVHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBtaW1lVHlwZSA9IG5hdmlnYXRvci5taW1lVHlwZXNbaV07XG4gICAgICAgICAgICAgICAgZW50cm9weVN0ciArPSBtaW1lVHlwZS5kZXNjcmlwdGlvbiArIFwiIFwiICsgbWltZVR5cGUudHlwZSArIFwiIFwiICsgbWltZVR5cGUuc3VmZml4ZXMgKyBcIiBcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiSU5GT1xcdGJyb3dzZXJFbnRyb3B5IGdhdGhlcmVkXCIpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy9ub2RlanM6UmVmZXJlbmNlRXJyb3I6IHdpbmRvdyBpcyBub3QgZGVmaW5lZFxuICAgICAgICAgICAgZW50cm9weVN0ciA9ICgwLCBfaGFzaC5zaGEyNTYpKG5ldyBEYXRlKCkudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYiA9IEJ1ZmZlci5mcm9tKGVudHJvcHlTdHIpO1xuICAgICAgICBlbnRyb3B5U3RyICs9IGIudG9TdHJpbmcoXCJiaW5hcnlcIikgKyBcIiBcIiArIG5ldyBEYXRlKCkudG9TdHJpbmcoKTtcbiAgICAgICAgcmV0dXJuIGVudHJvcHlTdHI7XG4gICAgfSxcblxuXG4gICAgLy8gQHJldHVybiBhcnJheSBvZiA1IGxlZ2FjeSBhZGRyZXNzZXMgZm9yIGEgcHVia2V5IHN0cmluZyBwYXJhbWV0ZXIuXG4gICAgYWRkcmVzc2VzOiBmdW5jdGlvbiBhZGRyZXNzZXMocHVia2V5KSB7XG4gICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogX2JpdHNoYXJlc2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgdmFyIHB1YmxpY19rZXkgPSBfUHVibGljS2V5Mi5kZWZhdWx0LmZyb21QdWJsaWNLZXlTdHJpbmcocHVia2V5LCBhZGRyZXNzX3ByZWZpeCk7XG4gICAgICAgIC8vIFMgTCBPIFdcbiAgICAgICAgdmFyIGFkZHJlc3Nfc3RyaW5nID0gW19hZGRyZXNzMi5kZWZhdWx0LmZyb21QdWJsaWMocHVibGljX2tleSwgZmFsc2UsIDApLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gYnRjX3VuY29tcHJlc3NlZFxuICAgICAgICBfYWRkcmVzczIuZGVmYXVsdC5mcm9tUHVibGljKHB1YmxpY19rZXksIHRydWUsIDApLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gYnRjX2NvbXByZXNzZWRcbiAgICAgICAgX2FkZHJlc3MyLmRlZmF1bHQuZnJvbVB1YmxpYyhwdWJsaWNfa2V5LCBmYWxzZSwgNTYpLnRvU3RyaW5nKGFkZHJlc3NfcHJlZml4KSwgLy8gcHRzX3VuY29tcHJlc3NlZFxuICAgICAgICBfYWRkcmVzczIuZGVmYXVsdC5mcm9tUHVibGljKHB1YmxpY19rZXksIHRydWUsIDU2KS50b1N0cmluZyhhZGRyZXNzX3ByZWZpeCksIC8vIHB0c19jb21wcmVzc2VkXG4gICAgICAgIHB1YmxpY19rZXkudG9BZGRyZXNzU3RyaW5nKGFkZHJlc3NfcHJlZml4KSAvLyBidHNfc2hvcnQsIG1vc3QgcmVjZW50IGZvcm1hdFxuICAgICAgICBdO1xuICAgICAgICByZXR1cm4gYWRkcmVzc19zdHJpbmc7XG4gICAgfVxufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0ga2V5O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9lY3VydmUgPSByZXF1aXJlKFwiZWN1cnZlXCIpO1xuXG52YXIgX2JpZ2kgPSByZXF1aXJlKFwiYmlnaVwiKTtcblxudmFyIF9iaWdpMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2JpZ2kpO1xuXG52YXIgX2JzID0gcmVxdWlyZShcImJzNThcIik7XG5cbnZhciBfaGFzaCA9IHJlcXVpcmUoXCIuL2hhc2hcIik7XG5cbnZhciBfUHVibGljS2V5ID0gcmVxdWlyZShcIi4vUHVibGljS2V5XCIpO1xuXG52YXIgX1B1YmxpY0tleTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9QdWJsaWNLZXkpO1xuXG52YXIgX2RlZXBFcXVhbCA9IHJlcXVpcmUoXCJkZWVwLWVxdWFsXCIpO1xuXG52YXIgX2RlZXBFcXVhbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9kZWVwRXF1YWwpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoXCJhc3NlcnRcIik7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBzZWNwMjU2azEgPSAoMCwgX2VjdXJ2ZS5nZXRDdXJ2ZUJ5TmFtZSkoXCJzZWNwMjU2azFcIik7XG52YXIgbiA9IHNlY3AyNTZrMS5uO1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZShcInNhZmUtYnVmZmVyXCIpLkJ1ZmZlcjtcblxudmFyIFByaXZhdGVLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICAgIEBwcml2YXRlIHNlZSBzdGF0aWMgZnVuY3Rpb25zXG4gICAgICAgIEBwYXJhbSB7QmlnSW50ZWdlcn1cbiAgICAqL1xuICAgIGZ1bmN0aW9uIFByaXZhdGVLZXkoZCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgUHJpdmF0ZUtleSk7XG5cbiAgICAgICAgdGhpcy5kID0gZDtcbiAgICB9XG5cbiAgICBQcml2YXRlS2V5LmZyb21CdWZmZXIgPSBmdW5jdGlvbiBmcm9tQnVmZmVyKGJ1Zikge1xuICAgICAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RpbmcgcGFyYW10ZXIgdG8gYmUgYSBCdWZmZXIgdHlwZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoMzIgIT09IGJ1Zi5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiV0FSTjogRXhwZWN0aW5nIDMyIGJ5dGVzLCBpbnN0ZWFkIGdvdCBcIiArIGJ1Zi5sZW5ndGggKyBcIiwgc3RhY2sgdHJhY2U6XCIsIG5ldyBFcnJvcigpLnN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRW1wdHkgYnVmZmVyXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUHJpdmF0ZUtleShfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZikpO1xuICAgIH07XG5cbiAgICAvKiogQGFyZyB7c3RyaW5nfSBzZWVkIC0gYW55IGxlbmd0aCBzdHJpbmcuICBUaGlzIGlzIHByaXZhdGUsIHRoZSBzYW1lIHNlZWQgcHJvZHVjZXMgdGhlIHNhbWUgcHJpdmF0ZSBrZXkgZXZlcnkgdGltZS4gICovXG5cblxuICAgIFByaXZhdGVLZXkuZnJvbVNlZWQgPSBmdW5jdGlvbiBmcm9tU2VlZChzZWVkKSB7XG4gICAgICAgIC8vIGdlbmVyYXRlX3ByaXZhdGVfa2V5XG4gICAgICAgIGlmICghKHR5cGVvZiBzZWVkID09PSBcInN0cmluZ1wiKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2VlZCBtdXN0IGJlIG9mIHR5cGUgc3RyaW5nXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcml2YXRlS2V5LmZyb21CdWZmZXIoKDAsIF9oYXNoLnNoYTI1Nikoc2VlZCkpO1xuICAgIH07XG5cbiAgICAvKiogQHJldHVybiB7c3RyaW5nfSBXYWxsZXQgSW1wb3J0IEZvcm1hdCAoc3RpbGwgYSBzZWNyZXQsIE5vdCBlbmNyeXB0ZWQpICovXG5cblxuICAgIFByaXZhdGVLZXkuZnJvbVdpZiA9IGZ1bmN0aW9uIGZyb21XaWYoX3ByaXZhdGVfd2lmKSB7XG4gICAgICAgIHZhciBwcml2YXRlX3dpZiA9IEJ1ZmZlci5mcm9tKCgwLCBfYnMuZGVjb2RlKShfcHJpdmF0ZV93aWYpKTtcbiAgICAgICAgdmFyIHZlcnNpb24gPSBwcml2YXRlX3dpZi5yZWFkVUludDgoMCk7XG4gICAgICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoMHg4MCwgdmVyc2lvbiwgXCJFeHBlY3RlZCB2ZXJzaW9uIFwiICsgMHg4MCArIFwiLCBpbnN0ZWFkIGdvdCBcIiArIHZlcnNpb24pO1xuICAgICAgICAvLyBjaGVja3N1bSBpbmNsdWRlcyB0aGUgdmVyc2lvblxuICAgICAgICB2YXIgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX3dpZi5zbGljZSgwLCAtNCk7XG4gICAgICAgIHZhciBjaGVja3N1bSA9IHByaXZhdGVfd2lmLnNsaWNlKC00KTtcbiAgICAgICAgdmFyIG5ld19jaGVja3N1bSA9ICgwLCBfaGFzaC5zaGEyNTYpKHByaXZhdGVfa2V5KTtcbiAgICAgICAgbmV3X2NoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikobmV3X2NoZWNrc3VtKTtcbiAgICAgICAgbmV3X2NoZWNrc3VtID0gbmV3X2NoZWNrc3VtLnNsaWNlKDAsIDQpO1xuICAgICAgICB2YXIgaXNFcXVhbCA9ICgwLCBfZGVlcEVxdWFsMi5kZWZhdWx0KShjaGVja3N1bSwgbmV3X2NoZWNrc3VtKTsgLy8sICdJbnZhbGlkIGNoZWNrc3VtJ1xuICAgICAgICBpZiAoIWlzRXF1YWwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNoZWNrc3VtIGRpZCBub3QgbWF0Y2hcIik7XG4gICAgICAgIH1cbiAgICAgICAgcHJpdmF0ZV9rZXkgPSBwcml2YXRlX2tleS5zbGljZSgxKTtcbiAgICAgICAgcmV0dXJuIFByaXZhdGVLZXkuZnJvbUJ1ZmZlcihwcml2YXRlX2tleSk7XG4gICAgfTtcblxuICAgIFByaXZhdGVLZXkucHJvdG90eXBlLnRvV2lmID0gZnVuY3Rpb24gdG9XaWYoKSB7XG4gICAgICAgIHZhciBwcml2YXRlX2tleSA9IHRoaXMudG9CdWZmZXIoKTtcbiAgICAgICAgLy8gY2hlY2tzdW0gaW5jbHVkZXMgdGhlIHZlcnNpb25cbiAgICAgICAgcHJpdmF0ZV9rZXkgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShbMHg4MF0pLCBwcml2YXRlX2tleV0pO1xuICAgICAgICB2YXIgY2hlY2tzdW0gPSAoMCwgX2hhc2guc2hhMjU2KShwcml2YXRlX2tleSk7XG4gICAgICAgIGNoZWNrc3VtID0gKDAsIF9oYXNoLnNoYTI1NikoY2hlY2tzdW0pO1xuICAgICAgICBjaGVja3N1bSA9IGNoZWNrc3VtLnNsaWNlKDAsIDQpO1xuICAgICAgICB2YXIgcHJpdmF0ZV93aWYgPSBCdWZmZXIuY29uY2F0KFtwcml2YXRlX2tleSwgY2hlY2tzdW1dKTtcbiAgICAgICAgcmV0dXJuICgwLCBfYnMuZW5jb2RlKShwcml2YXRlX3dpZik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAgICBAcmV0dXJuIHtQb2ludH1cbiAgICAqL1xuXG5cbiAgICBQcml2YXRlS2V5LnByb3RvdHlwZS50b1B1YmxpY0tleVBvaW50ID0gZnVuY3Rpb24gdG9QdWJsaWNLZXlQb2ludCgpIHtcbiAgICAgICAgcmV0dXJuIHNlY3AyNTZrMS5HLm11bHRpcGx5KHRoaXMuZCk7XG4gICAgfTtcblxuICAgIFByaXZhdGVLZXkucHJvdG90eXBlLnRvUHVibGljS2V5ID0gZnVuY3Rpb24gdG9QdWJsaWNLZXkoKSB7XG4gICAgICAgIGlmICh0aGlzLnB1YmxpY19rZXkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnB1YmxpY19rZXk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucHVibGljX2tleSA9IF9QdWJsaWNLZXkyLmRlZmF1bHQuZnJvbVBvaW50KHRoaXMudG9QdWJsaWNLZXlQb2ludCgpKTtcbiAgICB9O1xuXG4gICAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbiB0b0J1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZC50b0J1ZmZlcigzMik7XG4gICAgfTtcblxuICAgIC8qKiBFQ0lFUyAqL1xuXG5cbiAgICBQcml2YXRlS2V5LnByb3RvdHlwZS5nZXRfc2hhcmVkX3NlY3JldCA9IGZ1bmN0aW9uIGdldF9zaGFyZWRfc2VjcmV0KHB1YmxpY19rZXkpIHtcbiAgICAgICAgdmFyIGxlZ2FjeSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogZmFsc2U7XG5cbiAgICAgICAgcHVibGljX2tleSA9IHRvUHVibGljKHB1YmxpY19rZXkpO1xuICAgICAgICB2YXIgS0IgPSBwdWJsaWNfa2V5LnRvVW5jb21wcmVzc2VkKCkudG9CdWZmZXIoKTtcbiAgICAgICAgdmFyIEtCUCA9IF9lY3VydmUuUG9pbnQuZnJvbUFmZmluZShzZWNwMjU2azEsIF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoS0Iuc2xpY2UoMSwgMzMpKSwgLy8geFxuICAgICAgICBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKEtCLnNsaWNlKDMzLCA2NSkpIC8vIHlcbiAgICAgICAgKTtcbiAgICAgICAgdmFyIHIgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgICAgIHZhciBQID0gS0JQLm11bHRpcGx5KF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIocikpO1xuICAgICAgICB2YXIgUyA9IFAuYWZmaW5lWC50b0J1ZmZlcih7IHNpemU6IDMyIH0pO1xuICAgICAgICAvKlxuICAgICAgICB0aGUgaW5wdXQgdG8gc2hhNTEyIG11c3QgYmUgZXhhY3RseSAzMi1ieXRlcywgdG8gbWF0Y2ggdGhlIGMrKyBpbXBsZW1lbnRhdGlvblxuICAgICAgICBvZiBnZXRfc2hhcmVkX3NlY3JldC4gIFJpZ2h0IG5vdyBTIHdpbGwgYmUgc2hvcnRlciBpZiB0aGUgbW9zdCBzaWduaWZpY2FudFxuICAgICAgICBieXRlKHMpIGlzIHplcm8uICBQYWQgaXQgYmFjayB0byB0aGUgZnVsbCAzMi1ieXRlc1xuICAgICAgICAqL1xuICAgICAgICBpZiAoIWxlZ2FjeSAmJiBTLmxlbmd0aCA8IDMyKSB7XG4gICAgICAgICAgICB2YXIgcGFkID0gQnVmZmVyLmFsbG9jKDMyIC0gUy5sZW5ndGgpLmZpbGwoMCk7XG4gICAgICAgICAgICBTID0gQnVmZmVyLmNvbmNhdChbcGFkLCBTXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTSEE1MTIgdXNlZCBpbiBFQ0lFU1xuICAgICAgICByZXR1cm4gKDAsIF9oYXNoLnNoYTUxMikoUyk7XG4gICAgfTtcblxuICAgIC8vIC8qKiBFQ0lFUyAoZG9lcyBub3QgYWx3YXlzIG1hdGNoIHRoZSBQb2ludC5mcm9tQWZmaW5lIHZlcnNpb24gYWJvdmUpICovXG4gICAgLy8gZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSl7XG4gICAgLy8gICAgIHB1YmxpY19rZXkgPSB0b1B1YmxpYyhwdWJsaWNfa2V5KVxuICAgIC8vICAgICB2YXIgUCA9IHB1YmxpY19rZXkuUS5tdWx0aXBseSggdGhpcy5kICk7XG4gICAgLy8gICAgIHZhciBTID0gUC5hZmZpbmVYLnRvQnVmZmVyKHtzaXplOiAzMn0pO1xuICAgIC8vICAgICAvLyBFQ0lFUywgYWRkcyBhbiBleHRyYSBzaGE1MTJcbiAgICAvLyAgICAgcmV0dXJuIHNoYTUxMihTKTtcbiAgICAvLyB9XG5cbiAgICAvKiogQHRocm93cyB7RXJyb3J9IC0gb3ZlcmZsb3cgb2YgdGhlIGtleSBjb3VsZCBub3QgYmUgZGVyaXZlZCAqL1xuXG5cbiAgICBQcml2YXRlS2V5LnByb3RvdHlwZS5jaGlsZCA9IGZ1bmN0aW9uIGNoaWxkKG9mZnNldCkge1xuICAgICAgICBvZmZzZXQgPSBCdWZmZXIuY29uY2F0KFt0aGlzLnRvUHVibGljS2V5KCkudG9CdWZmZXIoKSwgb2Zmc2V0XSk7XG4gICAgICAgIG9mZnNldCA9ICgwLCBfaGFzaC5zaGEyNTYpKG9mZnNldCk7XG4gICAgICAgIHZhciBjID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihvZmZzZXQpO1xuXG4gICAgICAgIGlmIChjLmNvbXBhcmVUbyhuKSA+PSAwKSB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBvZmZzZXQgd2VudCBvdXQgb2YgYm91bmRzLCB0cnkgYWdhaW5cIik7XG5cbiAgICAgICAgdmFyIGRlcml2ZWQgPSB0aGlzLmQuYWRkKGMpOyAvLy5tb2QobilcblxuICAgICAgICBpZiAoZGVyaXZlZC5zaWdudW0oKSA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKFwiQ2hpbGQgb2Zmc2V0IGRlcml2ZWQgdG8gYW4gaW52YWxpZCBrZXksIHRyeSBhZ2FpblwiKTtcblxuICAgICAgICByZXR1cm4gbmV3IFByaXZhdGVLZXkoZGVyaXZlZCk7XG4gICAgfTtcblxuICAgIC8qIDxoZWxwZXJfZnVuY3Rpb25zPiAqL1xuXG4gICAgUHJpdmF0ZUtleS5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKCkge1xuICAgICAgICB2YXIgYiA9IG5ldyBCeXRlQnVmZmVyKEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWSwgQnl0ZUJ1ZmZlci5MSVRUTEVfRU5ESUFOKTtcbiAgICAgICAgdGhpcy5hcHBlbmRCeXRlQnVmZmVyKGIpO1xuICAgICAgICByZXR1cm4gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICB9O1xuXG4gICAgUHJpdmF0ZUtleS5mcm9tSGV4ID0gZnVuY3Rpb24gZnJvbUhleChoZXgpIHtcbiAgICAgICAgcmV0dXJuIFByaXZhdGVLZXkuZnJvbUJ1ZmZlcihuZXcgQnVmZmVyKGhleCwgXCJoZXhcIikpO1xuICAgIH07XG5cbiAgICBQcml2YXRlS2V5LnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uIHRvSGV4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b0J1ZmZlcigpLnRvU3RyaW5nKFwiaGV4XCIpO1xuICAgIH07XG5cbiAgICAvKiA8L2hlbHBlcl9mdW5jdGlvbnM+ICovXG5cblxuICAgIHJldHVybiBQcml2YXRlS2V5O1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBQcml2YXRlS2V5O1xuXG5cbnZhciB0b1B1YmxpYyA9IGZ1bmN0aW9uIHRvUHVibGljKGRhdGEpIHtcbiAgICByZXR1cm4gZGF0YSA9PSBudWxsID8gZGF0YSA6IGRhdGEuUSA/IGRhdGEgOiBfUHVibGljS2V5Mi5kZWZhdWx0LmZyb21TdHJpbmdPclRocm93KGRhdGEpO1xufTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoXCJiaWdpXCIpO1xuXG52YXIgX2JpZ2kyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYmlnaSk7XG5cbnZhciBfZWN1cnZlID0gcmVxdWlyZShcImVjdXJ2ZVwiKTtcblxudmFyIF9icyA9IHJlcXVpcmUoXCJiczU4XCIpO1xuXG52YXIgX2hhc2ggPSByZXF1aXJlKFwiLi9oYXNoXCIpO1xuXG52YXIgX2JpdHNoYXJlc2pzV3MgPSByZXF1aXJlKFwiYml0c2hhcmVzanMtd3NcIik7XG5cbnZhciBfYXNzZXJ0ID0gcmVxdWlyZShcImFzc2VydFwiKTtcblxudmFyIF9hc3NlcnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXNzZXJ0KTtcblxudmFyIF9kZWVwRXF1YWwgPSByZXF1aXJlKFwiZGVlcC1lcXVhbFwiKTtcblxudmFyIF9kZWVwRXF1YWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVlcEVxdWFsKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIHNlY3AyNTZrMSA9ICgwLCBfZWN1cnZlLmdldEN1cnZlQnlOYW1lKShcInNlY3AyNTZrMVwiKTtcblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoXCJzYWZlLWJ1ZmZlclwiKS5CdWZmZXI7XG52YXIgRyA9IHNlY3AyNTZrMS5HLFxuICAgIG4gPSBzZWNwMjU2azEubjtcblxudmFyIFB1YmxpY0tleSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHBhcmFtIHtQb2ludH0gcHVibGljIGtleSAqL1xuICAgIGZ1bmN0aW9uIFB1YmxpY0tleShRKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQdWJsaWNLZXkpO1xuXG4gICAgICAgIHRoaXMuUSA9IFE7XG4gICAgfVxuXG4gICAgUHVibGljS2V5LmZyb21CaW5hcnkgPSBmdW5jdGlvbiBmcm9tQmluYXJ5KGJpbikge1xuICAgICAgICByZXR1cm4gUHVibGljS2V5LmZyb21CdWZmZXIoQnVmZmVyLmZyb20oYmluLCBcImJpbmFyeVwiKSk7XG4gICAgfTtcblxuICAgIFB1YmxpY0tleS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlci50b1N0cmluZyhcImhleFwiKSA9PT0gXCIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBcIikgcmV0dXJuIG5ldyBQdWJsaWNLZXkobnVsbCk7XG4gICAgICAgIHJldHVybiBuZXcgUHVibGljS2V5KF9lY3VydmUuUG9pbnQuZGVjb2RlRnJvbShzZWNwMjU2azEsIGJ1ZmZlcikpO1xuICAgIH07XG5cbiAgICBQdWJsaWNLZXkucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIoKSB7XG4gICAgICAgIHZhciBjb21wcmVzc2VkID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB0aGlzLlEgPyB0aGlzLlEuY29tcHJlc3NlZCA6IG51bGw7XG5cbiAgICAgICAgaWYgKHRoaXMuUSA9PT0gbnVsbCkgcmV0dXJuIEJ1ZmZlci5mcm9tKFwiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwXCIsIFwiaGV4XCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5RLmdldEVuY29kZWQoY29tcHJlc3NlZCk7XG4gICAgfTtcblxuICAgIFB1YmxpY0tleS5mcm9tUG9pbnQgPSBmdW5jdGlvbiBmcm9tUG9pbnQocG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQdWJsaWNLZXkocG9pbnQpO1xuICAgIH07XG5cbiAgICBQdWJsaWNLZXkucHJvdG90eXBlLnRvVW5jb21wcmVzc2VkID0gZnVuY3Rpb24gdG9VbmNvbXByZXNzZWQoKSB7XG4gICAgICAgIHZhciBidWYgPSB0aGlzLlEuZ2V0RW5jb2RlZChmYWxzZSk7XG4gICAgICAgIHZhciBwb2ludCA9IF9lY3VydmUuUG9pbnQuZGVjb2RlRnJvbShzZWNwMjU2azEsIGJ1Zik7XG4gICAgICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbVBvaW50KHBvaW50KTtcbiAgICB9O1xuXG4gICAgLyoqIGJ0czo6YmxvY2tjaGFpbjo6YWRkcmVzcyAodW5pcXVlIGJ1dCBub3QgYSBmdWxsIHB1YmxpYyBrZXkpICovXG5cblxuICAgIFB1YmxpY0tleS5wcm90b3R5cGUudG9CbG9ja2NoYWluQWRkcmVzcyA9IGZ1bmN0aW9uIHRvQmxvY2tjaGFpbkFkZHJlc3MoKSB7XG4gICAgICAgIHZhciBwdWJfYnVmID0gdGhpcy50b0J1ZmZlcigpO1xuICAgICAgICB2YXIgcHViX3NoYSA9ICgwLCBfaGFzaC5zaGE1MTIpKHB1Yl9idWYpO1xuICAgICAgICByZXR1cm4gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHViX3NoYSk7XG4gICAgfTtcblxuICAgIC8qKiBBbGlhcyBmb3Ige0BsaW5rIHRvUHVibGljS2V5U3RyaW5nfSAqL1xuXG5cbiAgICBQdWJsaWNLZXkucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX2JpdHNoYXJlc2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudG9QdWJsaWNLZXlTdHJpbmcoYWRkcmVzc19wcmVmaXgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgICAgRnVsbCBwdWJsaWMga2V5XG4gICAgICAgIHtyZXR1cm59IHN0cmluZ1xuICAgICovXG5cblxuICAgIFB1YmxpY0tleS5wcm90b3R5cGUudG9QdWJsaWNLZXlTdHJpbmcgPSBmdW5jdGlvbiB0b1B1YmxpY0tleVN0cmluZygpIHtcbiAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICB2YXIgcHViX2J1ZiA9IHRoaXMudG9CdWZmZXIoKTtcbiAgICAgICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHViX2J1Zik7XG4gICAgICAgIHZhciBhZGR5ID0gQnVmZmVyLmNvbmNhdChbcHViX2J1ZiwgY2hlY2tzdW0uc2xpY2UoMCwgNCldKTtcbiAgICAgICAgcmV0dXJuIGFkZHJlc3NfcHJlZml4ICsgKDAsIF9icy5lbmNvZGUpKGFkZHkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgICAgQGFyZyB7c3RyaW5nfSBwdWJsaWNfa2V5IC0gbGlrZSBHUEhYeXouLi5cbiAgICAgICAgQGFyZyB7c3RyaW5nfSBhZGRyZXNzX3ByZWZpeCAtIGxpa2UgR1BIXG4gICAgICAgIEByZXR1cm4gUHVibGljS2V5IG9yIGBudWxsYCAoaWYgdGhlIHB1YmxpY19rZXkgc3RyaW5nIGlzIGludmFsaWQpXG4gICAgKi9cblxuXG4gICAgUHVibGljS2V5LmZyb21QdWJsaWNLZXlTdHJpbmcgPSBmdW5jdGlvbiBmcm9tUHVibGljS2V5U3RyaW5nKHB1YmxpY19rZXkpIHtcbiAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tU3RyaW5nT3JUaHJvdyhwdWJsaWNfa2V5LCBhZGRyZXNzX3ByZWZpeCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAgICBAYXJnIHtzdHJpbmd9IHB1YmxpY19rZXkgLSBsaWtlIEdQSFh5ei4uLlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGFkZHJlc3NfcHJlZml4IC0gbGlrZSBHUEhcbiAgICAgICAgQHRocm93cyB7RXJyb3J9IGlmIHB1YmxpYyBrZXkgaXMgaW52YWxpZFxuICAgICAgICBAcmV0dXJuIFB1YmxpY0tleVxuICAgICovXG5cblxuICAgIFB1YmxpY0tleS5mcm9tU3RyaW5nT3JUaHJvdyA9IGZ1bmN0aW9uIGZyb21TdHJpbmdPclRocm93KHB1YmxpY19rZXkpIHtcbiAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICBpZiAocHVibGljX2tleS5RID09PSBudWxsKSBwdWJsaWNfa2V5ID0gYWRkcmVzc19wcmVmaXggKyBcIjExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTRUMUFubVwiOyAvLyBudWxsIGtleVxuICAgICAgICB2YXIgcHJlZml4ID0gcHVibGljX2tleS5zbGljZSgwLCBhZGRyZXNzX3ByZWZpeC5sZW5ndGgpO1xuICAgICAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGFkZHJlc3NfcHJlZml4LCBwcmVmaXgsIFwiRXhwZWN0aW5nIGtleSB0byBiZWdpbiB3aXRoIFwiICsgYWRkcmVzc19wcmVmaXggKyBcIiwgaW5zdGVhZCBnb3QgXCIgKyBwcmVmaXgpO1xuICAgICAgICBwdWJsaWNfa2V5ID0gcHVibGljX2tleS5zbGljZShhZGRyZXNzX3ByZWZpeC5sZW5ndGgpO1xuXG4gICAgICAgIHB1YmxpY19rZXkgPSBCdWZmZXIuZnJvbSgoMCwgX2JzLmRlY29kZSkocHVibGljX2tleSksIFwiYmluYXJ5XCIpO1xuICAgICAgICB2YXIgY2hlY2tzdW0gPSBwdWJsaWNfa2V5LnNsaWNlKC00KTtcbiAgICAgICAgcHVibGljX2tleSA9IHB1YmxpY19rZXkuc2xpY2UoMCwgLTQpO1xuICAgICAgICB2YXIgbmV3X2NoZWNrc3VtID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHVibGljX2tleSk7XG4gICAgICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICAgICAgdmFyIGlzRXF1YWwgPSAoMCwgX2RlZXBFcXVhbDIuZGVmYXVsdCkoY2hlY2tzdW0sIG5ld19jaGVja3N1bSk7IC8vLCAnSW52YWxpZCBjaGVja3N1bSdcbiAgICAgICAgaWYgKCFpc0VxdWFsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDaGVja3N1bSBkaWQgbm90IG1hdGNoXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbUJ1ZmZlcihwdWJsaWNfa2V5KTtcbiAgICB9O1xuXG4gICAgUHVibGljS2V5LnByb3RvdHlwZS50b0FkZHJlc3NTdHJpbmcgPSBmdW5jdGlvbiB0b0FkZHJlc3NTdHJpbmcoKSB7XG4gICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX2JpdHNoYXJlc2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgdmFyIHB1Yl9idWYgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgICAgIHZhciBwdWJfc2hhID0gKDAsIF9oYXNoLnNoYTUxMikocHViX2J1Zik7XG4gICAgICAgIHZhciBhZGR5ID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHViX3NoYSk7XG4gICAgICAgIHZhciBjaGVja3N1bSA9ICgwLCBfaGFzaC5yaXBlbWQxNjApKGFkZHkpO1xuICAgICAgICBhZGR5ID0gQnVmZmVyLmNvbmNhdChbYWRkeSwgY2hlY2tzdW0uc2xpY2UoMCwgNCldKTtcbiAgICAgICAgcmV0dXJuIGFkZHJlc3NfcHJlZml4ICsgKDAsIF9icy5lbmNvZGUpKGFkZHkpO1xuICAgIH07XG5cbiAgICBQdWJsaWNLZXkucHJvdG90eXBlLnRvUHRzQWRkeSA9IGZ1bmN0aW9uIHRvUHRzQWRkeSgpIHtcbiAgICAgICAgdmFyIHB1Yl9idWYgPSB0aGlzLnRvQnVmZmVyKCk7XG4gICAgICAgIHZhciBwdWJfc2hhID0gKDAsIF9oYXNoLnNoYTI1NikocHViX2J1Zik7XG4gICAgICAgIHZhciBhZGR5ID0gKDAsIF9oYXNoLnJpcGVtZDE2MCkocHViX3NoYSk7XG4gICAgICAgIGFkZHkgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShbMHgzOF0pLCBhZGR5XSk7IC8vdmVyc2lvbiA1NihkZWNpbWFsKVxuXG4gICAgICAgIHZhciBjaGVja3N1bSA9ICgwLCBfaGFzaC5zaGEyNTYpKGFkZHkpO1xuICAgICAgICBjaGVja3N1bSA9ICgwLCBfaGFzaC5zaGEyNTYpKGNoZWNrc3VtKTtcblxuICAgICAgICBhZGR5ID0gQnVmZmVyLmNvbmNhdChbYWRkeSwgY2hlY2tzdW0uc2xpY2UoMCwgNCldKTtcbiAgICAgICAgcmV0dXJuICgwLCBfYnMuZW5jb2RlKShhZGR5KTtcbiAgICB9O1xuXG4gICAgUHVibGljS2V5LnByb3RvdHlwZS5jaGlsZCA9IGZ1bmN0aW9uIGNoaWxkKG9mZnNldCkge1xuICAgICAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoQnVmZmVyLmlzQnVmZmVyKG9mZnNldCksIFwiQnVmZmVyIHJlcXVpcmVkOiBvZmZzZXRcIik7XG4gICAgICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwob2Zmc2V0Lmxlbmd0aCwgMzIsIFwib2Zmc2V0IGxlbmd0aFwiKTtcblxuICAgICAgICBvZmZzZXQgPSBCdWZmZXIuY29uY2F0KFt0aGlzLnRvQnVmZmVyKCksIG9mZnNldF0pO1xuICAgICAgICBvZmZzZXQgPSAoMCwgX2hhc2guc2hhMjU2KShvZmZzZXQpO1xuXG4gICAgICAgIHZhciBjID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihvZmZzZXQpO1xuXG4gICAgICAgIGlmIChjLmNvbXBhcmVUbyhuKSA+PSAwKSB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBvZmZzZXQgd2VudCBvdXQgb2YgYm91bmRzLCB0cnkgYWdhaW5cIik7XG5cbiAgICAgICAgdmFyIGNHID0gRy5tdWx0aXBseShjKTtcbiAgICAgICAgdmFyIFFwcmltZSA9IHRoaXMuUS5hZGQoY0cpO1xuXG4gICAgICAgIGlmIChzZWNwMjU2azEuaXNJbmZpbml0eShRcHJpbWUpKSB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBvZmZzZXQgZGVyaXZlZCB0byBhbiBpbnZhbGlkIGtleSwgdHJ5IGFnYWluXCIpO1xuXG4gICAgICAgIHJldHVybiBQdWJsaWNLZXkuZnJvbVBvaW50KFFwcmltZSk7XG4gICAgfTtcblxuICAgIC8qIDxIRVg+ICovXG5cbiAgICBQdWJsaWNLZXkucHJvdG90eXBlLnRvQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIHRvQnl0ZUJ1ZmZlcigpIHtcbiAgICAgICAgdmFyIGIgPSBuZXcgQnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFksIEJ5dGVCdWZmZXIuTElUVExFX0VORElBTik7XG4gICAgICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgcmV0dXJuIGIuY29weSgwLCBiLm9mZnNldCk7XG4gICAgfTtcblxuICAgIFB1YmxpY0tleS5mcm9tSGV4ID0gZnVuY3Rpb24gZnJvbUhleChoZXgpIHtcbiAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tQnVmZmVyKEJ1ZmZlci5mcm9tKGhleCwgXCJoZXhcIikpO1xuICAgIH07XG5cbiAgICBQdWJsaWNLZXkucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvQnVmZmVyKCkudG9TdHJpbmcoXCJoZXhcIik7XG4gICAgfTtcblxuICAgIFB1YmxpY0tleS5mcm9tUHVibGljS2V5U3RyaW5nSGV4ID0gZnVuY3Rpb24gZnJvbVB1YmxpY0tleVN0cmluZ0hleChoZXgpIHtcbiAgICAgICAgcmV0dXJuIFB1YmxpY0tleS5mcm9tUHVibGljS2V5U3RyaW5nKEJ1ZmZlci5mcm9tKGhleCwgXCJoZXhcIikpO1xuICAgIH07XG5cbiAgICAvKiA8L0hFWD4gKi9cblxuXG4gICAgcmV0dXJuIFB1YmxpY0tleTtcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gUHVibGljS2V5O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9hc3NlcnQgPSByZXF1aXJlKFwiYXNzZXJ0XCIpO1xuXG52YXIgX2Fzc2VydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnQpO1xuXG52YXIgX2JpdHNoYXJlc2pzV3MgPSByZXF1aXJlKFwiYml0c2hhcmVzanMtd3NcIik7XG5cbnZhciBfaGFzaDIgPSByZXF1aXJlKFwiLi9oYXNoXCIpO1xuXG52YXIgX2JzID0gcmVxdWlyZShcImJzNThcIik7XG5cbnZhciBfZGVlcEVxdWFsID0gcmVxdWlyZShcImRlZXAtZXF1YWxcIik7XG5cbnZhciBfZGVlcEVxdWFsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2RlZXBFcXVhbCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKFwic2FmZS1idWZmZXJcIikuQnVmZmVyO1xuXG4vKiogQWRkcmVzc2VzIGFyZSBzaG9ydGVuZWQgbm9uLXJldmVyc2FibGUgaGFzaGVzIG9mIGEgcHVibGljIGtleS4gIFRoZSBmdWxsIFB1YmxpY0tleSBpcyBwcmVmZXJyZWQuXG4gKi9cblxudmFyIEFkZHJlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQWRkcmVzcyhhZGR5KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBZGRyZXNzKTtcblxuICAgICAgICB0aGlzLmFkZHkgPSBhZGR5O1xuICAgIH1cblxuICAgIEFkZHJlc3MuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uIGZyb21CdWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIHZhciBfaGFzaCA9ICgwLCBfaGFzaDIuc2hhNTEyKShidWZmZXIpO1xuICAgICAgICB2YXIgYWRkeSA9ICgwLCBfaGFzaDIucmlwZW1kMTYwKShfaGFzaCk7XG4gICAgICAgIHJldHVybiBuZXcgQWRkcmVzcyhhZGR5KTtcbiAgICB9O1xuXG4gICAgQWRkcmVzcy5mcm9tU3RyaW5nID0gZnVuY3Rpb24gZnJvbVN0cmluZyhzdHJpbmcpIHtcbiAgICAgICAgdmFyIGFkZHJlc3NfcHJlZml4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeDtcblxuICAgICAgICB2YXIgcHJlZml4ID0gc3RyaW5nLnNsaWNlKDAsIGFkZHJlc3NfcHJlZml4Lmxlbmd0aCk7XG4gICAgICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYWRkcmVzc19wcmVmaXgsIHByZWZpeCwgXCJFeHBlY3Rpbmcga2V5IHRvIGJlZ2luIHdpdGggXCIgKyBhZGRyZXNzX3ByZWZpeCArIFwiLCBpbnN0ZWFkIGdvdCBcIiArIHByZWZpeCk7XG4gICAgICAgIHZhciBhZGR5ID0gc3RyaW5nLnNsaWNlKGFkZHJlc3NfcHJlZml4Lmxlbmd0aCk7XG4gICAgICAgIGFkZHkgPSBuZXcgQnVmZmVyKCgwLCBfYnMuZGVjb2RlKShhZGR5KSwgXCJiaW5hcnlcIik7XG4gICAgICAgIHZhciBjaGVja3N1bSA9IGFkZHkuc2xpY2UoLTQpO1xuICAgICAgICBhZGR5ID0gYWRkeS5zbGljZSgwLCAtNCk7XG4gICAgICAgIHZhciBuZXdfY2hlY2tzdW0gPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkoYWRkeSk7XG4gICAgICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS5zbGljZSgwLCA0KTtcbiAgICAgICAgdmFyIGlzRXF1YWwgPSAoMCwgX2RlZXBFcXVhbDIuZGVmYXVsdCkoY2hlY2tzdW0sIG5ld19jaGVja3N1bSk7IC8vLCAnSW52YWxpZCBjaGVja3N1bSdcbiAgICAgICAgaWYgKCFpc0VxdWFsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDaGVja3N1bSBkaWQgbm90IG1hdGNoXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgQWRkcmVzcyhhZGR5KTtcbiAgICB9O1xuXG4gICAgLyoqIEByZXR1cm4gQWRkcmVzcyAtIENvbXByZXNzZWQgUFRTIGZvcm1hdCAoYnkgZGVmYXVsdCkgKi9cblxuXG4gICAgQWRkcmVzcy5mcm9tUHVibGljID0gZnVuY3Rpb24gZnJvbVB1YmxpYyhwdWJsaWNfa2V5KSB7XG4gICAgICAgIHZhciBjb21wcmVzc2VkID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0cnVlO1xuICAgICAgICB2YXIgdmVyc2lvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogNTY7XG5cbiAgICAgICAgdmFyIHNoYTIgPSAoMCwgX2hhc2gyLnNoYTI1NikocHVibGljX2tleS50b0J1ZmZlcihjb21wcmVzc2VkKSk7XG4gICAgICAgIHZhciByZXAgPSAoMCwgX2hhc2gyLnJpcGVtZDE2MCkoc2hhMik7XG4gICAgICAgIHZhciB2ZXJzaW9uQnVmZmVyID0gQnVmZmVyLmFsbG9jKDEpO1xuICAgICAgICB2ZXJzaW9uQnVmZmVyLndyaXRlVUludDgoMHhmZiAmIHZlcnNpb24sIDApO1xuICAgICAgICB2YXIgYWRkciA9IEJ1ZmZlci5jb25jYXQoW3ZlcnNpb25CdWZmZXIsIHJlcF0pO1xuICAgICAgICB2YXIgY2hlY2sgPSAoMCwgX2hhc2gyLnNoYTI1NikoYWRkcik7XG4gICAgICAgIGNoZWNrID0gKDAsIF9oYXNoMi5zaGEyNTYpKGNoZWNrKTtcbiAgICAgICAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW2FkZHIsIGNoZWNrLnNsaWNlKDAsIDQpXSk7XG4gICAgICAgIHJldHVybiBuZXcgQWRkcmVzcygoMCwgX2hhc2gyLnJpcGVtZDE2MCkoYnVmZmVyKSk7XG4gICAgfTtcblxuICAgIEFkZHJlc3MucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZHk7XG4gICAgfTtcblxuICAgIEFkZHJlc3MucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBhZGRyZXNzX3ByZWZpeCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogX2JpdHNoYXJlc2pzV3MuQ2hhaW5Db25maWcuYWRkcmVzc19wcmVmaXg7XG5cbiAgICAgICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoMi5yaXBlbWQxNjApKHRoaXMuYWRkeSk7XG4gICAgICAgIHZhciBhZGR5ID0gQnVmZmVyLmNvbmNhdChbdGhpcy5hZGR5LCBjaGVja3N1bS5zbGljZSgwLCA0KV0pO1xuICAgICAgICByZXR1cm4gYWRkcmVzc19wcmVmaXggKyAoMCwgX2JzLmVuY29kZSkoYWRkeSk7XG4gICAgfTtcblxuICAgIHJldHVybiBBZGRyZXNzO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBBZGRyZXNzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9hZXMgPSByZXF1aXJlKFwiY3J5cHRvLWpzL2Flc1wiKTtcblxudmFyIF9hZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWVzKTtcblxudmFyIF9lbmNIZXggPSByZXF1aXJlKFwiY3J5cHRvLWpzL2VuYy1oZXhcIik7XG5cbnZhciBfZW5jSGV4MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VuY0hleCk7XG5cbnZhciBfZW5jQmFzZSA9IHJlcXVpcmUoXCJjcnlwdG8tanMvZW5jLWJhc2U2NFwiKTtcblxudmFyIF9lbmNCYXNlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2VuY0Jhc2UpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoXCJhc3NlcnRcIik7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfaGFzaDIgPSByZXF1aXJlKFwiLi9oYXNoXCIpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfSAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xuXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKFwic2FmZS1idWZmZXJcIikuQnVmZmVyO1xuXG4vKiogUHJvdmlkZXMgc3ltZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB2aWEgQUVTLiAqL1xuXG52YXIgQWVzID0gZnVuY3Rpb24gKCkge1xuICAgIC8qKiBAcHJpdmF0ZSAqL1xuICAgIGZ1bmN0aW9uIEFlcyhpdiwga2V5KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBZXMpO1xuXG4gICAgICAgIHRoaXMuaXYgPSBpdiwgdGhpcy5rZXkgPSBrZXk7XG4gICAgfVxuXG4gICAgLyoqIFRoaXMgaXMgYW4gZXhjZWxsZW50IHdheSB0byBlbnN1cmUgdGhhdCBhbGwgcmVmZXJlbmNlcyB0byBBZXMgY2FuIG5vdCBvcGVyYXRlIGFueW1vcmUgKGV4YW1wbGU6IGEgd2FsbGV0IGJlY29tZXMgbG9ja2VkKS4gIEFuIGFwcGxpY2F0aW9uIHNob3VsZCBlbnN1cmUgdGhlcmUgaXMgb25seSBvbmUgQWVzIG9iamVjdCBpbnN0YW5jZSBmb3IgYSBnaXZlbiBzZWNyZXQgYHNlZWRgLiAqL1xuXG5cbiAgICBBZXMucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLml2ID0gdGhpcy5rZXkgPSB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIC8qKiBAYXJnIHtzdHJpbmd9IHNlZWQgLSBzZWNyZXQgc2VlZCBtYXkgYmUgdXNlZCB0byBlbmNyeXB0IG9yIGRlY3J5cHQuICovXG5cblxuICAgIEFlcy5mcm9tU2VlZCA9IGZ1bmN0aW9uIGZyb21TZWVkKHNlZWQpIHtcbiAgICAgICAgaWYgKHNlZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic2VlZCBpcyByZXF1aXJlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgX2hhc2ggPSAoMCwgX2hhc2gyLnNoYTUxMikoc2VlZCk7XG4gICAgICAgIF9oYXNoID0gX2hhc2gudG9TdHJpbmcoXCJoZXhcIik7XG4gICAgICAgIC8vIERFQlVHIGNvbnNvbGUubG9nKCcuLi4gZnJvbVNlZWQgX2hhc2gnLF9oYXNoKVxuICAgICAgICByZXR1cm4gQWVzLmZyb21TaGE1MTIoX2hhc2gpO1xuICAgIH07XG5cbiAgICAvKiogQGFyZyB7c3RyaW5nfSBoYXNoIC0gQSAxMjggYnl0ZSBoZXggc3RyaW5nLCB0eXBpY2FsbHkgb25lIHdvdWxkIGNhbGwge0BsaW5rIGZyb21TZWVkfSBpbnN0ZWFkLiAqL1xuXG5cbiAgICBBZXMuZnJvbVNoYTUxMiA9IGZ1bmN0aW9uIGZyb21TaGE1MTIoaGFzaCkge1xuICAgICAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGhhc2gubGVuZ3RoLCAxMjgsIFwiQSBTaGE1MTIgaW4gSEVYIHNob3VsZCBiZSAxMjggY2hhcmFjdGVycyBsb25nLCBpbnN0ZWFkIGdvdCBcIiArIGhhc2gubGVuZ3RoKTtcbiAgICAgICAgdmFyIGl2ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShoYXNoLnN1YnN0cmluZyg2NCwgOTYpKTtcbiAgICAgICAgdmFyIGtleSA9IF9lbmNIZXgyLmRlZmF1bHQucGFyc2UoaGFzaC5zdWJzdHJpbmcoMCwgNjQpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBBZXMoaXYsIGtleSk7XG4gICAgfTtcblxuICAgIEFlcy5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWYpIHtcbiAgICAgICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKEJ1ZmZlci5pc0J1ZmZlcihidWYpLCBcIkV4cGVjdGluZyBCdWZmZXJcIik7XG4gICAgICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmLmxlbmd0aCwgNjQsIFwiQSBTaGE1MTIgQnVmZmVyIHNob3VsZCBiZSA2NCBjaGFyYWN0ZXJzIGxvbmcsIGluc3RlYWQgZ290IFwiICsgYnVmLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiBBZXMuZnJvbVNoYTUxMihidWYudG9TdHJpbmcoXCJoZXhcIikpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICAgIEB0aHJvd3Mge0Vycm9yfSAtIFwiSW52YWxpZCBLZXksIC4uLlwiXG4gICAgICAgIEBhcmcge1ByaXZhdGVLZXl9IHByaXZhdGVfa2V5IC0gcmVxdWlyZWQgYW5kIHVzZWQgZm9yIGRlY3J5cHRpb25cbiAgICAgICAgQGFyZyB7UHVibGljS2V5fSBwdWJsaWNfa2V5IC0gcmVxdWlyZWQgYW5kIHVzZWQgdG8gY2FsY3VhbHRlIHRoZSBzaGFyZWQgc2VjcmV0XG4gICAgICAgIEBhcmcge3N0cmluZ30gW25vbmNlID0gXCJcIl0gb3B0aW9uYWwgYnV0IHNob3VsZCBhbHdheXMgYmUgcHJvdmlkZWQgYW5kIGJlIHVuaXF1ZSB3aGVuIHJlLXVzaW5nIHRoZSBzYW1lIHByaXZhdGUvcHVibGljIGtleXMgbW9yZSB0aGFuIG9uY2UuICBUaGlzIG5vbmNlIGlzIG5vdCBhIHNlY3JldC5cbiAgICAgICAgQGFyZyB7c3RyaW5nfEJ1ZmZlcn0gbWVzc2FnZSAtIEVuY3J5cHRlZCBtZXNzYWdlIGNvbnRhaW5pbmcgYSBjaGVja3N1bVxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9XG4gICAgKi9cblxuXG4gICAgQWVzLmRlY3J5cHRfd2l0aF9jaGVja3N1bSA9IGZ1bmN0aW9uIGRlY3J5cHRfd2l0aF9jaGVja3N1bShwcml2YXRlX2tleSwgcHVibGljX2tleSwgbm9uY2UsIG1lc3NhZ2UpIHtcbiAgICAgICAgdmFyIGxlZ2FjeSA9IGFyZ3VtZW50cy5sZW5ndGggPiA0ICYmIGFyZ3VtZW50c1s0XSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzRdIDogZmFsc2U7XG5cbiAgICAgICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsIG5vdCBjb252ZXJ0IFwibnVsbFwiIGludG8gYW4gZW10cHkgc3RyaW5nXG4gICAgICAgIGlmIChub25jZSA9PSBudWxsKVxuICAgICAgICAgICAgLy8gbnVsbCBvciB1bmRlZmluZWRcbiAgICAgICAgICAgIG5vbmNlID0gXCJcIjtcblxuICAgICAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgICAgICAgbWVzc2FnZSA9IG5ldyBCdWZmZXIobWVzc2FnZSwgXCJoZXhcIik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgUyA9IHByaXZhdGVfa2V5LmdldF9zaGFyZWRfc2VjcmV0KHB1YmxpY19rZXksIGxlZ2FjeSk7XG4gICAgICAgIC8vIEQgRSBCIFUgR1xuICAgICAgICAvLyBjb25zb2xlLmxvZygnZGVjcnlwdF93aXRoX2NoZWNrc3VtJywge1xuICAgICAgICAvLyAgICAgcHJpdl90b19wdWI6IHByaXZhdGVfa2V5LnRvUHVibGljS2V5KCkudG9TdHJpbmcoKSxcbiAgICAgICAgLy8gICAgIHB1YjogcHVibGljX2tleS50b1B1YmxpY0tleVN0cmluZygpLFxuICAgICAgICAvLyAgICAgbm9uY2U6IG5vbmNlLFxuICAgICAgICAvLyAgICAgbWVzc2FnZTogbWVzc2FnZS5sZW5ndGgsXG4gICAgICAgIC8vICAgICBTOiBTLnRvU3RyaW5nKCdoZXgnKVxuICAgICAgICAvLyB9KVxuXG4gICAgICAgIHZhciBhZXMgPSBBZXMuZnJvbVNlZWQoQnVmZmVyLmNvbmNhdChbXG4gICAgICAgIC8vIEEgbnVsbCBvciBlbXB0eSBzdHJpbmcgbm9uY2Ugd2lsbCBub3QgZWZmZWN0IHRoZSBoYXNoXG4gICAgICAgIEJ1ZmZlci5mcm9tKFwiXCIgKyBub25jZSksIEJ1ZmZlci5mcm9tKFMudG9TdHJpbmcoXCJoZXhcIikpXSkpO1xuXG4gICAgICAgIHZhciBwbGFuZWJ1ZmZlciA9IGFlcy5kZWNyeXB0KG1lc3NhZ2UpO1xuICAgICAgICBpZiAoIShwbGFuZWJ1ZmZlci5sZW5ndGggPj0gNCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQga2V5LCBjb3VsZCBub3QgZGVjcnlwdCBtZXNzYWdlKDEpXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBwbGFuZWJ1ZmZlcicscGxhbmVidWZmZXIpXG4gICAgICAgIHZhciBjaGVja3N1bSA9IHBsYW5lYnVmZmVyLnNsaWNlKDAsIDQpO1xuICAgICAgICB2YXIgcGxhaW50ZXh0ID0gcGxhbmVidWZmZXIuc2xpY2UoNCk7XG5cbiAgICAgICAgLy8gY29uc29sZS5sb2coJy4uLiBjaGVja3N1bScsY2hlY2tzdW0udG9TdHJpbmcoJ2hleCcpKVxuICAgICAgICAvLyBjb25zb2xlLmxvZygnLi4uIHBsYWludGV4dCcscGxhaW50ZXh0LnRvU3RyaW5nKCkpXG5cbiAgICAgICAgdmFyIG5ld19jaGVja3N1bSA9ICgwLCBfaGFzaDIuc2hhMjU2KShwbGFpbnRleHQpO1xuICAgICAgICBuZXdfY2hlY2tzdW0gPSBuZXdfY2hlY2tzdW0uc2xpY2UoMCwgNCk7XG4gICAgICAgIG5ld19jaGVja3N1bSA9IG5ld19jaGVja3N1bS50b1N0cmluZyhcImhleFwiKTtcblxuICAgICAgICBpZiAoIShjaGVja3N1bS50b1N0cmluZyhcImhleFwiKSA9PT0gbmV3X2NoZWNrc3VtKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBrZXksIGNvdWxkIG5vdCBkZWNyeXB0IG1lc3NhZ2UoMilcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGxhaW50ZXh0O1xuICAgIH07XG5cbiAgICAvKiogSWRlbnRpY2FsIHRvIHtAbGluayBkZWNyeXB0X3dpdGhfY2hlY2tzdW19IGJ1dCB1c2VkIHRvIGVuY3J5cHQuICBTaG91bGQgbm90IHRocm93IGFuIGVycm9yLlxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IG1lc3NhZ2UgLSBFbmNyeXB0ZWQgbWVzc2FnZSB3aGljaCBpbmNsdWRlcyBhIGNoZWNrc3VtXG4gICAgKi9cblxuXG4gICAgQWVzLmVuY3J5cHRfd2l0aF9jaGVja3N1bSA9IGZ1bmN0aW9uIGVuY3J5cHRfd2l0aF9jaGVja3N1bShwcml2YXRlX2tleSwgcHVibGljX2tleSwgbm9uY2UsIG1lc3NhZ2UpIHtcbiAgICAgICAgLy8gV2FybmluZzogRG8gbm90IHB1dCBgbm9uY2UgPSBcIlwiYCBpbiB0aGUgYXJndW1lbnRzLCBpbiBlczYgdGhpcyB3aWxsIG5vdCBjb252ZXJ0IFwibnVsbFwiIGludG8gYW4gZW10cHkgc3RyaW5nXG5cbiAgICAgICAgaWYgKG5vbmNlID09IG51bGwpXG4gICAgICAgICAgICAvLyBudWxsIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgbm9uY2UgPSBcIlwiO1xuXG4gICAgICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKG1lc3NhZ2UpKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gbmV3IEJ1ZmZlcihtZXNzYWdlLCBcImJpbmFyeVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBTID0gcHJpdmF0ZV9rZXkuZ2V0X3NoYXJlZF9zZWNyZXQocHVibGljX2tleSk7XG5cbiAgICAgICAgLy8gRCBFIEIgVSBHXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdlbmNyeXB0X3dpdGhfY2hlY2tzdW0nLCB7XG4gICAgICAgIC8vICAgICBwcml2X3RvX3B1YjogcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKS50b1N0cmluZygpXG4gICAgICAgIC8vICAgICBwdWI6IHB1YmxpY19rZXkudG9QdWJsaWNLZXlTdHJpbmcoKVxuICAgICAgICAvLyAgICAgbm9uY2U6IG5vbmNlXG4gICAgICAgIC8vICAgICBtZXNzYWdlOiBtZXNzYWdlLmxlbmd0aFxuICAgICAgICAvLyAgICAgUzogUy50b1N0cmluZygnaGV4JylcbiAgICAgICAgLy8gfSlcblxuICAgICAgICB2YXIgYWVzID0gQWVzLmZyb21TZWVkKEJ1ZmZlci5jb25jYXQoW1xuICAgICAgICAvLyBBIG51bGwgb3IgZW1wdHkgc3RyaW5nIG5vbmNlIHdpbGwgbm90IGVmZmVjdCB0aGUgaGFzaFxuICAgICAgICBCdWZmZXIuZnJvbShcIlwiICsgbm9uY2UpLCBCdWZmZXIuZnJvbShTLnRvU3RyaW5nKFwiaGV4XCIpKV0pKTtcbiAgICAgICAgLy8gREVCVUcgY29uc29sZS5sb2coJy4uLiBTJyxTLnRvU3RyaW5nKCdoZXgnKSlcbiAgICAgICAgdmFyIGNoZWNrc3VtID0gKDAsIF9oYXNoMi5zaGEyNTYpKG1lc3NhZ2UpLnNsaWNlKDAsIDQpO1xuICAgICAgICB2YXIgcGF5bG9hZCA9IEJ1ZmZlci5jb25jYXQoW2NoZWNrc3VtLCBtZXNzYWdlXSk7XG4gICAgICAgIC8vIERFQlVHIGNvbnNvbGUubG9nKCcuLi4gcGF5bG9hZCcscGF5bG9hZC50b1N0cmluZygpKVxuICAgICAgICByZXR1cm4gYWVzLmVuY3J5cHQocGF5bG9hZCk7XG4gICAgfTtcblxuICAgIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgICBBZXMucHJvdG90eXBlLl9kZWNyeXB0X3dvcmRfYXJyYXkgPSBmdW5jdGlvbiBfZGVjcnlwdF93b3JkX2FycmF5KGNpcGhlcikge1xuICAgICAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy8jQ3VzdG9tX0tleV9hbmRfSVZcbiAgICAgICAgLy8gc2VlIHdhbGxldF9yZWNvcmRzLmNwcCBtYXN0ZXJfa2V5OjpkZWNyeXB0X2tleVxuICAgICAgICByZXR1cm4gX2FlczIuZGVmYXVsdC5kZWNyeXB0KHsgY2lwaGVydGV4dDogY2lwaGVyLCBzYWx0OiBudWxsIH0sIHRoaXMua2V5LCB7XG4gICAgICAgICAgICBpdjogdGhpcy5pdlxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqIEBwcml2YXRlICovXG5cblxuICAgIEFlcy5wcm90b3R5cGUuX2VuY3J5cHRfd29yZF9hcnJheSA9IGZ1bmN0aW9uIF9lbmNyeXB0X3dvcmRfYXJyYXkocGxhaW50ZXh0KSB7XG4gICAgICAgIC8vaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvaXNzdWVzL2RldGFpbD9pZD04NVxuICAgICAgICB2YXIgY2lwaGVyID0gX2FlczIuZGVmYXVsdC5lbmNyeXB0KHBsYWludGV4dCwgdGhpcy5rZXksIHsgaXY6IHRoaXMuaXYgfSk7XG4gICAgICAgIHJldHVybiBfZW5jQmFzZTIuZGVmYXVsdC5wYXJzZShjaXBoZXIudG9TdHJpbmcoKSk7XG4gICAgfTtcblxuICAgIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gY2lwaGVydGV4dFxuICAgICAgICBAcmV0dXJuIHtCdWZmZXJ9IGJpbmFyeVxuICAgICovXG5cblxuICAgIEFlcy5wcm90b3R5cGUuZGVjcnlwdCA9IGZ1bmN0aW9uIGRlY3J5cHQoY2lwaGVydGV4dCkge1xuICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIGNpcGhlcnRleHQgPSBuZXcgQnVmZmVyKGNpcGhlcnRleHQsIFwiYmluYXJ5XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGNpcGhlcnRleHQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJidWZmZXIgcmVxdWlyZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGNpcGhlcnRleHQsIFwiTWlzc2luZyBjaXBoZXIgdGV4dFwiKTtcbiAgICAgICAgLy8gaGV4IGlzIHRoZSBvbmx5IGNvbW1vbiBmb3JtYXRcbiAgICAgICAgdmFyIGhleCA9IHRoaXMuZGVjcnlwdEhleChjaXBoZXJ0ZXh0LnRvU3RyaW5nKFwiaGV4XCIpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIoaGV4LCBcImhleFwiKTtcbiAgICB9O1xuXG4gICAgLyoqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHVzZSBhIGNoZWNrc3VtLCB0aGUgcmV0dXJuZWQgZGF0YSBtdXN0IGJlIHZhbGlkYXRlZCBzb21lIG90aGVyIHdheS5cbiAgICAgICAgQGFyZyB7c3RyaW5nfSBwbGFpbnRleHRcbiAgICAgICAgQHJldHVybiB7QnVmZmVyfSBiaW5hcnlcbiAgICAqL1xuXG5cbiAgICBBZXMucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbiBlbmNyeXB0KHBsYWludGV4dCkge1xuICAgICAgICBpZiAodHlwZW9mIHBsYWludGV4dCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcGxhaW50ZXh0ID0gbmV3IEJ1ZmZlcihwbGFpbnRleHQsIFwiYmluYXJ5XCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHBsYWludGV4dCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImJ1ZmZlciByZXF1aXJlZFwiKTtcbiAgICAgICAgfVxuICAgICAgICAvL2Fzc2VydCBwbGFpbnRleHQsIFwiTWlzc2luZyBwbGFpbiB0ZXh0XCJcbiAgICAgICAgLy8gaGV4IGlzIHRoZSBvbmx5IGNvbW1vbiBmb3JtYXRcbiAgICAgICAgdmFyIGhleCA9IHRoaXMuZW5jcnlwdEhleChwbGFpbnRleHQudG9TdHJpbmcoXCJoZXhcIikpO1xuICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihoZXgsIFwiaGV4XCIpO1xuICAgIH07XG5cbiAgICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd8QnVmZmVyfSBwbGFpbnRleHRcbiAgICAgICAgQHJldHVybiB7c3RyaW5nfSBoZXhcbiAgICAqL1xuXG5cbiAgICBBZXMucHJvdG90eXBlLmVuY3J5cHRUb0hleCA9IGZ1bmN0aW9uIGVuY3J5cHRUb0hleChwbGFpbnRleHQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwbGFpbnRleHQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHBsYWludGV4dCA9IG5ldyBCdWZmZXIocGxhaW50ZXh0LCBcImJpbmFyeVwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwbGFpbnRleHQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJidWZmZXIgcmVxdWlyZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgLy9hc3NlcnQgcGxhaW50ZXh0LCBcIk1pc3NpbmcgcGxhaW4gdGV4dFwiXG4gICAgICAgIC8vIGhleCBpcyB0aGUgb25seSBjb21tb24gZm9ybWF0XG4gICAgICAgIHJldHVybiB0aGlzLmVuY3J5cHRIZXgocGxhaW50ZXh0LnRvU3RyaW5nKFwiaGV4XCIpKTtcbiAgICB9O1xuXG4gICAgLyoqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHVzZSBhIGNoZWNrc3VtLCB0aGUgcmV0dXJuZWQgZGF0YSBtdXN0IGJlIHZhbGlkYXRlZCBzb21lIG90aGVyIHdheS5cbiAgICAgICAgQGFyZyB7c3RyaW5nfSBjaXBoZXIgLSBoZXhcbiAgICAgICAgQHJldHVybiB7c3RyaW5nfSBiaW5hcnkgKGNvdWxkIGVhc2lseSBiZSByZWFkYWJsZSB0ZXh0KVxuICAgICovXG5cblxuICAgIEFlcy5wcm90b3R5cGUuZGVjcnlwdEhleCA9IGZ1bmN0aW9uIGRlY3J5cHRIZXgoY2lwaGVyKSB7XG4gICAgICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShjaXBoZXIsIFwiTWlzc2luZyBjaXBoZXIgdGV4dFwiKTtcbiAgICAgICAgLy8gQ29udmVydCBkYXRhIGludG8gd29yZCBhcnJheXMgKHVzZWQgYnkgQ3J5cHRvKVxuICAgICAgICB2YXIgY2lwaGVyX2FycmF5ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShjaXBoZXIpO1xuICAgICAgICB2YXIgcGxhaW53b3JkcyA9IHRoaXMuX2RlY3J5cHRfd29yZF9hcnJheShjaXBoZXJfYXJyYXkpO1xuICAgICAgICByZXR1cm4gX2VuY0hleDIuZGVmYXVsdC5zdHJpbmdpZnkocGxhaW53b3Jkcyk7XG4gICAgfTtcblxuICAgIC8qKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCB1c2UgYSBjaGVja3N1bSwgdGhlIHJldHVybmVkIGRhdGEgbXVzdCBiZSB2YWxpZGF0ZWQgc29tZSBvdGhlciB3YXkuXG4gICAgICAgIEBhcmcge3N0cmluZ30gY2lwaGVyIC0gaGV4XG4gICAgICAgIEByZXR1cm4ge0J1ZmZlcn0gZW5jb2RlZCBhcyBzcGVjaWZpZWQgYnkgdGhlIHBhcmFtZXRlclxuICAgICovXG5cblxuICAgIEFlcy5wcm90b3R5cGUuZGVjcnlwdEhleFRvQnVmZmVyID0gZnVuY3Rpb24gZGVjcnlwdEhleFRvQnVmZmVyKGNpcGhlcikge1xuICAgICAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoY2lwaGVyLCBcIk1pc3NpbmcgY2lwaGVyIHRleHRcIik7XG4gICAgICAgIC8vIENvbnZlcnQgZGF0YSBpbnRvIHdvcmQgYXJyYXlzICh1c2VkIGJ5IENyeXB0bylcbiAgICAgICAgdmFyIGNpcGhlcl9hcnJheSA9IF9lbmNIZXgyLmRlZmF1bHQucGFyc2UoY2lwaGVyKTtcbiAgICAgICAgdmFyIHBsYWlud29yZHMgPSB0aGlzLl9kZWNyeXB0X3dvcmRfYXJyYXkoY2lwaGVyX2FycmF5KTtcbiAgICAgICAgdmFyIHBsYWluaGV4ID0gX2VuY0hleDIuZGVmYXVsdC5zdHJpbmdpZnkocGxhaW53b3Jkcyk7XG4gICAgICAgIHJldHVybiBuZXcgQnVmZmVyKHBsYWluaGV4LCBcImhleFwiKTtcbiAgICB9O1xuXG4gICAgLyoqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHVzZSBhIGNoZWNrc3VtLCB0aGUgcmV0dXJuZWQgZGF0YSBtdXN0IGJlIHZhbGlkYXRlZCBzb21lIG90aGVyIHdheS5cbiAgICAgICAgQGFyZyB7c3RyaW5nfSBjaXBoZXIgLSBoZXhcbiAgICAgICAgQGFyZyB7c3RyaW5nfSBbZW5jb2RpbmcgPSAnYmluYXJ5J10gLSBhIHZhbGlkIEJ1ZmZlciBlbmNvZGluZ1xuICAgICAgICBAcmV0dXJuIHtTdHJpbmd9IGVuY29kZWQgYXMgc3BlY2lmaWVkIGJ5IHRoZSBwYXJhbWV0ZXJcbiAgICAqL1xuXG5cbiAgICBBZXMucHJvdG90eXBlLmRlY3J5cHRIZXhUb1RleHQgPSBmdW5jdGlvbiBkZWNyeXB0SGV4VG9UZXh0KGNpcGhlcikge1xuICAgICAgICB2YXIgZW5jb2RpbmcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiYmluYXJ5XCI7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZGVjcnlwdEhleFRvQnVmZmVyKGNpcGhlcikudG9TdHJpbmcoZW5jb2RpbmcpO1xuICAgIH07XG5cbiAgICAvKiogVGhpcyBtZXRob2QgZG9lcyBub3QgdXNlIGEgY2hlY2tzdW0sIHRoZSByZXR1cm5lZCBkYXRhIG11c3QgYmUgdmFsaWRhdGVkIHNvbWUgb3RoZXIgd2F5LlxuICAgICAgICBAYXJnIHtzdHJpbmd9IHBsYWluaGV4IC0gaGV4IGZvcm1hdFxuICAgICAgICBAcmV0dXJuIHtTdHJpbmd9IGhleFxuICAgICovXG5cblxuICAgIEFlcy5wcm90b3R5cGUuZW5jcnlwdEhleCA9IGZ1bmN0aW9uIGVuY3J5cHRIZXgocGxhaW5oZXgpIHtcbiAgICAgICAgdmFyIHBsYWluX2FycmF5ID0gX2VuY0hleDIuZGVmYXVsdC5wYXJzZShwbGFpbmhleCk7XG4gICAgICAgIHZhciBjaXBoZXJfYXJyYXkgPSB0aGlzLl9lbmNyeXB0X3dvcmRfYXJyYXkocGxhaW5fYXJyYXkpO1xuICAgICAgICByZXR1cm4gX2VuY0hleDIuZGVmYXVsdC5zdHJpbmdpZnkoY2lwaGVyX2FycmF5KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFlcztcbn0oKTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gQWVzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHMudmVyaWZ5UmF3ID0gZXhwb3J0cy52ZXJpZnkgPSBleHBvcnRzLnNpZ24gPSBleHBvcnRzLnJlY292ZXJQdWJLZXkgPSBleHBvcnRzLmRldGVybWluaXN0aWNHZW5lcmF0ZUsgPSBleHBvcnRzLmNhbGNQdWJLZXlSZWNvdmVyeVBhcmFtID0gdW5kZWZpbmVkO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoXCJhc3NlcnRcIik7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfaGFzaCA9IHJlcXVpcmUoXCIuL2hhc2hcIik7XG5cbnZhciBfZW5mb3JjZV90eXBlcyA9IHJlcXVpcmUoXCIuL2VuZm9yY2VfdHlwZXNcIik7XG5cbnZhciBfZW5mb3JjZV90eXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbmZvcmNlX3R5cGVzKTtcblxudmFyIF9iaWdpID0gcmVxdWlyZShcImJpZ2lcIik7XG5cbnZhciBfYmlnaTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9iaWdpKTtcblxudmFyIF9lY3NpZ25hdHVyZSA9IHJlcXVpcmUoXCIuL2Vjc2lnbmF0dXJlXCIpO1xuXG52YXIgX2Vjc2lnbmF0dXJlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Vjc2lnbmF0dXJlKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLy8gZnJvbSBnaXRodWIuY29tL2JpdGNvaW5qcy9iaXRjb2luanMtbGliIGZyb20gZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvZWNkc2FcbnZhciBCdWZmZXIgPSByZXF1aXJlKFwic2FmZS1idWZmZXJcIikuQnVmZmVyO1xuXG4vLyBodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjNjk3OSNzZWN0aW9uLTMuMlxuZnVuY3Rpb24gZGV0ZXJtaW5pc3RpY0dlbmVyYXRlSyhjdXJ2ZSwgaGFzaCwgZCwgY2hlY2tTaWcsIG5vbmNlKSB7XG4gICAgKDAsIF9lbmZvcmNlX3R5cGVzMi5kZWZhdWx0KShcIkJ1ZmZlclwiLCBoYXNoKTtcbiAgICAoMCwgX2VuZm9yY2VfdHlwZXMyLmRlZmF1bHQpKF9iaWdpMi5kZWZhdWx0LCBkKTtcblxuICAgIGlmIChub25jZSkge1xuICAgICAgICBoYXNoID0gKDAsIF9oYXNoLnNoYTI1NikoQnVmZmVyLmNvbmNhdChbaGFzaCwgQnVmZmVyLmFsbG9jKG5vbmNlKV0pKTtcbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2tcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGhhc2gubGVuZ3RoLCAzMiwgXCJIYXNoIG11c3QgYmUgMjU2IGJpdFwiKTtcblxuICAgIHZhciB4ID0gZC50b0J1ZmZlcigzMik7XG4gICAgdmFyIGsgPSBCdWZmZXIuYWxsb2MoMzIpO1xuICAgIHZhciB2ID0gQnVmZmVyLmFsbG9jKDMyKTtcblxuICAgIC8vIFN0ZXAgQlxuICAgIHYuZmlsbCgxKTtcblxuICAgIC8vIFN0ZXAgQ1xuICAgIGsuZmlsbCgwKTtcblxuICAgIC8vIFN0ZXAgRFxuICAgIGsgPSAoMCwgX2hhc2guSG1hY1NIQTI1NikoQnVmZmVyLmNvbmNhdChbdiwgbmV3IEJ1ZmZlcihbMF0pLCB4LCBoYXNoXSksIGspO1xuXG4gICAgLy8gU3RlcCBFXG4gICAgdiA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KSh2LCBrKTtcblxuICAgIC8vIFN0ZXAgRlxuICAgIGsgPSAoMCwgX2hhc2guSG1hY1NIQTI1NikoQnVmZmVyLmNvbmNhdChbdiwgbmV3IEJ1ZmZlcihbMV0pLCB4LCBoYXNoXSksIGspO1xuXG4gICAgLy8gU3RlcCBHXG4gICAgdiA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KSh2LCBrKTtcblxuICAgIC8vIFN0ZXAgSDEvSDJhLCBpZ25vcmVkIGFzIHRsZW4gPT09IHFsZW4gKDI1NiBiaXQpXG4gICAgLy8gU3RlcCBIMmJcbiAgICB2ID0gKDAsIF9oYXNoLkhtYWNTSEEyNTYpKHYsIGspO1xuXG4gICAgdmFyIFQgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKHYpO1xuXG4gICAgLy8gU3RlcCBIMywgcmVwZWF0IHVudGlsIFQgaXMgd2l0aGluIHRoZSBpbnRlcnZhbCBbMSwgbiAtIDFdXG4gICAgd2hpbGUgKFQuc2lnbnVtKCkgPD0gMCB8fCBULmNvbXBhcmVUbyhjdXJ2ZS5uKSA+PSAwIHx8ICFjaGVja1NpZyhUKSkge1xuICAgICAgICBrID0gKDAsIF9oYXNoLkhtYWNTSEEyNTYpKEJ1ZmZlci5jb25jYXQoW3YsIG5ldyBCdWZmZXIoWzBdKV0pLCBrKTtcbiAgICAgICAgdiA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KSh2LCBrKTtcblxuICAgICAgICAvLyBTdGVwIEgxL0gyYSwgYWdhaW4sIGlnbm9yZWQgYXMgdGxlbiA9PT0gcWxlbiAoMjU2IGJpdClcbiAgICAgICAgLy8gU3RlcCBIMmIgYWdhaW5cbiAgICAgICAgdiA9ICgwLCBfaGFzaC5IbWFjU0hBMjU2KSh2LCBrKTtcblxuICAgICAgICBUID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcih2KTtcbiAgICB9XG5cbiAgICByZXR1cm4gVDtcbn1cblxuZnVuY3Rpb24gc2lnbihjdXJ2ZSwgaGFzaCwgZCwgbm9uY2UpIHtcbiAgICB2YXIgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoaGFzaCk7XG4gICAgdmFyIG4gPSBjdXJ2ZS5uO1xuICAgIHZhciBHID0gY3VydmUuRztcblxuICAgIHZhciByID0gdm9pZCAwLFxuICAgICAgICBzID0gdm9pZCAwO1xuXG4gICAgZGV0ZXJtaW5pc3RpY0dlbmVyYXRlSyhjdXJ2ZSwgaGFzaCwgZCwgZnVuY3Rpb24gKGspIHtcbiAgICAgICAgLy8gZmluZCBjYW5vbmljYWxseSB2YWxpZCBzaWduYXR1cmVcbiAgICAgICAgdmFyIFEgPSBHLm11bHRpcGx5KGspO1xuXG4gICAgICAgIGlmIChjdXJ2ZS5pc0luZmluaXR5KFEpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgciA9IFEuYWZmaW5lWC5tb2Qobik7XG4gICAgICAgIGlmIChyLnNpZ251bSgpID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgcyA9IGsubW9kSW52ZXJzZShuKS5tdWx0aXBseShlLmFkZChkLm11bHRpcGx5KHIpKSkubW9kKG4pO1xuICAgICAgICBpZiAocy5zaWdudW0oKSA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sIG5vbmNlKTtcblxuICAgIHZhciBOX09WRVJfVFdPID0gbi5zaGlmdFJpZ2h0KDEpO1xuXG4gICAgLy8gZW5mb3JjZSBsb3cgUyB2YWx1ZXMsIHNlZSBiaXA2MjogJ2xvdyBzIHZhbHVlcyBpbiBzaWduYXR1cmVzJ1xuICAgIGlmIChzLmNvbXBhcmVUbyhOX09WRVJfVFdPKSA+IDApIHtcbiAgICAgICAgcyA9IG4uc3VidHJhY3Qocyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBfZWNzaWduYXR1cmUyLmRlZmF1bHQociwgcyk7XG59XG5cbmZ1bmN0aW9uIHZlcmlmeVJhdyhjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKSB7XG4gICAgdmFyIG4gPSBjdXJ2ZS5uO1xuICAgIHZhciBHID0gY3VydmUuRztcblxuICAgIHZhciByID0gc2lnbmF0dXJlLnI7XG4gICAgdmFyIHMgPSBzaWduYXR1cmUucztcblxuICAgIC8vIDEuNC4xIEVuZm9yY2UgciBhbmQgcyBhcmUgYm90aCBpbnRlZ2VycyBpbiB0aGUgaW50ZXJ2YWwgWzEsIG4g4oiSIDFdXG4gICAgaWYgKHIuc2lnbnVtKCkgPD0gMCB8fCByLmNvbXBhcmVUbyhuKSA+PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHMuc2lnbnVtKCkgPD0gMCB8fCBzLmNvbXBhcmVUbyhuKSA+PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBjID0gc14tMSBtb2QgblxuICAgIHZhciBjID0gcy5tb2RJbnZlcnNlKG4pO1xuXG4gICAgLy8gMS40LjQgQ29tcHV0ZSB1MSA9IGVzXuKIkjEgbW9kIG5cbiAgICAvLyAgICAgICAgICAgICAgIHUyID0gcnNe4oiSMSBtb2QgblxuICAgIHZhciB1MSA9IGUubXVsdGlwbHkoYykubW9kKG4pO1xuICAgIHZhciB1MiA9IHIubXVsdGlwbHkoYykubW9kKG4pO1xuXG4gICAgLy8gMS40LjUgQ29tcHV0ZSBSID0gKHhSLCB5UikgPSB1MUcgKyB1MlFcbiAgICB2YXIgUiA9IEcubXVsdGlwbHlUd28odTEsIFEsIHUyKTtcblxuICAgIC8vIDEuNC41IChjb250LikgRW5mb3JjZSBSIGlzIG5vdCBhdCBpbmZpbml0eVxuICAgIGlmIChjdXJ2ZS5pc0luZmluaXR5KFIpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyAxLjQuNiBDb252ZXJ0IHRoZSBmaWVsZCBlbGVtZW50IFIueCB0byBhbiBpbnRlZ2VyXG4gICAgdmFyIHhSID0gUi5hZmZpbmVYO1xuXG4gICAgLy8gMS40LjcgU2V0IHYgPSB4UiBtb2QgblxuICAgIHZhciB2ID0geFIubW9kKG4pO1xuXG4gICAgLy8gMS40LjggSWYgdiA9IHIsIG91dHB1dCBcInZhbGlkXCIsIGFuZCBpZiB2ICE9IHIsIG91dHB1dCBcImludmFsaWRcIlxuICAgIHJldHVybiB2LmVxdWFscyhyKTtcbn1cblxuZnVuY3Rpb24gdmVyaWZ5KGN1cnZlLCBoYXNoLCBzaWduYXR1cmUsIFEpIHtcbiAgICAvLyAxLjQuMiBIID0gSGFzaChNKSwgYWxyZWFkeSBkb25lIGJ5IHRoZSB1c2VyXG4gICAgLy8gMS40LjMgZSA9IEhcbiAgICB2YXIgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoaGFzaCk7XG4gICAgcmV0dXJuIHZlcmlmeVJhdyhjdXJ2ZSwgZSwgc2lnbmF0dXJlLCBRKTtcbn1cblxuLyoqXG4gKiBSZWNvdmVyIGEgcHVibGljIGtleSBmcm9tIGEgc2lnbmF0dXJlLlxuICpcbiAqIFNlZSBTRUMgMTogRWxsaXB0aWMgQ3VydmUgQ3J5cHRvZ3JhcGh5LCBzZWN0aW9uIDQuMS42LCBcIlB1YmxpY1xuICogS2V5IFJlY292ZXJ5IE9wZXJhdGlvblwiLlxuICpcbiAqIGh0dHA6Ly93d3cuc2VjZy5vcmcvZG93bmxvYWQvYWlkLTc4MC9zZWMxLXYyLnBkZlxuICovXG5mdW5jdGlvbiByZWNvdmVyUHViS2V5KGN1cnZlLCBlLCBzaWduYXR1cmUsIGkpIHtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LnN0cmljdEVxdWFsKGkgJiAzLCBpLCBcIlJlY292ZXJ5IHBhcmFtIGlzIG1vcmUgdGhhbiB0d28gYml0c1wiKTtcblxuICAgIHZhciBuID0gY3VydmUubjtcbiAgICB2YXIgRyA9IGN1cnZlLkc7XG5cbiAgICB2YXIgciA9IHNpZ25hdHVyZS5yO1xuICAgIHZhciBzID0gc2lnbmF0dXJlLnM7XG5cbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoci5zaWdudW0oKSA+IDAgJiYgci5jb21wYXJlVG8obikgPCAwLCBcIkludmFsaWQgciB2YWx1ZVwiKTtcbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkocy5zaWdudW0oKSA+IDAgJiYgcy5jb21wYXJlVG8obikgPCAwLCBcIkludmFsaWQgcyB2YWx1ZVwiKTtcblxuICAgIC8vIEEgc2V0IExTQiBzaWduaWZpZXMgdGhhdCB0aGUgeS1jb29yZGluYXRlIGlzIG9kZFxuICAgIHZhciBpc1lPZGQgPSBpICYgMTtcblxuICAgIC8vIFRoZSBtb3JlIHNpZ25pZmljYW50IGJpdCBzcGVjaWZpZXMgd2hldGhlciB3ZSBzaG91bGQgdXNlIHRoZVxuICAgIC8vIGZpcnN0IG9yIHNlY29uZCBjYW5kaWRhdGUga2V5LlxuICAgIHZhciBpc1NlY29uZEtleSA9IGkgPj4gMTtcblxuICAgIC8vIDEuMSBMZXQgeCA9IHIgKyBqblxuICAgIHZhciB4ID0gaXNTZWNvbmRLZXkgPyByLmFkZChuKSA6IHI7XG4gICAgdmFyIFIgPSBjdXJ2ZS5wb2ludEZyb21YKGlzWU9kZCwgeCk7XG5cbiAgICAvLyAxLjQgQ2hlY2sgdGhhdCBuUiBpcyBhdCBpbmZpbml0eVxuICAgIHZhciBuUiA9IFIubXVsdGlwbHkobik7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKGN1cnZlLmlzSW5maW5pdHkoblIpLCBcIm5SIGlzIG5vdCBhIHZhbGlkIGN1cnZlIHBvaW50XCIpO1xuXG4gICAgLy8gQ29tcHV0ZSAtZSBmcm9tIGVcbiAgICB2YXIgZU5lZyA9IGUubmVnYXRlKCkubW9kKG4pO1xuXG4gICAgLy8gMS42LjEgQ29tcHV0ZSBRID0gcl4tMSAoc1IgLSAgZUcpXG4gICAgLy8gICAgICAgICAgICAgICBRID0gcl4tMSAoc1IgKyAtZUcpXG4gICAgdmFyIHJJbnYgPSByLm1vZEludmVyc2Uobik7XG5cbiAgICB2YXIgUSA9IFIubXVsdGlwbHlUd28ocywgRywgZU5lZykubXVsdGlwbHkockludik7XG4gICAgY3VydmUudmFsaWRhdGUoUSk7XG5cbiAgICByZXR1cm4gUTtcbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgcHVia2V5IGV4dHJhY3Rpb24gcGFyYW1ldGVyLlxuICpcbiAqIFdoZW4gZXh0cmFjdGluZyBhIHB1YmtleSBmcm9tIGEgc2lnbmF0dXJlLCB3ZSBoYXZlIHRvXG4gKiBkaXN0aW5ndWlzaCBmb3VyIGRpZmZlcmVudCBjYXNlcy4gUmF0aGVyIHRoYW4gcHV0dGluZyB0aGlzXG4gKiBidXJkZW4gb24gdGhlIHZlcmlmaWVyLCBCaXRjb2luIGluY2x1ZGVzIGEgMi1iaXQgdmFsdWUgd2l0aCB0aGVcbiAqIHNpZ25hdHVyZS5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHNpbXBseSB0cmllcyBhbGwgZm91ciBjYXNlcyBhbmQgcmV0dXJucyB0aGUgdmFsdWVcbiAqIHRoYXQgcmVzdWx0ZWQgaW4gYSBzdWNjZXNzZnVsIHB1YmtleSByZWNvdmVyeS5cbiAqL1xuZnVuY3Rpb24gY2FsY1B1YktleVJlY292ZXJ5UGFyYW0oY3VydmUsIGUsIHNpZ25hdHVyZSwgUSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgIHZhciBRcHJpbWUgPSByZWNvdmVyUHViS2V5KGN1cnZlLCBlLCBzaWduYXR1cmUsIGkpO1xuXG4gICAgICAgIC8vIDEuNi4yIFZlcmlmeSBRXG4gICAgICAgIGlmIChRcHJpbWUuZXF1YWxzKFEpKSB7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byBmaW5kIHZhbGlkIHJlY292ZXJ5IGZhY3RvclwiKTtcbn1cblxuZXhwb3J0cy5jYWxjUHViS2V5UmVjb3ZlcnlQYXJhbSA9IGNhbGNQdWJLZXlSZWNvdmVyeVBhcmFtO1xuZXhwb3J0cy5kZXRlcm1pbmlzdGljR2VuZXJhdGVLID0gZGV0ZXJtaW5pc3RpY0dlbmVyYXRlSztcbmV4cG9ydHMucmVjb3ZlclB1YktleSA9IHJlY292ZXJQdWJLZXk7XG5leHBvcnRzLnNpZ24gPSBzaWduO1xuZXhwb3J0cy52ZXJpZnkgPSB2ZXJpZnk7XG5leHBvcnRzLnZlcmlmeVJhdyA9IHZlcmlmeVJhdzsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9hc3NlcnQgPSByZXF1aXJlKFwiYXNzZXJ0XCIpO1xuXG52YXIgX2Fzc2VydDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hc3NlcnQpO1xuXG52YXIgX2VuZm9yY2VfdHlwZXMgPSByZXF1aXJlKFwiLi9lbmZvcmNlX3R5cGVzXCIpO1xuXG52YXIgX2VuZm9yY2VfdHlwZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZW5mb3JjZV90eXBlcyk7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoXCJiaWdpXCIpO1xuXG52YXIgX2JpZ2kyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYmlnaSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2JpdGNvaW5qcy9iaXRjb2luanMtbGliXG52YXIgQnVmZmVyID0gcmVxdWlyZShcInNhZmUtYnVmZmVyXCIpLkJ1ZmZlcjtcblxuZnVuY3Rpb24gRUNTaWduYXR1cmUociwgcykge1xuICAgICgwLCBfZW5mb3JjZV90eXBlczIuZGVmYXVsdCkoX2JpZ2kyLmRlZmF1bHQsIHIpO1xuICAgICgwLCBfZW5mb3JjZV90eXBlczIuZGVmYXVsdCkoX2JpZ2kyLmRlZmF1bHQsIHMpO1xuXG4gICAgdGhpcy5yID0gcjtcbiAgICB0aGlzLnMgPSBzO1xufVxuXG4vLyBJbXBvcnQgb3BlcmF0aW9uc1xuRUNTaWduYXR1cmUucGFyc2VDb21wYWN0ID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmZmVyLmxlbmd0aCwgNjUsIFwiSW52YWxpZCBzaWduYXR1cmUgbGVuZ3RoXCIpO1xuICAgIHZhciBpID0gYnVmZmVyLnJlYWRVSW50OCgwKSAtIDI3O1xuXG4gICAgLy8gQXQgbW9zdCAzIGJpdHNcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGksIGkgJiA3LCBcIkludmFsaWQgc2lnbmF0dXJlIHBhcmFtZXRlclwiKTtcbiAgICB2YXIgY29tcHJlc3NlZCA9ICEhKGkgJiA0KTtcblxuICAgIC8vIFJlY292ZXJ5IHBhcmFtIG9ubHlcbiAgICBpID0gaSAmIDM7XG5cbiAgICB2YXIgciA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoYnVmZmVyLnNsaWNlKDEsIDMzKSk7XG4gICAgdmFyIHMgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKGJ1ZmZlci5zbGljZSgzMykpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tcHJlc3NlZDogY29tcHJlc3NlZCxcbiAgICAgICAgaTogaSxcbiAgICAgICAgc2lnbmF0dXJlOiBuZXcgRUNTaWduYXR1cmUociwgcylcbiAgICB9O1xufTtcblxuRUNTaWduYXR1cmUuZnJvbURFUiA9IGZ1bmN0aW9uIChidWZmZXIpIHtcbiAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGJ1ZmZlci5yZWFkVUludDgoMCksIDB4MzAsIFwiTm90IGEgREVSIHNlcXVlbmNlXCIpO1xuICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmZmVyLnJlYWRVSW50OCgxKSwgYnVmZmVyLmxlbmd0aCAtIDIsIFwiSW52YWxpZCBzZXF1ZW5jZSBsZW5ndGhcIik7XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KDIpLCAweDAyLCBcIkV4cGVjdGVkIGEgREVSIGludGVnZXJcIik7XG5cbiAgICB2YXIgckxlbiA9IGJ1ZmZlci5yZWFkVUludDgoMyk7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHJMZW4gPiAwLCBcIlIgbGVuZ3RoIGlzIHplcm9cIik7XG5cbiAgICB2YXIgb2Zmc2V0ID0gNCArIHJMZW47XG4gICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChidWZmZXIucmVhZFVJbnQ4KG9mZnNldCksIDB4MDIsIFwiRXhwZWN0ZWQgYSBERVIgaW50ZWdlciAoMilcIik7XG5cbiAgICB2YXIgc0xlbiA9IGJ1ZmZlci5yZWFkVUludDgob2Zmc2V0ICsgMSk7XG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHNMZW4gPiAwLCBcIlMgbGVuZ3RoIGlzIHplcm9cIik7XG5cbiAgICB2YXIgckIgPSBidWZmZXIuc2xpY2UoNCwgb2Zmc2V0KTtcbiAgICB2YXIgc0IgPSBidWZmZXIuc2xpY2Uob2Zmc2V0ICsgMik7XG4gICAgb2Zmc2V0ICs9IDIgKyBzTGVuO1xuXG4gICAgaWYgKHJMZW4gPiAxICYmIHJCLnJlYWRVSW50OCgwKSA9PT0gMHgwMCkge1xuICAgICAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkockIucmVhZFVJbnQ4KDEpICYgMHg4MCwgXCJSIHZhbHVlIGV4Y2Vzc2l2ZWx5IHBhZGRlZFwiKTtcbiAgICB9XG5cbiAgICBpZiAoc0xlbiA+IDEgJiYgc0IucmVhZFVJbnQ4KDApID09PSAweDAwKSB7XG4gICAgICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShzQi5yZWFkVUludDgoMSkgJiAweDgwLCBcIlMgdmFsdWUgZXhjZXNzaXZlbHkgcGFkZGVkXCIpO1xuICAgIH1cblxuICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwob2Zmc2V0LCBidWZmZXIubGVuZ3RoLCBcIkludmFsaWQgREVSIGVuY29kaW5nXCIpO1xuICAgIHZhciByID0gX2JpZ2kyLmRlZmF1bHQuZnJvbURFUkludGVnZXIockIpO1xuICAgIHZhciBzID0gX2JpZ2kyLmRlZmF1bHQuZnJvbURFUkludGVnZXIoc0IpO1xuXG4gICAgKDAsIF9hc3NlcnQyLmRlZmF1bHQpKHIuc2lnbnVtKCkgPj0gMCwgXCJSIHZhbHVlIGlzIG5lZ2F0aXZlXCIpO1xuICAgICgwLCBfYXNzZXJ0Mi5kZWZhdWx0KShzLnNpZ251bSgpID49IDAsIFwiUyB2YWx1ZSBpcyBuZWdhdGl2ZVwiKTtcblxuICAgIHJldHVybiBuZXcgRUNTaWduYXR1cmUociwgcyk7XG59O1xuXG4vLyBGSVhNRTogMHgwMCwgMHgwNCwgMHg4MCBhcmUgU0lHSEFTSF8qIGJvdW5kYXJ5IGNvbnN0YW50cywgaW1wb3J0aW5nIFRyYW5zYWN0aW9uIGNhdXNlcyBhIGNpcmN1bGFyIGRlcGVuZGVuY3lcbkVDU2lnbmF0dXJlLnBhcnNlU2NyaXB0U2lnbmF0dXJlID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICAgIHZhciBoYXNoVHlwZSA9IGJ1ZmZlci5yZWFkVUludDgoYnVmZmVyLmxlbmd0aCAtIDEpO1xuICAgIHZhciBoYXNoVHlwZU1vZCA9IGhhc2hUeXBlICYgfjB4ODA7XG5cbiAgICAoMCwgX2Fzc2VydDIuZGVmYXVsdCkoaGFzaFR5cGVNb2QgPiAweDAwICYmIGhhc2hUeXBlTW9kIDwgMHgwNCwgXCJJbnZhbGlkIGhhc2hUeXBlXCIpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgc2lnbmF0dXJlOiBFQ1NpZ25hdHVyZS5mcm9tREVSKGJ1ZmZlci5zbGljZSgwLCAtMSkpLFxuICAgICAgICBoYXNoVHlwZTogaGFzaFR5cGVcbiAgICB9O1xufTtcblxuLy8gRXhwb3J0IG9wZXJhdGlvbnNcbkVDU2lnbmF0dXJlLnByb3RvdHlwZS50b0NvbXBhY3QgPSBmdW5jdGlvbiAoaSwgY29tcHJlc3NlZCkge1xuICAgIGlmIChjb21wcmVzc2VkKSBpICs9IDQ7XG4gICAgaSArPSAyNztcblxuICAgIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2MoNjUpO1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KGksIDApO1xuXG4gICAgdGhpcy5yLnRvQnVmZmVyKDMyKS5jb3B5KGJ1ZmZlciwgMSk7XG4gICAgdGhpcy5zLnRvQnVmZmVyKDMyKS5jb3B5KGJ1ZmZlciwgMzMpO1xuXG4gICAgcmV0dXJuIGJ1ZmZlcjtcbn07XG5cbkVDU2lnbmF0dXJlLnByb3RvdHlwZS50b0RFUiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgckJhID0gdGhpcy5yLnRvREVSSW50ZWdlcigpO1xuICAgIHZhciBzQmEgPSB0aGlzLnMudG9ERVJJbnRlZ2VyKCk7XG5cbiAgICB2YXIgc2VxdWVuY2UgPSBbXTtcblxuICAgIC8vIElOVEVHRVJcbiAgICBzZXF1ZW5jZS5wdXNoKDB4MDIsIHJCYS5sZW5ndGgpO1xuICAgIHNlcXVlbmNlID0gc2VxdWVuY2UuY29uY2F0KHJCYSk7XG5cbiAgICAvLyBJTlRFR0VSXG4gICAgc2VxdWVuY2UucHVzaCgweDAyLCBzQmEubGVuZ3RoKTtcbiAgICBzZXF1ZW5jZSA9IHNlcXVlbmNlLmNvbmNhdChzQmEpO1xuXG4gICAgLy8gU0VRVUVOQ0VcbiAgICBzZXF1ZW5jZS51bnNoaWZ0KDB4MzAsIHNlcXVlbmNlLmxlbmd0aCk7XG5cbiAgICByZXR1cm4gQnVmZmVyLmZyb20oc2VxdWVuY2UpO1xufTtcblxuRUNTaWduYXR1cmUucHJvdG90eXBlLnRvU2NyaXB0U2lnbmF0dXJlID0gZnVuY3Rpb24gKGhhc2hUeXBlKSB7XG4gICAgdmFyIGhhc2hUeXBlQnVmZmVyID0gQnVmZmVyLmFsbG9jKDEpO1xuICAgIGhhc2hUeXBlQnVmZmVyLndyaXRlVUludDgoaGFzaFR5cGUsIDApO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW3RoaXMudG9ERVIoKSwgaGFzaFR5cGVCdWZmZXJdKTtcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEVDU2lnbmF0dXJlO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHMuZGVmYXVsdCA9IGVuZm9yY2U7XG5mdW5jdGlvbiBlbmZvcmNlKHR5cGUsIHZhbHVlKSB7XG4gICAgLy8gQ29waWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2JpdGNvaW5qcy9iaXRjb2luanMtbGliXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgXCJBcnJheVwiOlxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJCb29sZWFuXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCIpIHJldHVybjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFwiQnVmZmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpIHJldHVybjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICBjYXNlIFwiTnVtYmVyXCI6XG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJTdHJpbmdcIjpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSByZXR1cm47XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZiAoZ2V0TmFtZSh2YWx1ZS5jb25zdHJ1Y3RvcikgPT09IGdldE5hbWUodHlwZSkpIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgXCIgKyAoZ2V0TmFtZSh0eXBlKSB8fCB0eXBlKSArIFwiLCBnb3QgXCIgKyB2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGdldE5hbWUoZm4pIHtcbiAgICAvLyBXaHkgbm90IGZuLm5hbWU6IGh0dHBzOi8va2FuZ2F4LmdpdGh1Yi5pby9jb21wYXQtdGFibGUvZXM2LyNmdW5jdGlvbl9uYW1lX3Byb3BlcnR5XG4gICAgdmFyIG1hdGNoID0gZm4udG9TdHJpbmcoKS5tYXRjaCgvZnVuY3Rpb24gKC4qPylcXCgvKTtcbiAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6IG51bGw7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5yaXBlbWQxNjAgPSBleHBvcnRzLkhtYWNTSEEyNTYgPSBleHBvcnRzLnNoYTUxMiA9IGV4cG9ydHMuc2hhMjU2ID0gZXhwb3J0cy5zaGExID0gdW5kZWZpbmVkO1xuXG52YXIgX2NyZWF0ZUhhc2ggPSByZXF1aXJlKFwiY3JlYXRlLWhhc2hcIik7XG5cbnZhciBfY3JlYXRlSGFzaDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jcmVhdGVIYXNoKTtcblxudmFyIF9jcmVhdGVIbWFjID0gcmVxdWlyZShcImNyZWF0ZS1obWFjXCIpO1xuXG52YXIgX2NyZWF0ZUhtYWMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlSG1hYyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8qKiBAYXJnIHtzdHJpbmd8QnVmZmVyfSBkYXRhXG4gICAgQGFyZyB7c3RyaW5nfSBbZGlnZXN0ID0gbnVsbF0gLSAnaGV4JywgJ2JpbmFyeScgb3IgJ2Jhc2U2NCdcbiAgICBAcmV0dXJuIHtzdHJpbmd8QnVmZmVyfSAtIEJ1ZmZlciB3aGVuIGRpZ2VzdCBpcyBudWxsLCBvciBzdHJpbmdcbiovXG5mdW5jdGlvbiBzaGExKGRhdGEsIGVuY29kaW5nKSB7XG4gICAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoXCJzaGExXCIpLnVwZGF0ZShkYXRhKS5kaWdlc3QoZW5jb2RpbmcpO1xufVxuXG4vKiogQGFyZyB7c3RyaW5nfEJ1ZmZlcn0gZGF0YVxuICAgIEBhcmcge3N0cmluZ30gW2RpZ2VzdCA9IG51bGxdIC0gJ2hleCcsICdiaW5hcnknIG9yICdiYXNlNjQnXG4gICAgQHJldHVybiB7c3RyaW5nfEJ1ZmZlcn0gLSBCdWZmZXIgd2hlbiBkaWdlc3QgaXMgbnVsbCwgb3Igc3RyaW5nXG4qL1xuZnVuY3Rpb24gc2hhMjU2KGRhdGEsIGVuY29kaW5nKSB7XG4gICAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoXCJzaGEyNTZcIikudXBkYXRlKGRhdGEpLmRpZ2VzdChlbmNvZGluZyk7XG59XG5cbi8qKiBAYXJnIHtzdHJpbmd8QnVmZmVyfSBkYXRhXG4gICAgQGFyZyB7c3RyaW5nfSBbZGlnZXN0ID0gbnVsbF0gLSAnaGV4JywgJ2JpbmFyeScgb3IgJ2Jhc2U2NCdcbiAgICBAcmV0dXJuIHtzdHJpbmd8QnVmZmVyfSAtIEJ1ZmZlciB3aGVuIGRpZ2VzdCBpcyBudWxsLCBvciBzdHJpbmdcbiovXG5mdW5jdGlvbiBzaGE1MTIoZGF0YSwgZW5jb2RpbmcpIHtcbiAgICByZXR1cm4gKDAsIF9jcmVhdGVIYXNoMi5kZWZhdWx0KShcInNoYTUxMlwiKS51cGRhdGUoZGF0YSkuZGlnZXN0KGVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gSG1hY1NIQTI1NihidWZmZXIsIHNlY3JldCkge1xuICAgIHJldHVybiAoMCwgX2NyZWF0ZUhtYWMyLmRlZmF1bHQpKFwic2hhMjU2XCIsIHNlY3JldCkudXBkYXRlKGJ1ZmZlcikuZGlnZXN0KCk7XG59XG5cbmZ1bmN0aW9uIHJpcGVtZDE2MChkYXRhKSB7XG4gICAgcmV0dXJuICgwLCBfY3JlYXRlSGFzaDIuZGVmYXVsdCkoXCJybWQxNjBcIikudXBkYXRlKGRhdGEpLmRpZ2VzdCgpO1xufVxuXG4vLyBmdW5jdGlvbiBoYXNoMTYwKGJ1ZmZlcikge1xuLy8gICByZXR1cm4gcmlwZW1kMTYwKHNoYTI1NihidWZmZXIpKVxuLy8gfVxuLy9cbi8vIGZ1bmN0aW9uIGhhc2gyNTYoYnVmZmVyKSB7XG4vLyAgIHJldHVybiBzaGEyNTYoc2hhMjU2KGJ1ZmZlcikpXG4vLyB9XG5cbi8vXG4vLyBmdW5jdGlvbiBIbWFjU0hBNTEyKGJ1ZmZlciwgc2VjcmV0KSB7XG4vLyAgIHJldHVybiBjcnlwdG8uY3JlYXRlSG1hYygnc2hhNTEyJywgc2VjcmV0KS51cGRhdGUoYnVmZmVyKS5kaWdlc3QoKVxuLy8gfVxuXG5leHBvcnRzLnNoYTEgPSBzaGExO1xuZXhwb3J0cy5zaGEyNTYgPSBzaGEyNTY7XG5leHBvcnRzLnNoYTUxMiA9IHNoYTUxMjtcbmV4cG9ydHMuSG1hY1NIQTI1NiA9IEhtYWNTSEEyNTY7XG5leHBvcnRzLnJpcGVtZDE2MCA9IHJpcGVtZDE2MDsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9lY2RzYSA9IHJlcXVpcmUoXCIuL2VjZHNhXCIpO1xuXG52YXIgX2hhc2gyID0gcmVxdWlyZShcIi4vaGFzaFwiKTtcblxudmFyIF9lY3VydmUgPSByZXF1aXJlKFwiZWN1cnZlXCIpO1xuXG52YXIgX2Fzc2VydCA9IHJlcXVpcmUoXCJhc3NlcnRcIik7XG5cbnZhciBfYXNzZXJ0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Fzc2VydCk7XG5cbnZhciBfYmlnaSA9IHJlcXVpcmUoXCJiaWdpXCIpO1xuXG52YXIgX2JpZ2kyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYmlnaSk7XG5cbnZhciBfUHVibGljS2V5ID0gcmVxdWlyZShcIi4vUHVibGljS2V5XCIpO1xuXG52YXIgX1B1YmxpY0tleTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9QdWJsaWNLZXkpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgc2VjcDI1NmsxID0gKDAsIF9lY3VydmUuZ2V0Q3VydmVCeU5hbWUpKFwic2VjcDI1NmsxXCIpO1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZShcInNhZmUtYnVmZmVyXCIpLkJ1ZmZlcjtcblxudmFyIFNpZ25hdHVyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTaWduYXR1cmUocjEsIHMxLCBpMSkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgU2lnbmF0dXJlKTtcblxuICAgICAgICB0aGlzLnIgPSByMTtcbiAgICAgICAgdGhpcy5zID0gczE7XG4gICAgICAgIHRoaXMuaSA9IGkxO1xuICAgICAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMuciAhPSBudWxsLCB0cnVlLCBcIk1pc3NpbmcgcGFyYW1ldGVyXCIpO1xuICAgICAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMucyAhPSBudWxsLCB0cnVlLCBcIk1pc3NpbmcgcGFyYW1ldGVyXCIpO1xuICAgICAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKHRoaXMuaSAhPSBudWxsLCB0cnVlLCBcIk1pc3NpbmcgcGFyYW1ldGVyXCIpO1xuICAgIH1cblxuICAgIFNpZ25hdHVyZS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWYpIHtcbiAgICAgICAgdmFyIGksIHIsIHM7XG4gICAgICAgIF9hc3NlcnQyLmRlZmF1bHQuZXF1YWwoYnVmLmxlbmd0aCwgNjUsIFwiSW52YWxpZCBzaWduYXR1cmUgbGVuZ3RoXCIpO1xuICAgICAgICBpID0gYnVmLnJlYWRVSW50OCgwKTtcbiAgICAgICAgX2Fzc2VydDIuZGVmYXVsdC5lcXVhbChpIC0gMjcsIGkgLSAyNyAmIDcsIFwiSW52YWxpZCBzaWduYXR1cmUgcGFyYW1ldGVyXCIpO1xuICAgICAgICByID0gX2JpZ2kyLmRlZmF1bHQuZnJvbUJ1ZmZlcihidWYuc2xpY2UoMSwgMzMpKTtcbiAgICAgICAgcyA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoYnVmLnNsaWNlKDMzKSk7XG4gICAgICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKHIsIHMsIGkpO1xuICAgIH07XG5cbiAgICBTaWduYXR1cmUucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIoKSB7XG4gICAgICAgIHZhciBidWY7XG4gICAgICAgIGJ1ZiA9IEJ1ZmZlci5hbGxvYyg2NSk7XG4gICAgICAgIGJ1Zi53cml0ZVVJbnQ4KHRoaXMuaSwgMCk7XG4gICAgICAgIHRoaXMuci50b0J1ZmZlcigzMikuY29weShidWYsIDEpO1xuICAgICAgICB0aGlzLnMudG9CdWZmZXIoMzIpLmNvcHkoYnVmLCAzMyk7XG4gICAgICAgIHJldHVybiBidWY7XG4gICAgfTtcblxuICAgIFNpZ25hdHVyZS5wcm90b3R5cGUucmVjb3ZlclB1YmxpY0tleUZyb21CdWZmZXIgPSBmdW5jdGlvbiByZWNvdmVyUHVibGljS2V5RnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb3ZlclB1YmxpY0tleSgoMCwgX2hhc2gyLnNoYTI1NikoYnVmZmVyKSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAgICBAcmV0dXJuIHtQdWJsaWNLZXl9XG4gICAgKi9cblxuXG4gICAgU2lnbmF0dXJlLnByb3RvdHlwZS5yZWNvdmVyUHVibGljS2V5ID0gZnVuY3Rpb24gcmVjb3ZlclB1YmxpY0tleShzaGEyNTZfYnVmZmVyKSB7XG4gICAgICAgIHZhciBRID0gdm9pZCAwLFxuICAgICAgICAgICAgZSA9IHZvaWQgMCxcbiAgICAgICAgICAgIGkgPSB2b2lkIDA7XG4gICAgICAgIGUgPSBfYmlnaTIuZGVmYXVsdC5mcm9tQnVmZmVyKHNoYTI1Nl9idWZmZXIpO1xuICAgICAgICBpID0gdGhpcy5pO1xuICAgICAgICBpIC09IDI3O1xuICAgICAgICBpID0gaSAmIDM7XG4gICAgICAgIFEgPSAoMCwgX2VjZHNhLnJlY292ZXJQdWJLZXkpKHNlY3AyNTZrMSwgZSwgdGhpcywgaSk7XG4gICAgICAgIHJldHVybiBfUHVibGljS2V5Mi5kZWZhdWx0LmZyb21Qb2ludChRKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICAgIEBwYXJhbSB7QnVmZmVyfSBidWZcbiAgICAgICAgQHBhcmFtIHtQcml2YXRlS2V5fSBwcml2YXRlX2tleVxuICAgICAgICBAcmV0dXJuIHtTaWduYXR1cmV9XG4gICAgKi9cblxuXG4gICAgU2lnbmF0dXJlLnNpZ25CdWZmZXIgPSBmdW5jdGlvbiBzaWduQnVmZmVyKGJ1ZiwgcHJpdmF0ZV9rZXkpIHtcbiAgICAgICAgdmFyIF9oYXNoID0gKDAsIF9oYXNoMi5zaGEyNTYpKGJ1Zik7XG4gICAgICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlclNoYTI1NihfaGFzaCwgcHJpdmF0ZV9rZXkpO1xuICAgIH07XG5cbiAgICAvKiogU2lnbiBhIGJ1ZmZlciBvZiBleGFjdGFsbHkgMzIgYnl0ZXMgaW4gc2l6ZSAoc2hhMjU2KHRleHQpKVxuICAgICAgICBAcGFyYW0ge0J1ZmZlcn0gYnVmIC0gMzIgYnl0ZXMgYmluYXJ5XG4gICAgICAgIEBwYXJhbSB7UHJpdmF0ZUtleX0gcHJpdmF0ZV9rZXlcbiAgICAgICAgQHJldHVybiB7U2lnbmF0dXJlfVxuICAgICovXG5cblxuICAgIFNpZ25hdHVyZS5zaWduQnVmZmVyU2hhMjU2ID0gZnVuY3Rpb24gc2lnbkJ1ZmZlclNoYTI1NihidWZfc2hhMjU2LCBwcml2YXRlX2tleSkge1xuICAgICAgICBpZiAoYnVmX3NoYTI1Ni5sZW5ndGggIT09IDMyIHx8ICFCdWZmZXIuaXNCdWZmZXIoYnVmX3NoYTI1NikpIHRocm93IG5ldyBFcnJvcihcImJ1Zl9zaGEyNTY6IDMyIGJ5dGUgYnVmZmVyIHJlcXVyZWRcIik7XG4gICAgICAgIHZhciBkZXIsIGUsIGVjc2lnbmF0dXJlLCBpLCBsZW5SLCBsZW5TLCBub25jZTtcbiAgICAgICAgaSA9IG51bGw7XG4gICAgICAgIG5vbmNlID0gMDtcbiAgICAgICAgZSA9IF9iaWdpMi5kZWZhdWx0LmZyb21CdWZmZXIoYnVmX3NoYTI1Nik7XG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgICBlY3NpZ25hdHVyZSA9ICgwLCBfZWNkc2Euc2lnbikoc2VjcDI1NmsxLCBidWZfc2hhMjU2LCBwcml2YXRlX2tleS5kLCBub25jZSsrKTtcbiAgICAgICAgICAgIGRlciA9IGVjc2lnbmF0dXJlLnRvREVSKCk7XG4gICAgICAgICAgICBsZW5SID0gZGVyWzNdO1xuICAgICAgICAgICAgbGVuUyA9IGRlcls1ICsgbGVuUl07XG4gICAgICAgICAgICBpZiAobGVuUiA9PT0gMzIgJiYgbGVuUyA9PT0gMzIpIHtcbiAgICAgICAgICAgICAgICBpID0gKDAsIF9lY2RzYS5jYWxjUHViS2V5UmVjb3ZlcnlQYXJhbSkoc2VjcDI1NmsxLCBlLCBlY3NpZ25hdHVyZSwgcHJpdmF0ZV9rZXkudG9QdWJsaWNLZXkoKS5RKTtcbiAgICAgICAgICAgICAgICBpICs9IDQ7IC8vIGNvbXByZXNzZWRcbiAgICAgICAgICAgICAgICBpICs9IDI3OyAvLyBjb21wYWN0ICAvLyAgMjQgb3IgMjcgOiggZm9yY2luZyBvZGQteSAybmQga2V5IGNhbmRpZGF0ZSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChub25jZSAlIDEwID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJXQVJOOiBcIiArIG5vbmNlICsgXCIgYXR0ZW1wdHMgdG8gZmluZCBjYW5vbmljYWwgc2lnbmF0dXJlXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKGVjc2lnbmF0dXJlLnIsIGVjc2lnbmF0dXJlLnMsIGkpO1xuICAgIH07XG5cbiAgICBTaWduYXR1cmUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24oc3RyaW5nLCBwcml2YXRlX2tleSkge1xuICAgICAgICByZXR1cm4gU2lnbmF0dXJlLnNpZ25CdWZmZXIoQnVmZmVyLmZyb20oc3RyaW5nKSwgcHJpdmF0ZV9rZXkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgICAgQHBhcmFtIHtCdWZmZXJ9IHVuLWhhc2hlZFxuICAgICAgICBAcGFyYW0gey4vUHVibGljS2V5fVxuICAgICAgICBAcmV0dXJuIHtib29sZWFufVxuICAgICovXG5cblxuICAgIFNpZ25hdHVyZS5wcm90b3R5cGUudmVyaWZ5QnVmZmVyID0gZnVuY3Rpb24gdmVyaWZ5QnVmZmVyKGJ1ZiwgcHVibGljX2tleSkge1xuICAgICAgICB2YXIgX2hhc2ggPSAoMCwgX2hhc2gyLnNoYTI1NikoYnVmKTtcbiAgICAgICAgcmV0dXJuIHRoaXMudmVyaWZ5SGFzaChfaGFzaCwgcHVibGljX2tleSk7XG4gICAgfTtcblxuICAgIFNpZ25hdHVyZS5wcm90b3R5cGUudmVyaWZ5SGFzaCA9IGZ1bmN0aW9uIHZlcmlmeUhhc2goaGFzaCwgcHVibGljX2tleSkge1xuICAgICAgICBfYXNzZXJ0Mi5kZWZhdWx0LmVxdWFsKGhhc2gubGVuZ3RoLCAzMiwgXCJBIFNIQSAyNTYgc2hvdWxkIGJlIDMyIGJ5dGVzIGxvbmcsIGluc3RlYWQgZ290IFwiICsgaGFzaC5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gKDAsIF9lY2RzYS52ZXJpZnkpKHNlY3AyNTZrMSwgaGFzaCwge1xuICAgICAgICAgICAgcjogdGhpcy5yLFxuICAgICAgICAgICAgczogdGhpcy5zXG4gICAgICAgIH0sIHB1YmxpY19rZXkuUSk7XG4gICAgfTtcblxuICAgIC8qIDxIRVg+ICovXG5cbiAgICBTaWduYXR1cmUucHJvdG90eXBlLnRvQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uIHRvQnl0ZUJ1ZmZlcigpIHtcbiAgICAgICAgdmFyIGI7XG4gICAgICAgIGIgPSBuZXcgQnl0ZUJ1ZmZlcihCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFksIEJ5dGVCdWZmZXIuTElUVExFX0VORElBTik7XG4gICAgICAgIHRoaXMuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgcmV0dXJuIGIuY29weSgwLCBiLm9mZnNldCk7XG4gICAgfTtcblxuICAgIFNpZ25hdHVyZS5mcm9tSGV4ID0gZnVuY3Rpb24gZnJvbUhleChoZXgpIHtcbiAgICAgICAgcmV0dXJuIFNpZ25hdHVyZS5mcm9tQnVmZmVyKEJ1ZmZlci5mcm9tKGhleCwgXCJoZXhcIikpO1xuICAgIH07XG5cbiAgICBTaWduYXR1cmUucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24gdG9IZXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvQnVmZmVyKCkudG9TdHJpbmcoXCJoZXhcIik7XG4gICAgfTtcblxuICAgIFNpZ25hdHVyZS5zaWduSGV4ID0gZnVuY3Rpb24gc2lnbkhleChoZXgsIHByaXZhdGVfa2V5KSB7XG4gICAgICAgIHZhciBidWY7XG4gICAgICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleCwgXCJoZXhcIik7XG4gICAgICAgIHJldHVybiBTaWduYXR1cmUuc2lnbkJ1ZmZlcihidWYsIHByaXZhdGVfa2V5KTtcbiAgICB9O1xuXG4gICAgU2lnbmF0dXJlLnByb3RvdHlwZS52ZXJpZnlIZXggPSBmdW5jdGlvbiB2ZXJpZnlIZXgoaGV4LCBwdWJsaWNfa2V5KSB7XG4gICAgICAgIHZhciBidWY7XG4gICAgICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGhleCwgXCJoZXhcIik7XG4gICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUJ1ZmZlcihidWYsIHB1YmxpY19rZXkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gU2lnbmF0dXJlO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBTaWduYXR1cmU7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5TZXJpYWxpemVyVmFsaWRhdGlvbiA9IGV4cG9ydHMudGVtcGxhdGUgPSBleHBvcnRzLm9wcyA9IGV4cG9ydHMudHlwZXMgPSBleHBvcnRzLmZwID0gZXhwb3J0cy5TZXJpYWxpemVyID0gdW5kZWZpbmVkO1xuXG52YXIgX3NlcmlhbGl6ZXIgPSByZXF1aXJlKFwiLi9zcmMvc2VyaWFsaXplclwiKTtcblxudmFyIF9zZXJpYWxpemVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3NlcmlhbGl6ZXIpO1xuXG52YXIgX0Zhc3RQYXJzZXIgPSByZXF1aXJlKFwiLi9zcmMvRmFzdFBhcnNlclwiKTtcblxudmFyIF9GYXN0UGFyc2VyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0Zhc3RQYXJzZXIpO1xuXG52YXIgX3R5cGVzID0gcmVxdWlyZShcIi4vc3JjL3R5cGVzXCIpO1xuXG52YXIgX3R5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3R5cGVzKTtcblxudmFyIF9vcGVyYXRpb25zID0gcmVxdWlyZShcIi4vc3JjL29wZXJhdGlvbnNcIik7XG5cbnZhciBvcHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfb3BlcmF0aW9ucyk7XG5cbnZhciBfdGVtcGxhdGUgPSByZXF1aXJlKFwiLi9zcmMvdGVtcGxhdGVcIik7XG5cbnZhciBfdGVtcGxhdGUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdGVtcGxhdGUpO1xuXG52YXIgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uID0gcmVxdWlyZShcIi4vc3JjL1NlcmlhbGl6ZXJWYWxpZGF0aW9uXCIpO1xuXG52YXIgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZXhwb3J0cy5TZXJpYWxpemVyID0gX3NlcmlhbGl6ZXIyLmRlZmF1bHQ7XG5leHBvcnRzLmZwID0gX0Zhc3RQYXJzZXIyLmRlZmF1bHQ7XG5leHBvcnRzLnR5cGVzID0gX3R5cGVzMi5kZWZhdWx0O1xuZXhwb3J0cy5vcHMgPSBvcHM7XG5leHBvcnRzLnRlbXBsYXRlID0gX3RlbXBsYXRlMi5kZWZhdWx0O1xuZXhwb3J0cy5TZXJpYWxpemVyVmFsaWRhdGlvbiA9IF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9QdWJsaWNLZXkgPSByZXF1aXJlKFwiLi4vLi4vZWNjL3NyYy9QdWJsaWNLZXlcIik7XG5cbnZhciBfUHVibGljS2V5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0tleSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKFwic2FmZS1idWZmZXJcIikuQnVmZmVyO1xuXG52YXIgRmFzdFBhcnNlciA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBGYXN0UGFyc2VyKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRmFzdFBhcnNlcik7XG4gICAgfVxuXG4gICAgRmFzdFBhcnNlci5maXhlZF9kYXRhID0gZnVuY3Rpb24gZml4ZWRfZGF0YShiLCBsZW4sIGJ1ZmZlcikge1xuICAgICAgICBpZiAoIWIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnVmZmVyKSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IGJ1ZmZlci5zbGljZSgwLCBsZW4pLnRvU3RyaW5nKFwiYmluYXJ5XCIpO1xuICAgICAgICAgICAgYi5hcHBlbmQoZGF0YSwgXCJiaW5hcnlcIik7XG4gICAgICAgICAgICB3aGlsZSAobGVuLS0gPiBkYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGIud3JpdGVVaW50OCgwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKTtcbiAgICAgICAgICAgIGIuc2tpcChsZW4pO1xuICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJfY29weS50b0JpbmFyeSgpLCBcImJpbmFyeVwiKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBGYXN0UGFyc2VyLnB1YmxpY19rZXkgPSBmdW5jdGlvbiBwdWJsaWNfa2V5KGIsIF9wdWJsaWNfa2V5KSB7XG4gICAgICAgIGlmICghYikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChfcHVibGljX2tleSkge1xuICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IF9wdWJsaWNfa2V5LnRvQnVmZmVyKCk7XG4gICAgICAgICAgICBiLmFwcGVuZChidWZmZXIudG9TdHJpbmcoXCJiaW5hcnlcIiksIFwiYmluYXJ5XCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnVmZmVyID0gRmFzdFBhcnNlci5maXhlZF9kYXRhKGIsIDMzKTtcbiAgICAgICAgICAgIHJldHVybiBfUHVibGljS2V5Mi5kZWZhdWx0LmZyb21CdWZmZXIoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBGYXN0UGFyc2VyLnJpcGVtZDE2MCA9IGZ1bmN0aW9uIHJpcGVtZDE2MChiLCBfcmlwZW1kKSB7XG4gICAgICAgIGlmICghYikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChfcmlwZW1kKSB7XG4gICAgICAgICAgICBGYXN0UGFyc2VyLmZpeGVkX2RhdGEoYiwgMjAsIF9yaXBlbWQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIEZhc3RQYXJzZXIuZml4ZWRfZGF0YShiLCAyMCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgRmFzdFBhcnNlci50aW1lX3BvaW50X3NlYyA9IGZ1bmN0aW9uIHRpbWVfcG9pbnRfc2VjKGIsIGVwb2NoKSB7XG4gICAgICAgIGlmIChlcG9jaCkge1xuICAgICAgICAgICAgZXBvY2ggPSBNYXRoLmNlaWwoZXBvY2ggLyAxMDAwKTtcbiAgICAgICAgICAgIGIud3JpdGVJbnQzMihlcG9jaCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcG9jaCA9IGIucmVhZEludDMyKCk7IC8vIGZjOjp0aW1lX3BvaW50X3NlY1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGVwb2NoICogMTAwMCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEZhc3RQYXJzZXI7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEZhc3RQYXJzZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cbnZhciBfYnl0ZWJ1ZmZlciA9IHJlcXVpcmUoXCJieXRlYnVmZmVyXCIpO1xuXG52YXIgX0NoYWluVHlwZXMgPSByZXF1aXJlKFwiLi4vLi4vY2hhaW4vc3JjL0NoYWluVHlwZXNcIik7XG5cbnZhciBfQ2hhaW5UeXBlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpblR5cGVzKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIE1BWF9TQUZFX0lOVCA9IDkwMDcxOTkyNTQ3NDA5OTE7XG52YXIgTUlOX1NBRkVfSU5UID0gLTkwMDcxOTkyNTQ3NDA5OTE7XG5cbi8qKlxuICAgIE1vc3QgdmFsaWRhdGlvbnMgYXJlIHNraXBwZWQgYW5kIHRoZSB2YWx1ZSByZXR1cm5lZCB1bmNoYW5nZWQgd2hlbiBhbiBlbXB0eSBzdHJpbmcsIG51bGwsIG9yIHVuZGVmaW5lZCBpcyBlbmNvdW50ZXJlZCAoZXhjZXB0IFwicmVxdWlyZWRcIikuXG5cbiAgICBWYWxpZGF0aW9ucyBzdXBwb3J0IGEgc3RyaW5nIGZvcm1hdCBmb3IgZGVhbGluZyB3aXRoIGxhcmdlIG51bWJlcnMuXG4qL1xudmFyIF9teSA9IHtcbiAgICBpc19lbXB0eTogZnVuY3Rpb24gaXNfZW1wdHkodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQ7XG4gICAgfSxcblxuICAgIHJlcXVpcmVkOiBmdW5jdGlvbiByZXF1aXJlZCh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInZhbHVlIHJlcXVpcmVkIFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgcmVxdWlyZV9hcnJheTogZnVuY3Rpb24gcmVxdWlyZV9hcnJheSh2YWx1ZSwgaW5zdGFuY2VfcmVxdWlyZSkge1xuICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYXJyYXkgcmVxdWlyZWRcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluc3RhbmNlX3JlcXVpcmUpIHtcbiAgICAgICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24gKGkpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZV9yZXF1aXJlKGkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgcmVxdWlyZV9sb25nOiBmdW5jdGlvbiByZXF1aXJlX2xvbmcodmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKCFfYnl0ZWJ1ZmZlci5Mb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkxvbmcgdmFsdWUgcmVxdWlyZWQgXCIgKyBmaWVsZF9uYW1lICsgXCIgXCIgKyB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gICAgc3RyaW5nOiBmdW5jdGlvbiBzdHJpbmcodmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwic3RyaW5nIHJlcXVpcmVkOiBcIiArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICBudW1iZXI6IGZ1bmN0aW9uIG51bWJlcih2YWx1ZSkge1xuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJudW1iZXIgcmVxdWlyZWQ6IFwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIHdob2xlX251bWJlcjogZnVuY3Rpb24gd2hvbGVfbnVtYmVyKHZhbHVlKSB7XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBcIlwiO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICgvXFwuLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwid2hvbGUgbnVtYmVyIHJlcXVpcmVkIFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIHVuc2lnbmVkOiBmdW5jdGlvbiB1bnNpZ25lZCh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoLy0vLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnNpZ25lZCByZXF1aXJlZCBcIiArIGZpZWxkX25hbWUgKyBcIiBcIiArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcblxuXG4gICAgaXNfZGlnaXRzOiBmdW5jdGlvbiBpc19kaWdpdHModmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1lcmljXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoL15bMC05XSskLy50ZXN0KHZhbHVlKVxuICAgICAgICApO1xuICAgIH0sXG5cbiAgICB0b19udW1iZXI6IGZ1bmN0aW9uIHRvX251bWJlcih2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vX292ZXJmbG93NTModmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICB2YXIgaW50X3ZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSgpO1xuICAgICAgICByZXR1cm4gaW50X3ZhbHVlO1xuICAgIH0sXG5cbiAgICB0b19sb25nOiBmdW5jdGlvbiB0b19sb25nKHZhbHVlKSB7XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBcIlwiO1xuICAgICAgICB2YXIgdW5zaWduZWQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IGZhbHNlO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChfYnl0ZWJ1ZmZlci5Mb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubm9fb3ZlcmZsb3c2NCh2YWx1ZSwgZmllbGRfbmFtZSwgdW5zaWduZWQpO1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IFwiXCIgKyB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX2J5dGVidWZmZXIuTG9uZy5mcm9tU3RyaW5nKHZhbHVlLCB1bnNpZ25lZCk7XG4gICAgfSxcbiAgICB0b19zdHJpbmc6IGZ1bmN0aW9uIHRvX3N0cmluZyh2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgdGhpcy5ub19vdmVyZmxvdzUzKHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgICAgIHJldHVybiBcIlwiICsgdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgXCJ1bnN1cHBvcnRlZCB0eXBlIFwiICsgZmllbGRfbmFtZSArIFwiOiAoXCIgKyAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YodmFsdWUpKSArIFwiKSBcIiArIHZhbHVlO1xuICAgIH0sXG4gICAgcmVxdWlyZV90ZXN0OiBmdW5jdGlvbiByZXF1aXJlX3Rlc3QocmVnZXgsIHZhbHVlKSB7XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBcIlwiO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVnZXgudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVubWF0Y2hlZCBcIiArIHJlZ2V4ICsgXCIgXCIgKyBmaWVsZF9uYW1lICsgXCIgXCIgKyB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG5cblxuICAgIHJlcXVpcmVfbWF0Y2g6IGZ1bmN0aW9uIHJlcXVpcmVfbWF0Y2gocmVnZXgsIHZhbHVlKSB7XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiBcIlwiO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYXRjaCA9IHZhbHVlLm1hdGNoKHJlZ2V4KTtcbiAgICAgICAgaWYgKG1hdGNoID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bm1hdGNoZWQgXCIgKyByZWdleCArIFwiIFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9LFxuXG4gICAgcmVxdWlyZV9vYmplY3RfaWQ6IGZ1bmN0aW9uIHJlcXVpcmVfb2JqZWN0X2lkKHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIHJldHVybiByZXF1aXJlX21hdGNoKC9eKFswLTldKylcXC4oWzAtOV0rKVxcLihbMC05XSspJC8sIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICB9LFxuXG4gICAgLy8gRG9lcyBub3Qgc3VwcG9ydCBvdmVyIDUzIGJpdHNcbiAgICByZXF1aXJlX3JhbmdlOiBmdW5jdGlvbiByZXF1aXJlX3JhbmdlKG1pbiwgbWF4LCB2YWx1ZSkge1xuICAgICAgICB2YXIgZmllbGRfbmFtZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogXCJcIjtcblxuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbnVtYmVyID0gdGhpcy50b19udW1iZXIodmFsdWUpO1xuICAgICAgICBpZiAodmFsdWUgPCBtaW4gfHwgdmFsdWUgPiBtYXgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm91dCBvZiByYW5nZSBcIiArIHZhbHVlICsgXCIgXCIgKyBmaWVsZF9uYW1lICsgXCIgXCIgKyB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG5cblxuICAgIHJlcXVpcmVfb2JqZWN0X3R5cGU6IGZ1bmN0aW9uIHJlcXVpcmVfb2JqZWN0X3R5cGUoKSB7XG4gICAgICAgIHZhciByZXNlcnZlZF9zcGFjZXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IDE7XG4gICAgICAgIHZhciB0eXBlID0gYXJndW1lbnRzWzFdO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmd1bWVudHNbMl07XG4gICAgICAgIHZhciBmaWVsZF9uYW1lID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBcIlwiO1xuXG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvYmplY3RfdHlwZSA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9iamVjdF90eXBlW3R5cGVdO1xuICAgICAgICBpZiAoIW9iamVjdF90eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG9iamVjdCB0eXBlIFwiICsgdHlwZSArIFwiIFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZSA9IG5ldyBSZWdFeHAocmVzZXJ2ZWRfc3BhY2VzICsgXCIuXCIgKyBvYmplY3RfdHlwZSArIFwiLlswLTldKyRcIik7XG4gICAgICAgIGlmICghcmUudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGluZyBcIiArIHR5cGUgKyBcIiBpbiBmb3JtYXQgXCIgKyAocmVzZXJ2ZWRfc3BhY2VzICsgXCIuXCIgKyBvYmplY3RfdHlwZSArIFwiLlswLTldKyBcIikgKyAoXCJpbnN0ZWFkIG9mIFwiICsgdmFsdWUgKyBcIiBcIiArIGZpZWxkX25hbWUgKyBcIiBcIiArIHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG5cbiAgICBnZXRfaW5zdGFuY2U6IGZ1bmN0aW9uIGdldF9pbnN0YW5jZShyZXNlcnZlX3NwYWNlcywgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKHJlc2VydmVfc3BhY2VzLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdChcIi5cIilbMl0pO1xuICAgIH0sXG5cbiAgICByZXF1aXJlX3JlbGF0aXZlX3R5cGU6IGZ1bmN0aW9uIHJlcXVpcmVfcmVsYXRpdmVfdHlwZSh0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgICAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMCwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcblxuICAgIGdldF9yZWxhdGl2ZV9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X3JlbGF0aXZlX2luc3RhbmNlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZSgwLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdChcIi5cIilbMl0pO1xuICAgIH0sXG5cbiAgICByZXF1aXJlX3Byb3RvY29sX3R5cGU6IGZ1bmN0aW9uIHJlcXVpcmVfcHJvdG9jb2xfdHlwZSh0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgICAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMSwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcblxuICAgIGdldF9wcm90b2NvbF9pbnN0YW5jZTogZnVuY3Rpb24gZ2V0X3Byb3RvY29sX2luc3RhbmNlKHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVxdWlyZV9vYmplY3RfdHlwZSgxLCB0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZS5zcGxpdChcIi5cIilbMl0pO1xuICAgIH0sXG5cbiAgICBnZXRfcHJvdG9jb2xfdHlwZTogZnVuY3Rpb24gZ2V0X3Byb3RvY29sX3R5cGUodmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNfZW1wdHkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZXF1aXJlX29iamVjdF9pZCh2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHZhciB2YWx1ZXMgPSB2YWx1ZS5zcGxpdChcIi5cIik7XG4gICAgICAgIHJldHVybiB0aGlzLnRvX251bWJlcih2YWx1ZXNbMV0pO1xuICAgIH0sXG5cbiAgICBnZXRfcHJvdG9jb2xfdHlwZV9uYW1lOiBmdW5jdGlvbiBnZXRfcHJvdG9jb2xfdHlwZV9uYW1lKHZhbHVlLCBmaWVsZF9uYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmlzX2VtcHR5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0eXBlX2lkID0gdGhpcy5nZXRfcHJvdG9jb2xfdHlwZSh2YWx1ZSwgZmllbGRfbmFtZSk7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhfQ2hhaW5UeXBlczIuZGVmYXVsdC5vYmplY3RfdHlwZSlbdHlwZV9pZF07XG4gICAgfSxcblxuXG4gICAgcmVxdWlyZV9pbXBsZW1lbnRhdGlvbl90eXBlOiBmdW5jdGlvbiByZXF1aXJlX2ltcGxlbWVudGF0aW9uX3R5cGUodHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpIHtcbiAgICAgICAgdGhpcy5yZXF1aXJlX29iamVjdF90eXBlKDIsIHR5cGUsIHZhbHVlLCBmaWVsZF9uYW1lKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG5cbiAgICBnZXRfaW1wbGVtZW50YXRpb25faW5zdGFuY2U6IGZ1bmN0aW9uIGdldF9pbXBsZW1lbnRhdGlvbl9pbnN0YW5jZSh0eXBlLCB2YWx1ZSwgZmllbGRfbmFtZSkge1xuICAgICAgICBpZiAodGhpcy5pc19lbXB0eSh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlcXVpcmVfb2JqZWN0X3R5cGUoMiwgdHlwZSwgdmFsdWUsIGZpZWxkX25hbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy50b19udW1iZXIodmFsdWUuc3BsaXQoXCIuXCIpWzJdKTtcbiAgICB9LFxuXG4gICAgLy8gc2lnbmVkIC8gdW5zaWduZWQgZGVjaW1hbFxuICAgIG5vX292ZXJmbG93NTM6IGZ1bmN0aW9uIG5vX292ZXJmbG93NTModmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gTUFYX1NBRkVfSU5UIHx8IHZhbHVlIDwgTUlOX1NBRkVfSU5UKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwib3ZlcmZsb3cgXCIgKyBmaWVsZF9uYW1lICsgXCIgXCIgKyB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdmFyIGludCA9IHBhcnNlSW50KHZhbHVlKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IE1BWF9TQUZFX0lOVCB8fCB2YWx1ZSA8IE1JTl9TQUZFX0lOVCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm92ZXJmbG93IFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChfYnl0ZWJ1ZmZlci5Mb25nLmlzTG9uZyh2YWx1ZSkpIHtcbiAgICAgICAgICAgIC8vIHR5cGVvZiB2YWx1ZS50b0ludCgpIGlzICdudW1iZXInXG4gICAgICAgICAgICB0aGlzLm5vX292ZXJmbG93NTModmFsdWUudG9JbnQoKSwgZmllbGRfbmFtZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgXCJ1bnN1cHBvcnRlZCB0eXBlIFwiICsgZmllbGRfbmFtZSArIFwiOiAoXCIgKyAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YodmFsdWUpKSArIFwiKSBcIiArIHZhbHVlO1xuICAgIH0sXG5cblxuICAgIC8vIHNpZ25lZCAvIHVuc2lnbmVkIHdob2xlIG51bWJlcnMgb25seVxuICAgIG5vX292ZXJmbG93NjQ6IGZ1bmN0aW9uIG5vX292ZXJmbG93NjQodmFsdWUpIHtcbiAgICAgICAgdmFyIGZpZWxkX25hbWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG4gICAgICAgIHZhciB1bnNpZ25lZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vTG9uZy5qcy9pc3N1ZXMvMjBcbiAgICAgICAgaWYgKF9ieXRlYnVmZmVyLkxvbmcuaXNMb25nKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmlnSW50ZWdlciNpc0JpZ0ludGVnZXIgaHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iaWdpL2lzc3Vlcy8yMFxuICAgICAgICBpZiAodmFsdWUudCAhPT0gdW5kZWZpbmVkICYmIHZhbHVlLnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5ub19vdmVyZmxvdzY0KHZhbHVlLnRvU3RyaW5nKCksIGZpZWxkX25hbWUsIHVuc2lnbmVkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSBsZWFkaW5nIHplcm9zLCB3aWxsIGNhdXNlIGEgZmFsc2UgcG9zaXRpdmVcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXjArLywgXCJcIik7XG4gICAgICAgICAgICAvLyByZW1vdmUgdHJhaWxpbmcgemVyb3NcbiAgICAgICAgICAgIHdoaWxlICgvMCQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHJpbmcoMCwgdmFsdWUubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoL1xcLiQvLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRyYWlsaW5nIGRvdFxuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuc3Vic3RyaW5nKDAsIHZhbHVlLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBcIjBcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBsb25nX3N0cmluZyA9IF9ieXRlYnVmZmVyLkxvbmcuZnJvbVN0cmluZyh2YWx1ZSwgdW5zaWduZWQpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICBpZiAobG9uZ19zdHJpbmcgIT09IHZhbHVlLnRyaW0oKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm92ZXJmbG93IFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IE1BWF9TQUZFX0lOVCB8fCB2YWx1ZSA8IE1JTl9TQUZFX0lOVCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm92ZXJmbG93IFwiICsgZmllbGRfbmFtZSArIFwiIFwiICsgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgXCJ1bnN1cHBvcnRlZCB0eXBlIFwiICsgZmllbGRfbmFtZSArIFwiOiAoXCIgKyAodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YodmFsdWUpKSArIFwiKSBcIiArIHZhbHVlO1xuICAgIH1cbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IF9teTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbi8qKiBFeGNlcHRpb24gbmVzdGluZy4gICovXG52YXIgRXJyb3JXaXRoQ2F1c2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRXJyb3JXaXRoQ2F1c2UobWVzc2FnZSwgY2F1c2UpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEVycm9yV2l0aENhdXNlKTtcblxuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgICAgICBpZiAodHlwZW9mIGNhdXNlICE9PSBcInVuZGVmaW5lZFwiICYmIGNhdXNlICE9PSBudWxsID8gY2F1c2UubWVzc2FnZSA6IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gXCJjYXVzZVxcdFwiICsgY2F1c2UubWVzc2FnZSArIFwiXFx0XCIgKyB0aGlzLm1lc3NhZ2U7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3RhY2sgPSBcIlwiOyAvLyhuZXcgRXJyb3IpLnN0YWNrXG4gICAgICAgIGlmICh0eXBlb2YgY2F1c2UgIT09IFwidW5kZWZpbmVkXCIgJiYgY2F1c2UgIT09IG51bGwgPyBjYXVzZS5zdGFjayA6IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc3RhY2sgPSBcImNhdXNlZCBieVxcblxcdFwiICsgY2F1c2Uuc3RhY2sgKyBcIlxcdFwiICsgc3RhY2s7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnN0YWNrID0gdGhpcy5tZXNzYWdlICsgXCJcXG5cIiArIHN0YWNrO1xuICAgIH1cblxuICAgIEVycm9yV2l0aENhdXNlLnRocm93ID0gZnVuY3Rpb24gX3Rocm93KG1lc3NhZ2UsIGNhdXNlKSB7XG4gICAgICAgIHZhciBtc2cgPSBtZXNzYWdlO1xuICAgICAgICBpZiAodHlwZW9mIGNhdXNlICE9PSBcInVuZGVmaW5lZFwiICYmIGNhdXNlICE9PSBudWxsID8gY2F1c2UubWVzc2FnZSA6IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbXNnICs9IFwiXFx0IGNhdXNlOiBcIiArIGNhdXNlLm1lc3NhZ2UgKyBcIiBcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGNhdXNlICE9PSBcInVuZGVmaW5lZFwiICYmIGNhdXNlICE9PSBudWxsID8gY2F1c2Uuc3RhY2sgOiB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG1zZyArPSBcIlxcbiBzdGFjazogXCIgKyBjYXVzZS5zdGFjayArIFwiIFwiO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgIH07XG5cbiAgICByZXR1cm4gRXJyb3JXaXRoQ2F1c2U7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEVycm9yV2l0aENhdXNlO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHMuc3RlYWx0aF9tZW1vX2RhdGEgPSBleHBvcnRzLnNpZ25lZF90cmFuc2FjdGlvbiA9IGV4cG9ydHMudHJhbnNhY3Rpb24gPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9pc3N1ZXIgPSBleHBvcnRzLmFzc2V0X2NsYWltX3Bvb2wgPSBleHBvcnRzLmV4ZWN1dGVfYmlkID0gZXhwb3J0cy5iaWRfY29sbGF0ZXJhbCA9IGV4cG9ydHMuZmJhX2Rpc3RyaWJ1dGUgPSBleHBvcnRzLmFzc2V0X2NsYWltX2ZlZXMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWwgPSBleHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmQgPSBleHBvcnRzLmJsaW5kX3RyYW5zZmVyID0gZXhwb3J0cy5ibGluZF9pbnB1dCA9IGV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmQgPSBleHBvcnRzLmJsaW5kX291dHB1dCA9IGV4cG9ydHMuc3RlYWx0aF9jb25maXJtYXRpb24gPSBleHBvcnRzLm92ZXJyaWRlX3RyYW5zZmVyID0gZXhwb3J0cy5iYWxhbmNlX2NsYWltID0gZXhwb3J0cy5hc3NlcnQgPSBleHBvcnRzLmJsb2NrX2lkX3ByZWRpY2F0ZSA9IGV4cG9ydHMuYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBleHBvcnRzLmFjY291bnRfbmFtZV9lcV9saXRfcHJlZGljYXRlID0gZXhwb3J0cy5jdXN0b20gPSBleHBvcnRzLndvcmtlcl9jcmVhdGUgPSBleHBvcnRzLmJ1cm5fd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy5yZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGUgPSB1bmRlZmluZWQ7XG5leHBvcnRzLmNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IGV4cG9ydHMubGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycyA9IGV4cG9ydHMuY2hhaW5fcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGUgPSBleHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGUgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlID0gZXhwb3J0cy5wcm9wb3NhbF9kZWxldGUgPSBleHBvcnRzLnByb3Bvc2FsX3VwZGF0ZSA9IGV4cG9ydHMucHJvcG9zYWxfY3JlYXRlID0gZXhwb3J0cy5vcF93cmFwcGVyID0gZXhwb3J0cy53aXRuZXNzX3VwZGF0ZSA9IGV4cG9ydHMud2l0bmVzc19jcmVhdGUgPSBleHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZCA9IGV4cG9ydHMucHJpY2VfZmVlZCA9IGV4cG9ydHMuYXNzZXRfZ2xvYmFsX3NldHRsZSA9IGV4cG9ydHMuYXNzZXRfc2V0dGxlID0gZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sID0gZXhwb3J0cy5hc3NldF9yZXNlcnZlID0gZXhwb3J0cy5hc3NldF9pc3N1ZSA9IGV4cG9ydHMuYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzID0gZXhwb3J0cy5hc3NldF91cGRhdGVfYml0YXNzZXQgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZSA9IGV4cG9ydHMuYXNzZXRfY3JlYXRlID0gZXhwb3J0cy5iaXRhc3NldF9vcHRpb25zID0gZXhwb3J0cy5hc3NldF9vcHRpb25zID0gZXhwb3J0cy5wcmljZSA9IGV4cG9ydHMuYWNjb3VudF90cmFuc2ZlciA9IGV4cG9ydHMuYWNjb3VudF91cGdyYWRlID0gZXhwb3J0cy5hY2NvdW50X3doaXRlbGlzdCA9IGV4cG9ydHMuYWNjb3VudF91cGRhdGUgPSBleHBvcnRzLmFjY291bnRfY3JlYXRlID0gZXhwb3J0cy5hY2NvdW50X29wdGlvbnMgPSBleHBvcnRzLmF1dGhvcml0eSA9IGV4cG9ydHMuZmlsbF9vcmRlciA9IGV4cG9ydHMuY2FsbF9vcmRlcl91cGRhdGUgPSBleHBvcnRzLmxpbWl0X29yZGVyX2NhbmNlbCA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlID0gZXhwb3J0cy50cmFuc2ZlciA9IGV4cG9ydHMubWVtb19kYXRhID0gZXhwb3J0cy5zaWduZWRfYmxvY2tfaGVhZGVyID0gZXhwb3J0cy5ibG9ja19oZWFkZXIgPSBleHBvcnRzLnNpZ25lZF9ibG9jayA9IGV4cG9ydHMucHJvY2Vzc2VkX3RyYW5zYWN0aW9uID0gZXhwb3J0cy5hc3NldCA9IGV4cG9ydHMudm9pZF9yZXN1bHQgPSBleHBvcnRzLmZlZV9zY2hlZHVsZSA9IGV4cG9ydHMuYXNzZXRfdXBkYXRlX2lzc3Vlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2NsYWltX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5leGVjdXRlX2JpZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJpZF9jb2xsYXRlcmFsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuZmJhX2Rpc3RyaWJ1dGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9jbGFpbV9mZWVzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfc2V0dGxlX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5ibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnRyYW5zZmVyX3RvX2JsaW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMub3ZlcnJpZGVfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5iYWxhbmNlX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud29ya2VyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV93aXRoZHJhd19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMucHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMucHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMucHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0bmVzc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2lzc3VlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmxpbWl0X29yZGVyX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmxpbWl0X29yZGVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnRyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMub3BlcmF0aW9uID0gdW5kZWZpbmVkO1xuXG52YXIgX3R5cGVzID0gcmVxdWlyZShcIi4vdHlwZXNcIik7XG5cbnZhciBfdHlwZXMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdHlwZXMpO1xuXG52YXIgX3NlcmlhbGl6ZXIgPSByZXF1aXJlKFwiLi9zZXJpYWxpemVyXCIpO1xuXG52YXIgX3NlcmlhbGl6ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2VyaWFsaXplcik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciB1aW50OCA9IF90eXBlczIuZGVmYXVsdC51aW50OCxcbiAgICB1aW50MTYgPSBfdHlwZXMyLmRlZmF1bHQudWludDE2LFxuICAgIHVpbnQzMiA9IF90eXBlczIuZGVmYXVsdC51aW50MzIsXG4gICAgaW50NjQgPSBfdHlwZXMyLmRlZmF1bHQuaW50NjQsXG4gICAgdWludDY0ID0gX3R5cGVzMi5kZWZhdWx0LnVpbnQ2NCxcbiAgICBzdHJpbmcgPSBfdHlwZXMyLmRlZmF1bHQuc3RyaW5nLFxuICAgIGJ5dGVzID0gX3R5cGVzMi5kZWZhdWx0LmJ5dGVzLFxuICAgIGJvb2wgPSBfdHlwZXMyLmRlZmF1bHQuYm9vbCxcbiAgICBhcnJheSA9IF90eXBlczIuZGVmYXVsdC5hcnJheSxcbiAgICBwcm90b2NvbF9pZF90eXBlID0gX3R5cGVzMi5kZWZhdWx0LnByb3RvY29sX2lkX3R5cGUsXG4gICAgb2JqZWN0X2lkX3R5cGUgPSBfdHlwZXMyLmRlZmF1bHQub2JqZWN0X2lkX3R5cGUsXG4gICAgdm90ZV9pZCA9IF90eXBlczIuZGVmYXVsdC52b3RlX2lkLFxuICAgIGZ1dHVyZV9leHRlbnNpb25zID0gX3R5cGVzMi5kZWZhdWx0LmZ1dHVyZV9leHRlbnNpb25zLFxuICAgIHN0YXRpY192YXJpYW50ID0gX3R5cGVzMi5kZWZhdWx0LnN0YXRpY192YXJpYW50LFxuICAgIG1hcCA9IF90eXBlczIuZGVmYXVsdC5tYXAsXG4gICAgc2V0ID0gX3R5cGVzMi5kZWZhdWx0LnNldCxcbiAgICBwdWJsaWNfa2V5ID0gX3R5cGVzMi5kZWZhdWx0LnB1YmxpY19rZXksXG4gICAgYWRkcmVzcyA9IF90eXBlczIuZGVmYXVsdC5hZGRyZXNzLFxuICAgIHRpbWVfcG9pbnRfc2VjID0gX3R5cGVzMi5kZWZhdWx0LnRpbWVfcG9pbnRfc2VjLFxuICAgIG9wdGlvbmFsID0gX3R5cGVzMi5kZWZhdWx0Lm9wdGlvbmFsLFxuICAgIGV4dGVuc2lvbiA9IF90eXBlczIuZGVmYXVsdC5leHRlbnNpb247XG5cblxuZnV0dXJlX2V4dGVuc2lvbnMgPSBfdHlwZXMyLmRlZmF1bHQudm9pZDtcblxuLypcbldoZW4gdXBkYXRpbmcgZ2VuZXJhdGVkIGNvZGVcblJlcGxhY2U6ICBvcGVyYXRpb24gPSBzdGF0aWNfdmFyaWFudCBbXG53aXRoOiAgICAgb3BlcmF0aW9uLnN0X29wZXJhdGlvbnMgPSBbXG5cbkRlbGV0ZTpcbnB1YmxpY19rZXkgPSBuZXcgU2VyaWFsaXplcihcbiAgICBcInB1YmxpY19rZXlcIlxuICAgIGtleV9kYXRhOiBieXRlcyAzM1xuKVxuXG4qL1xuLy8gUGxhY2UtaG9sZGVyLCB0aGVpciBhcmUgZGVwZW5kZW5jaWVzIG9uIFwib3BlcmF0aW9uXCIgLi4gVGhlIGZpbmFsIGxpc3Qgb2Zcbi8vIG9wZXJhdGlvbnMgaXMgbm90IGF2aWFsYmxlIHVudGlsIHRoZSB2ZXJ5IGVuZCBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUuXG4vLyBTZWU6IG9wZXJhdGlvbi5zdF9vcGVyYXRpb25zID0gLi4uXG52YXIgb3BlcmF0aW9uID0gc3RhdGljX3ZhcmlhbnQoKTtcbi8vIG1vZHVsZS5leHBvcnRzW1wib3BlcmF0aW9uXCJdID0gb3BlcmF0aW9uO1xuXG5leHBvcnRzLm9wZXJhdGlvbiA9IG9wZXJhdGlvbjtcbi8vIEZvciBtb2R1bGUuZXhwb3J0c1xuXG52YXIgU2VyaWFsaXplciA9IGZ1bmN0aW9uIFNlcmlhbGl6ZXIob3BlcmF0aW9uX25hbWUsIHNlcmlsaXphdGlvbl90eXBlc19vYmplY3QpIHtcbiAgICByZXR1cm4gbmV3IF9zZXJpYWxpemVyMi5kZWZhdWx0KG9wZXJhdGlvbl9uYW1lLCBzZXJpbGl6YXRpb25fdHlwZXNfb2JqZWN0KTtcbiAgICAvLyByZXR1cm4gbW9kdWxlLmV4cG9ydHNbb3BlcmF0aW9uX25hbWVdID0gcztcbn07XG5cbi8vIEN1c3RvbS10eXBlcyBmb2xsb3cgR2VuZXJhdGVkIGNvZGU6XG5cbi8vICMjICBHZW5lcmF0ZWQgY29kZSBmb2xsb3dzXG4vLyAjIHByb2dyYW1zL2pzX29wZXJhdGlvbl9zZXJpYWxpemVyID4gbnBtIGkgLWcgZGVjYWZmZWluYXRlXG4vLyAjIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG52YXIgdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy50cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcInRyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgbGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwibGltaXRfb3JkZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgbGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMubGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwibGltaXRfb3JkZXJfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY2FsbF9vcmRlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImNhbGxfb3JkZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgZmlsbF9vcmRlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJmaWxsX29yZGVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiKTtcblxudmFyIGFjY291bnRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYWNjb3VudF9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwge1xuICAgIGJhc2ljX2ZlZTogdWludDY0LFxuICAgIHByZW1pdW1fZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgYWNjb3VudF91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hY2NvdW50X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiBpbnQ2NCxcbiAgICBwcmljZV9wZXJfa2J5dGU6IHVpbnQzMlxufSk7XG5cbnZhciBhY2NvdW50X3doaXRlbGlzdF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfd2hpdGVsaXN0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHsgZmVlOiBpbnQ2NCB9KTtcblxudmFyIGFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfdXBncmFkZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwge1xuICAgIG1lbWJlcnNoaXBfYW5udWFsX2ZlZTogdWludDY0LFxuICAgIG1lbWJlcnNoaXBfbGlmZXRpbWVfZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYWNjb3VudF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFjY291bnRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgc3ltYm9sMzogdWludDY0LFxuICAgIHN5bWJvbDQ6IHVpbnQ2NCxcbiAgICBsb25nX3N5bWJvbDogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwge1xuICAgIGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3VwZGF0ZV9iaXRhc3NldF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2Vyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2Vyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2Vyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X2lzc3VlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9pc3N1ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwge1xuICAgIGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIGFzc2V0X3Jlc2VydmVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfcmVzZXJ2ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X2Z1bmRfZmVlX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9mdW5kX2ZlZV9wb29sX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9nbG9iYWxfc2V0dGxlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfZ2xvYmFsX3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGFzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3B1Ymxpc2hfZmVlZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIHdpdG5lc3NfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0bmVzc19jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMud2l0bmVzc191cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRuZXNzX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IGludDY0IH0pO1xuXG52YXIgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMucHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwicHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMucHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwicHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMucHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwicHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIndpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9kZWxldGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcIndpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY29tbWl0dGVlX21lbWJlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwidmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgd29ya2VyX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLndvcmtlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ3b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjQsXG4gICAgcHJpY2VfcGVyX2tieXRlOiB1aW50MzJcbn0pO1xuXG52YXIgYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJhbGFuY2VfY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJiYWxhbmNlX2NsYWltX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiKTtcblxudmFyIG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMub3ZlcnJpZGVfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJvdmVycmlkZV90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwge1xuICAgIGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9rYnl0ZTogdWludDMyXG59KTtcblxudmFyIHRyYW5zZmVyX3RvX2JsaW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMudHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ0cmFuc2Zlcl90b19ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwge1xuICAgIGZlZTogdWludDY0LFxuICAgIHByaWNlX3Blcl9vdXRwdXQ6IHVpbnQzMlxufSk7XG5cbnZhciBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJsaW5kX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYmxpbmRfdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHtcbiAgICBmZWU6IHVpbnQ2NCxcbiAgICBwcmljZV9wZXJfb3V0cHV0OiB1aW50MzJcbn0pO1xuXG52YXIgdHJhbnNmZXJfZnJvbV9ibGluZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLnRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJ0cmFuc2Zlcl9mcm9tX2JsaW5kX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7IGZlZTogdWludDY0IH0pO1xuXG52YXIgYXNzZXRfc2V0dGxlX2NhbmNlbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiKTtcblxudmFyIGFzc2V0X2NsYWltX2ZlZXNfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gZXhwb3J0cy5hc3NldF9jbGFpbV9mZWVzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIiwgeyBmZWU6IHVpbnQ2NCB9KTtcblxudmFyIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IGV4cG9ydHMuZmJhX2Rpc3RyaWJ1dGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJmYmFfZGlzdHJpYnV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnNcIik7XG5cbnZhciBiaWRfY29sbGF0ZXJhbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmJpZF9jb2xsYXRlcmFsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiYmlkX2NvbGxhdGVyYWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIsIHtcbiAgICBmZWU6IHVpbnQ2NFxufSk7XG5cbnZhciBleGVjdXRlX2JpZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmV4ZWN1dGVfYmlkX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycyA9IG5ldyBTZXJpYWxpemVyKFwiZXhlY3V0ZV9iaWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzXCIpO1xuXG52YXIgYXNzZXRfY2xhaW1fcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X2NsYWltX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9jbGFpbV9wb29sX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgYXNzZXRfdXBkYXRlX2lzc3Vlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9pc3N1ZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF91cGRhdGVfaXNzdWVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc1wiLCB7XG4gICAgZmVlOiB1aW50NjRcbn0pO1xuXG52YXIgZmVlX3BhcmFtZXRlcnMgPSBzdGF0aWNfdmFyaWFudChbdHJhbnNmZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBsaW1pdF9vcmRlcl9jYW5jZWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjYWxsX29yZGVyX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZpbGxfb3JkZXJfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFjY291bnRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYWNjb3VudF93aGl0ZWxpc3Rfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3VwZ3JhZGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhY2NvdW50X3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2JpdGFzc2V0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfaXNzdWVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9yZXNlcnZlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfZnVuZF9mZWVfcG9vbF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X3NldHRsZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X2dsb2JhbF9zZXR0bGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9wdWJsaXNoX2ZlZWRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRuZXNzX2NyZWF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdG5lc3NfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfdXBkYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgcHJvcG9zYWxfZGVsZXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHdpdGhkcmF3X3Blcm1pc3Npb25fY2xhaW1fb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY29tbWl0dGVlX21lbWJlcl91cGRhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVyc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHZlc3RpbmdfYmFsYW5jZV9jcmVhdGVfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB2ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXdfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCB3b3JrZXJfY3JlYXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgY3VzdG9tX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXJ0X29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmFsYW5jZV9jbGFpbV9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIG92ZXJyaWRlX3RyYW5zZmVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgdHJhbnNmZXJfdG9fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBibGluZF90cmFuc2Zlcl9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIHRyYW5zZmVyX2Zyb21fYmxpbmRfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF9zZXR0bGVfY2FuY2VsX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYXNzZXRfY2xhaW1fZmVlc19vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGZiYV9kaXN0cmlidXRlX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVycywgYmlkX2NvbGxhdGVyYWxfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBleGVjdXRlX2JpZF9vcGVyYXRpb25fZmVlX3BhcmFtZXRlcnMsIGFzc2V0X2NsYWltX3Bvb2xfb3BlcmF0aW9uX2ZlZV9wYXJhbWV0ZXJzLCBhc3NldF91cGRhdGVfaXNzdWVyX29wZXJhdGlvbl9mZWVfcGFyYW1ldGVyc10pO1xuXG52YXIgZmVlX3NjaGVkdWxlID0gZXhwb3J0cy5mZWVfc2NoZWR1bGUgPSBuZXcgU2VyaWFsaXplcihcImZlZV9zY2hlZHVsZVwiLCB7XG4gICAgcGFyYW1ldGVyczogc2V0KGZlZV9wYXJhbWV0ZXJzKSxcbiAgICBzY2FsZTogdWludDMyXG59KTtcblxudmFyIHZvaWRfcmVzdWx0ID0gZXhwb3J0cy52b2lkX3Jlc3VsdCA9IG5ldyBTZXJpYWxpemVyKFwidm9pZF9yZXN1bHRcIik7XG5cbnZhciBhc3NldCA9IGV4cG9ydHMuYXNzZXQgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0XCIsIHtcbiAgICBhbW91bnQ6IGludDY0LFxuICAgIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIilcbn0pO1xuXG52YXIgb3BlcmF0aW9uX3Jlc3VsdCA9IHN0YXRpY192YXJpYW50KFt2b2lkX3Jlc3VsdCwgb2JqZWN0X2lkX3R5cGUsIGFzc2V0XSk7XG5cbnZhciBwcm9jZXNzZWRfdHJhbnNhY3Rpb24gPSBleHBvcnRzLnByb2Nlc3NlZF90cmFuc2FjdGlvbiA9IG5ldyBTZXJpYWxpemVyKFwicHJvY2Vzc2VkX3RyYW5zYWN0aW9uXCIsIHtcbiAgICByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gICAgcmVmX2Jsb2NrX3ByZWZpeDogdWludDMyLFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpLFxuICAgIG9wZXJhdGlvbl9yZXN1bHRzOiBhcnJheShvcGVyYXRpb25fcmVzdWx0KVxufSk7XG5cbnZhciBzaWduZWRfYmxvY2sgPSBleHBvcnRzLnNpZ25lZF9ibG9jayA9IG5ldyBTZXJpYWxpemVyKFwic2lnbmVkX2Jsb2NrXCIsIHtcbiAgICBwcmV2aW91czogYnl0ZXMoMjApLFxuICAgIHRpbWVzdGFtcDogdGltZV9wb2ludF9zZWMsXG4gICAgd2l0bmVzczogcHJvdG9jb2xfaWRfdHlwZShcIndpdG5lc3NcIiksXG4gICAgdHJhbnNhY3Rpb25fbWVya2xlX3Jvb3Q6IGJ5dGVzKDIwKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpLFxuICAgIHdpdG5lc3Nfc2lnbmF0dXJlOiBieXRlcyg2NSksXG4gICAgdHJhbnNhY3Rpb25zOiBhcnJheShwcm9jZXNzZWRfdHJhbnNhY3Rpb24pXG59KTtcblxudmFyIGJsb2NrX2hlYWRlciA9IGV4cG9ydHMuYmxvY2tfaGVhZGVyID0gbmV3IFNlcmlhbGl6ZXIoXCJibG9ja19oZWFkZXJcIiwge1xuICAgIHByZXZpb3VzOiBieXRlcygyMCksXG4gICAgdGltZXN0YW1wOiB0aW1lX3BvaW50X3NlYyxcbiAgICB3aXRuZXNzOiBwcm90b2NvbF9pZF90eXBlKFwid2l0bmVzc1wiKSxcbiAgICB0cmFuc2FjdGlvbl9tZXJrbGVfcm9vdDogYnl0ZXMoMjApLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgc2lnbmVkX2Jsb2NrX2hlYWRlciA9IGV4cG9ydHMuc2lnbmVkX2Jsb2NrX2hlYWRlciA9IG5ldyBTZXJpYWxpemVyKFwic2lnbmVkX2Jsb2NrX2hlYWRlclwiLCB7XG4gICAgcHJldmlvdXM6IGJ5dGVzKDIwKSxcbiAgICB0aW1lc3RhbXA6IHRpbWVfcG9pbnRfc2VjLFxuICAgIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRuZXNzXCIpLFxuICAgIHRyYW5zYWN0aW9uX21lcmtsZV9yb290OiBieXRlcygyMCksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgICB3aXRuZXNzX3NpZ25hdHVyZTogYnl0ZXMoNjUpXG59KTtcblxudmFyIG1lbW9fZGF0YSA9IGV4cG9ydHMubWVtb19kYXRhID0gbmV3IFNlcmlhbGl6ZXIoXCJtZW1vX2RhdGFcIiwge1xuICAgIGZyb206IHB1YmxpY19rZXksXG4gICAgdG86IHB1YmxpY19rZXksXG4gICAgbm9uY2U6IHVpbnQ2NCxcbiAgICBtZXNzYWdlOiBieXRlcygpXG59KTtcblxudmFyIHRyYW5zZmVyID0gZXhwb3J0cy50cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKFwidHJhbnNmZXJcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgZnJvbTogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgdG86IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKSxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGxpbWl0X29yZGVyX2NyZWF0ZSA9IGV4cG9ydHMubGltaXRfb3JkZXJfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJsaW1pdF9vcmRlcl9jcmVhdGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgc2VsbGVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnRfdG9fc2VsbDogYXNzZXQsXG4gICAgbWluX3RvX3JlY2VpdmU6IGFzc2V0LFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIGZpbGxfb3Jfa2lsbDogYm9vbCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGxpbWl0X29yZGVyX2NhbmNlbCA9IGV4cG9ydHMubGltaXRfb3JkZXJfY2FuY2VsID0gbmV3IFNlcmlhbGl6ZXIoXCJsaW1pdF9vcmRlcl9jYW5jZWxcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgZmVlX3BheWluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBvcmRlcjogcHJvdG9jb2xfaWRfdHlwZShcImxpbWl0X29yZGVyXCIpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgY2FsbF9vcmRlcl91cGRhdGUgPSBleHBvcnRzLmNhbGxfb3JkZXJfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJjYWxsX29yZGVyX3VwZGF0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBmdW5kaW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGRlbHRhX2NvbGxhdGVyYWw6IGFzc2V0LFxuICAgIGRlbHRhX2RlYnQ6IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IGV4dGVuc2lvbihbe1xuICAgICAgICBuYW1lOiBcInRhcmdldF9jb2xsYXRlcmFsX3JhdGlvXCIsXG4gICAgICAgIHR5cGU6IHVpbnQxNlxuICAgIH1dKVxufSk7XG5cbnZhciBmaWxsX29yZGVyID0gZXhwb3J0cy5maWxsX29yZGVyID0gbmV3IFNlcmlhbGl6ZXIoXCJmaWxsX29yZGVyXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIG9yZGVyX2lkOiBvYmplY3RfaWRfdHlwZSxcbiAgICBhY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBwYXlzOiBhc3NldCxcbiAgICByZWNlaXZlczogYXNzZXRcbn0pO1xuXG52YXIgYXV0aG9yaXR5ID0gZXhwb3J0cy5hdXRob3JpdHkgPSBuZXcgU2VyaWFsaXplcihcImF1dGhvcml0eVwiLCB7XG4gICAgd2VpZ2h0X3RocmVzaG9sZDogdWludDMyLFxuICAgIGFjY291bnRfYXV0aHM6IG1hcChwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSwgdWludDE2KSxcbiAgICBrZXlfYXV0aHM6IG1hcChwdWJsaWNfa2V5LCB1aW50MTYpLFxuICAgIGFkZHJlc3NfYXV0aHM6IG1hcChhZGRyZXNzLCB1aW50MTYpXG59KTtcblxudmFyIGFjY291bnRfb3B0aW9ucyA9IGV4cG9ydHMuYWNjb3VudF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X29wdGlvbnNcIiwge1xuICAgIG1lbW9fa2V5OiBwdWJsaWNfa2V5LFxuICAgIHZvdGluZ19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBudW1fd2l0bmVzczogdWludDE2LFxuICAgIG51bV9jb21taXR0ZWU6IHVpbnQxNixcbiAgICB2b3Rlczogc2V0KHZvdGVfaWQpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYWNjb3VudF9jcmVhdGUgPSBleHBvcnRzLmFjY291bnRfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X2NyZWF0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICByZWdpc3RyYXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHJlZmVycmVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICByZWZlcnJlcl9wZXJjZW50OiB1aW50MTYsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIG93bmVyOiBhdXRob3JpdHksXG4gICAgYWN0aXZlOiBhdXRob3JpdHksXG4gICAgb3B0aW9uczogYWNjb3VudF9vcHRpb25zLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYWNjb3VudF91cGRhdGUgPSBleHBvcnRzLmFjY291bnRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhY2NvdW50X3VwZGF0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBhY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBvd25lcjogb3B0aW9uYWwoYXV0aG9yaXR5KSxcbiAgICBhY3RpdmU6IG9wdGlvbmFsKGF1dGhvcml0eSksXG4gICAgbmV3X29wdGlvbnM6IG9wdGlvbmFsKGFjY291bnRfb3B0aW9ucyksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhY2NvdW50X3doaXRlbGlzdCA9IGV4cG9ydHMuYWNjb3VudF93aGl0ZWxpc3QgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfd2hpdGVsaXN0XCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGF1dGhvcml6aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFjY291bnRfdG9fbGlzdDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbmV3X2xpc3Rpbmc6IHVpbnQ4LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYWNjb3VudF91cGdyYWRlID0gZXhwb3J0cy5hY2NvdW50X3VwZ3JhZGUgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfdXBncmFkZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBhY2NvdW50X3RvX3VwZ3JhZGU6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHVwZ3JhZGVfdG9fbGlmZXRpbWVfbWVtYmVyOiBib29sLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYWNjb3VudF90cmFuc2ZlciA9IGV4cG9ydHMuYWNjb3VudF90cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKFwiYWNjb3VudF90cmFuc2ZlclwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBhY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBuZXdfb3duZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJpY2UgPSBleHBvcnRzLnByaWNlID0gbmV3IFNlcmlhbGl6ZXIoXCJwcmljZVwiLCB7XG4gICAgYmFzZTogYXNzZXQsXG4gICAgcXVvdGU6IGFzc2V0XG59KTtcblxudmFyIGFzc2V0X29wdGlvbnMgPSBleHBvcnRzLmFzc2V0X29wdGlvbnMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X29wdGlvbnNcIiwge1xuICAgIG1heF9zdXBwbHk6IGludDY0LFxuICAgIG1hcmtldF9mZWVfcGVyY2VudDogdWludDE2LFxuICAgIG1heF9tYXJrZXRfZmVlOiBpbnQ2NCxcbiAgICBpc3N1ZXJfcGVybWlzc2lvbnM6IHVpbnQxNixcbiAgICBmbGFnczogdWludDE2LFxuICAgIGNvcmVfZXhjaGFuZ2VfcmF0ZTogcHJpY2UsXG4gICAgd2hpdGVsaXN0X2F1dGhvcml0aWVzOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIGJsYWNrbGlzdF9hdXRob3JpdGllczogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICB3aGl0ZWxpc3RfbWFya2V0czogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSksXG4gICAgYmxhY2tsaXN0X21hcmtldHM6IHNldChwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIikpLFxuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmcsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiaXRhc3NldF9vcHRpb25zID0gZXhwb3J0cy5iaXRhc3NldF9vcHRpb25zID0gbmV3IFNlcmlhbGl6ZXIoXCJiaXRhc3NldF9vcHRpb25zXCIsIHtcbiAgICBmZWVkX2xpZmV0aW1lX3NlYzogdWludDMyLFxuICAgIG1pbmltdW1fZmVlZHM6IHVpbnQ4LFxuICAgIGZvcmNlX3NldHRsZW1lbnRfZGVsYXlfc2VjOiB1aW50MzIsXG4gICAgZm9yY2Vfc2V0dGxlbWVudF9vZmZzZXRfcGVyY2VudDogdWludDE2LFxuICAgIG1heGltdW1fZm9yY2Vfc2V0dGxlbWVudF92b2x1bWU6IHVpbnQxNixcbiAgICBzaG9ydF9iYWNraW5nX2Fzc2V0OiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF9jcmVhdGUgPSBleHBvcnRzLmFzc2V0X2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfY3JlYXRlXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgc3ltYm9sOiBzdHJpbmcsXG4gICAgcHJlY2lzaW9uOiB1aW50OCxcbiAgICBjb21tb25fb3B0aW9uczogYXNzZXRfb3B0aW9ucyxcbiAgICBiaXRhc3NldF9vcHRzOiBvcHRpb25hbChiaXRhc3NldF9vcHRpb25zKSxcbiAgICBpc19wcmVkaWN0aW9uX21hcmtldDogYm9vbCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X3VwZGF0ZSA9IGV4cG9ydHMuYXNzZXRfdXBkYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF91cGRhdGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhc3NldF90b191cGRhdGU6IHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSxcbiAgICBuZXdfaXNzdWVyOiBvcHRpb25hbChwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSksXG4gICAgbmV3X29wdGlvbnM6IGFzc2V0X29wdGlvbnMsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF91cGRhdGVfYml0YXNzZXQgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9iaXRhc3NldCA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX2JpdGFzc2V0XCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXNzZXRfdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgbmV3X29wdGlvbnM6IGJpdGFzc2V0X29wdGlvbnMsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF91cGRhdGVfZmVlZF9wcm9kdWNlcnMgPSBleHBvcnRzLmFzc2V0X3VwZGF0ZV9mZWVkX3Byb2R1Y2VycyA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXNzZXRfdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgbmV3X2ZlZWRfcHJvZHVjZXJzOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfaXNzdWUgPSBleHBvcnRzLmFzc2V0X2lzc3VlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9pc3N1ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X3RvX2lzc3VlOiBhc3NldCxcbiAgICBpc3N1ZV90b19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBtZW1vOiBvcHRpb25hbChtZW1vX2RhdGEpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfcmVzZXJ2ZSA9IGV4cG9ydHMuYXNzZXRfcmVzZXJ2ZSA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfcmVzZXJ2ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBwYXllcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYW1vdW50X3RvX3Jlc2VydmU6IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgYXNzZXRfZnVuZF9mZWVfcG9vbCA9IGV4cG9ydHMuYXNzZXRfZnVuZF9mZWVfcG9vbCA9IG5ldyBTZXJpYWxpemVyKFwiYXNzZXRfZnVuZF9mZWVfcG9vbFwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBmcm9tX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgYW1vdW50OiBpbnQ2NCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X3NldHRsZSA9IGV4cG9ydHMuYXNzZXRfc2V0dGxlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zZXR0bGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYW1vdW50OiBhc3NldCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X2dsb2JhbF9zZXR0bGUgPSBleHBvcnRzLmFzc2V0X2dsb2JhbF9zZXR0bGUgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2dsb2JhbF9zZXR0bGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhc3NldF90b19zZXR0bGU6IHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSxcbiAgICBzZXR0bGVfcHJpY2U6IHByaWNlLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJpY2VfZmVlZCA9IGV4cG9ydHMucHJpY2VfZmVlZCA9IG5ldyBTZXJpYWxpemVyKFwicHJpY2VfZmVlZFwiLCB7XG4gICAgc2V0dGxlbWVudF9wcmljZTogcHJpY2UsXG4gICAgbWFpbnRlbmFuY2VfY29sbGF0ZXJhbF9yYXRpbzogdWludDE2LFxuICAgIG1heGltdW1fc2hvcnRfc3F1ZWV6ZV9yYXRpbzogdWludDE2LFxuICAgIGNvcmVfZXhjaGFuZ2VfcmF0ZTogcHJpY2Vcbn0pO1xuXG52YXIgYXNzZXRfcHVibGlzaF9mZWVkID0gZXhwb3J0cy5hc3NldF9wdWJsaXNoX2ZlZWQgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3B1Ymxpc2hfZmVlZFwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBwdWJsaXNoZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFzc2V0X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgZmVlZDogcHJpY2VfZmVlZCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIHdpdG5lc3NfY3JlYXRlID0gZXhwb3J0cy53aXRuZXNzX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0bmVzc19jcmVhdGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgd2l0bmVzc19hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB1cmw6IHN0cmluZyxcbiAgICBibG9ja19zaWduaW5nX2tleTogcHVibGljX2tleVxufSk7XG5cbnZhciB3aXRuZXNzX3VwZGF0ZSA9IGV4cG9ydHMud2l0bmVzc191cGRhdGUgPSBuZXcgU2VyaWFsaXplcihcIndpdG5lc3NfdXBkYXRlXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIHdpdG5lc3M6IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRuZXNzXCIpLFxuICAgIHdpdG5lc3NfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbmV3X3VybDogb3B0aW9uYWwoc3RyaW5nKSxcbiAgICBuZXdfc2lnbmluZ19rZXk6IG9wdGlvbmFsKHB1YmxpY19rZXkpXG59KTtcblxudmFyIG9wX3dyYXBwZXIgPSBleHBvcnRzLm9wX3dyYXBwZXIgPSBuZXcgU2VyaWFsaXplcihcIm9wX3dyYXBwZXJcIiwgeyBvcDogb3BlcmF0aW9uIH0pO1xuXG52YXIgcHJvcG9zYWxfY3JlYXRlID0gZXhwb3J0cy5wcm9wb3NhbF9jcmVhdGUgPSBuZXcgU2VyaWFsaXplcihcInByb3Bvc2FsX2NyZWF0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGV4cGlyYXRpb25fdGltZTogdGltZV9wb2ludF9zZWMsXG4gICAgcHJvcG9zZWRfb3BzOiBhcnJheShvcF93cmFwcGVyKSxcbiAgICByZXZpZXdfcGVyaW9kX3NlY29uZHM6IG9wdGlvbmFsKHVpbnQzMiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBwcm9wb3NhbF91cGRhdGUgPSBleHBvcnRzLnByb3Bvc2FsX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKFwicHJvcG9zYWxfdXBkYXRlXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGZlZV9wYXlpbmdfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgcHJvcG9zYWw6IHByb3RvY29sX2lkX3R5cGUoXCJwcm9wb3NhbFwiKSxcbiAgICBhY3RpdmVfYXBwcm92YWxzX3RvX2FkZDogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICBhY3RpdmVfYXBwcm92YWxzX3RvX3JlbW92ZTogc2V0KHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpKSxcbiAgICBvd25lcl9hcHByb3ZhbHNfdG9fYWRkOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIG93bmVyX2FwcHJvdmFsc190b19yZW1vdmU6IHNldChwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSksXG4gICAga2V5X2FwcHJvdmFsc190b19hZGQ6IHNldChwdWJsaWNfa2V5KSxcbiAgICBrZXlfYXBwcm92YWxzX3RvX3JlbW92ZTogc2V0KHB1YmxpY19rZXkpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgcHJvcG9zYWxfZGVsZXRlID0gZXhwb3J0cy5wcm9wb3NhbF9kZWxldGUgPSBuZXcgU2VyaWFsaXplcihcInByb3Bvc2FsX2RlbGV0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHVzaW5nX293bmVyX2F1dGhvcml0eTogYm9vbCxcbiAgICBwcm9wb3NhbDogcHJvdG9jb2xfaWRfdHlwZShcInByb3Bvc2FsXCIpLFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGUgPSBleHBvcnRzLndpdGhkcmF3X3Blcm1pc3Npb25fY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJ3aXRoZHJhd19wZXJtaXNzaW9uX2NyZWF0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICB3aXRoZHJhd19mcm9tX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGF1dGhvcml6ZWRfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgd2l0aGRyYXdhbF9saW1pdDogYXNzZXQsXG4gICAgd2l0aGRyYXdhbF9wZXJpb2Rfc2VjOiB1aW50MzIsXG4gICAgcGVyaW9kc191bnRpbF9leHBpcmF0aW9uOiB1aW50MzIsXG4gICAgcGVyaW9kX3N0YXJ0X3RpbWU6IHRpbWVfcG9pbnRfc2VjXG59KTtcblxudmFyIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlID0gZXhwb3J0cy53aXRoZHJhd19wZXJtaXNzaW9uX3VwZGF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid2l0aGRyYXdfcGVybWlzc2lvbl91cGRhdGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgd2l0aGRyYXdfZnJvbV9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhdXRob3JpemVkX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHBlcm1pc3Npb25fdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKFwid2l0aGRyYXdfcGVybWlzc2lvblwiKSxcbiAgICB3aXRoZHJhd2FsX2xpbWl0OiBhc3NldCxcbiAgICB3aXRoZHJhd2FsX3BlcmlvZF9zZWM6IHVpbnQzMixcbiAgICBwZXJpb2Rfc3RhcnRfdGltZTogdGltZV9wb2ludF9zZWMsXG4gICAgcGVyaW9kc191bnRpbF9leHBpcmF0aW9uOiB1aW50MzJcbn0pO1xuXG52YXIgd2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbSA9IG5ldyBTZXJpYWxpemVyKFwid2l0aGRyYXdfcGVybWlzc2lvbl9jbGFpbVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICB3aXRoZHJhd19wZXJtaXNzaW9uOiBwcm90b2NvbF9pZF90eXBlKFwid2l0aGRyYXdfcGVybWlzc2lvblwiKSxcbiAgICB3aXRoZHJhd19mcm9tX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHdpdGhkcmF3X3RvX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudF90b193aXRoZHJhdzogYXNzZXQsXG4gICAgbWVtbzogb3B0aW9uYWwobWVtb19kYXRhKVxufSk7XG5cbnZhciB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSA9IGV4cG9ydHMud2l0aGRyYXdfcGVybWlzc2lvbl9kZWxldGUgPSBuZXcgU2VyaWFsaXplcihcIndpdGhkcmF3X3Blcm1pc3Npb25fZGVsZXRlXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIHdpdGhkcmF3X2Zyb21fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXV0aG9yaXplZF9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB3aXRoZHJhd2FsX3Blcm1pc3Npb246IHByb3RvY29sX2lkX3R5cGUoXCJ3aXRoZHJhd19wZXJtaXNzaW9uXCIpXG59KTtcblxudmFyIGNvbW1pdHRlZV9tZW1iZXJfY3JlYXRlID0gZXhwb3J0cy5jb21taXR0ZWVfbWVtYmVyX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwiY29tbWl0dGVlX21lbWJlcl9jcmVhdGVcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgY29tbWl0dGVlX21lbWJlcl9hY2NvdW50OiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICB1cmw6IHN0cmluZ1xufSk7XG5cbnZhciBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZSA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGUgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGNvbW1pdHRlZV9tZW1iZXI6IHByb3RvY29sX2lkX3R5cGUoXCJjb21taXR0ZWVfbWVtYmVyXCIpLFxuICAgIGNvbW1pdHRlZV9tZW1iZXJfYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgbmV3X3VybDogb3B0aW9uYWwoc3RyaW5nKVxufSk7XG5cbnZhciBjaGFpbl9wYXJhbWV0ZXJzID0gZXhwb3J0cy5jaGFpbl9wYXJhbWV0ZXJzID0gbmV3IFNlcmlhbGl6ZXIoXCJjaGFpbl9wYXJhbWV0ZXJzXCIsIHtcbiAgICBjdXJyZW50X2ZlZXM6IGZlZV9zY2hlZHVsZSxcbiAgICBibG9ja19pbnRlcnZhbDogdWludDgsXG4gICAgbWFpbnRlbmFuY2VfaW50ZXJ2YWw6IHVpbnQzMixcbiAgICBtYWludGVuYW5jZV9za2lwX3Nsb3RzOiB1aW50OCxcbiAgICBjb21taXR0ZWVfcHJvcG9zYWxfcmV2aWV3X3BlcmlvZDogdWludDMyLFxuICAgIG1heGltdW1fdHJhbnNhY3Rpb25fc2l6ZTogdWludDMyLFxuICAgIG1heGltdW1fYmxvY2tfc2l6ZTogdWludDMyLFxuICAgIG1heGltdW1fdGltZV91bnRpbF9leHBpcmF0aW9uOiB1aW50MzIsXG4gICAgbWF4aW11bV9wcm9wb3NhbF9saWZldGltZTogdWludDMyLFxuICAgIG1heGltdW1fYXNzZXRfd2hpdGVsaXN0X2F1dGhvcml0aWVzOiB1aW50OCxcbiAgICBtYXhpbXVtX2Fzc2V0X2ZlZWRfcHVibGlzaGVyczogdWludDgsXG4gICAgbWF4aW11bV93aXRuZXNzX2NvdW50OiB1aW50MTYsXG4gICAgbWF4aW11bV9jb21taXR0ZWVfY291bnQ6IHVpbnQxNixcbiAgICBtYXhpbXVtX2F1dGhvcml0eV9tZW1iZXJzaGlwOiB1aW50MTYsXG4gICAgcmVzZXJ2ZV9wZXJjZW50X29mX2ZlZTogdWludDE2LFxuICAgIG5ldHdvcmtfcGVyY2VudF9vZl9mZWU6IHVpbnQxNixcbiAgICBsaWZldGltZV9yZWZlcnJlcl9wZXJjZW50X29mX2ZlZTogdWludDE2LFxuICAgIGNhc2hiYWNrX3Zlc3RpbmdfcGVyaW9kX3NlY29uZHM6IHVpbnQzMixcbiAgICBjYXNoYmFja192ZXN0aW5nX3RocmVzaG9sZDogaW50NjQsXG4gICAgY291bnRfbm9uX21lbWJlcl92b3RlczogYm9vbCxcbiAgICBhbGxvd19ub25fbWVtYmVyX3doaXRlbGlzdHM6IGJvb2wsXG4gICAgd2l0bmVzc19wYXlfcGVyX2Jsb2NrOiBpbnQ2NCxcbiAgICB3b3JrZXJfYnVkZ2V0X3Blcl9kYXk6IGludDY0LFxuICAgIG1heF9wcmVkaWNhdGVfb3Bjb2RlOiB1aW50MTYsXG4gICAgZmVlX2xpcXVpZGF0aW9uX3RocmVzaG9sZDogaW50NjQsXG4gICAgYWNjb3VudHNfcGVyX2ZlZV9zY2FsZTogdWludDE2LFxuICAgIGFjY291bnRfZmVlX3NjYWxlX2JpdHNoaWZ0czogdWludDgsXG4gICAgbWF4X2F1dGhvcml0eV9kZXB0aDogdWludDgsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycyA9IGV4cG9ydHMuY29tbWl0dGVlX21lbWJlcl91cGRhdGVfZ2xvYmFsX3BhcmFtZXRlcnMgPSBuZXcgU2VyaWFsaXplcihcImNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlX2dsb2JhbF9wYXJhbWV0ZXJzXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIG5ld19wYXJhbWV0ZXJzOiBjaGFpbl9wYXJhbWV0ZXJzXG59KTtcblxudmFyIGxpbmVhcl92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciA9IGV4cG9ydHMubGluZWFyX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoXCJsaW5lYXJfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXJcIiwge1xuICAgIGJlZ2luX3RpbWVzdGFtcDogdGltZV9wb2ludF9zZWMsXG4gICAgdmVzdGluZ19jbGlmZl9zZWNvbmRzOiB1aW50MzIsXG4gICAgdmVzdGluZ19kdXJhdGlvbl9zZWNvbmRzOiB1aW50MzJcbn0pO1xuXG52YXIgY2RkX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gZXhwb3J0cy5jZGRfdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplcihcImNkZF92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplclwiLCB7XG4gICAgc3RhcnRfY2xhaW06IHRpbWVfcG9pbnRfc2VjLFxuICAgIHZlc3Rpbmdfc2Vjb25kczogdWludDMyXG59KTtcblxudmFyIHZlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyID0gc3RhdGljX3ZhcmlhbnQoW2xpbmVhcl92ZXN0aW5nX3BvbGljeV9pbml0aWFsaXplciwgY2RkX3Zlc3RpbmdfcG9saWN5X2luaXRpYWxpemVyXSk7XG5cbnZhciB2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2VfY3JlYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJ2ZXN0aW5nX2JhbGFuY2VfY3JlYXRlXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGNyZWF0b3I6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIG93bmVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnQ6IGFzc2V0LFxuICAgIHBvbGljeTogdmVzdGluZ19wb2xpY3lfaW5pdGlhbGl6ZXJcbn0pO1xuXG52YXIgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3ID0gZXhwb3J0cy52ZXN0aW5nX2JhbGFuY2Vfd2l0aGRyYXcgPSBuZXcgU2VyaWFsaXplcihcInZlc3RpbmdfYmFsYW5jZV93aXRoZHJhd1wiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICB2ZXN0aW5nX2JhbGFuY2U6IHByb3RvY29sX2lkX3R5cGUoXCJ2ZXN0aW5nX2JhbGFuY2VcIiksXG4gICAgb3duZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGFtb3VudDogYXNzZXRcbn0pO1xuXG52YXIgcmVmdW5kX3dvcmtlcl9pbml0aWFsaXplciA9IGV4cG9ydHMucmVmdW5kX3dvcmtlcl9pbml0aWFsaXplciA9IG5ldyBTZXJpYWxpemVyKFwicmVmdW5kX3dvcmtlcl9pbml0aWFsaXplclwiKTtcblxudmFyIHZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXIgPSBleHBvcnRzLnZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXIgPSBuZXcgU2VyaWFsaXplcihcInZlc3RpbmdfYmFsYW5jZV93b3JrZXJfaW5pdGlhbGl6ZXJcIiwgeyBwYXlfdmVzdGluZ19wZXJpb2RfZGF5czogdWludDE2IH0pO1xuXG52YXIgYnVybl93b3JrZXJfaW5pdGlhbGl6ZXIgPSBleHBvcnRzLmJ1cm5fd29ya2VyX2luaXRpYWxpemVyID0gbmV3IFNlcmlhbGl6ZXIoXCJidXJuX3dvcmtlcl9pbml0aWFsaXplclwiKTtcblxudmFyIHdvcmtlcl9pbml0aWFsaXplciA9IHN0YXRpY192YXJpYW50KFtyZWZ1bmRfd29ya2VyX2luaXRpYWxpemVyLCB2ZXN0aW5nX2JhbGFuY2Vfd29ya2VyX2luaXRpYWxpemVyLCBidXJuX3dvcmtlcl9pbml0aWFsaXplcl0pO1xuXG52YXIgd29ya2VyX2NyZWF0ZSA9IGV4cG9ydHMud29ya2VyX2NyZWF0ZSA9IG5ldyBTZXJpYWxpemVyKFwid29ya2VyX2NyZWF0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBvd25lcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgd29ya19iZWdpbl9kYXRlOiB0aW1lX3BvaW50X3NlYyxcbiAgICB3b3JrX2VuZF9kYXRlOiB0aW1lX3BvaW50X3NlYyxcbiAgICBkYWlseV9wYXk6IGludDY0LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB1cmw6IHN0cmluZyxcbiAgICBpbml0aWFsaXplcjogd29ya2VyX2luaXRpYWxpemVyXG59KTtcblxudmFyIGN1c3RvbSA9IGV4cG9ydHMuY3VzdG9tID0gbmV3IFNlcmlhbGl6ZXIoXCJjdXN0b21cIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgcGF5ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHJlcXVpcmVkX2F1dGhzOiBzZXQocHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIikpLFxuICAgIGlkOiB1aW50MTYsXG4gICAgZGF0YTogYnl0ZXMoKVxufSk7XG5cbnZhciBhY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZSA9IGV4cG9ydHMuYWNjb3VudF9uYW1lX2VxX2xpdF9wcmVkaWNhdGUgPSBuZXcgU2VyaWFsaXplcihcImFjY291bnRfbmFtZV9lcV9saXRfcHJlZGljYXRlXCIsIHtcbiAgICBhY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBuYW1lOiBzdHJpbmdcbn0pO1xuXG52YXIgYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUgPSBleHBvcnRzLmFzc2V0X3N5bWJvbF9lcV9saXRfcHJlZGljYXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF9zeW1ib2xfZXFfbGl0X3ByZWRpY2F0ZVwiLCB7XG4gICAgYXNzZXRfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJhc3NldFwiKSxcbiAgICBzeW1ib2w6IHN0cmluZ1xufSk7XG5cbnZhciBibG9ja19pZF9wcmVkaWNhdGUgPSBleHBvcnRzLmJsb2NrX2lkX3ByZWRpY2F0ZSA9IG5ldyBTZXJpYWxpemVyKFwiYmxvY2tfaWRfcHJlZGljYXRlXCIsIHtcbiAgICBpZDogYnl0ZXMoMjApXG59KTtcblxudmFyIHByZWRpY2F0ZSA9IHN0YXRpY192YXJpYW50KFthY2NvdW50X25hbWVfZXFfbGl0X3ByZWRpY2F0ZSwgYXNzZXRfc3ltYm9sX2VxX2xpdF9wcmVkaWNhdGUsIGJsb2NrX2lkX3ByZWRpY2F0ZV0pO1xuXG52YXIgYXNzZXJ0ID0gZXhwb3J0cy5hc3NlcnQgPSBuZXcgU2VyaWFsaXplcihcImFzc2VydFwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBmZWVfcGF5aW5nX2FjY291bnQ6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHByZWRpY2F0ZXM6IGFycmF5KHByZWRpY2F0ZSksXG4gICAgcmVxdWlyZWRfYXV0aHM6IHNldChwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBiYWxhbmNlX2NsYWltID0gZXhwb3J0cy5iYWxhbmNlX2NsYWltID0gbmV3IFNlcmlhbGl6ZXIoXCJiYWxhbmNlX2NsYWltXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGRlcG9zaXRfdG9fYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYmFsYW5jZV90b19jbGFpbTogcHJvdG9jb2xfaWRfdHlwZShcImJhbGFuY2VcIiksXG4gICAgYmFsYW5jZV9vd25lcl9rZXk6IHB1YmxpY19rZXksXG4gICAgdG90YWxfY2xhaW1lZDogYXNzZXRcbn0pO1xuXG52YXIgb3ZlcnJpZGVfdHJhbnNmZXIgPSBleHBvcnRzLm92ZXJyaWRlX3RyYW5zZmVyID0gbmV3IFNlcmlhbGl6ZXIoXCJvdmVycmlkZV90cmFuc2ZlclwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBpc3N1ZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGZyb206IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIHRvOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnQ6IGFzc2V0LFxuICAgIG1lbW86IG9wdGlvbmFsKG1lbW9fZGF0YSksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBzdGVhbHRoX2NvbmZpcm1hdGlvbiA9IGV4cG9ydHMuc3RlYWx0aF9jb25maXJtYXRpb24gPSBuZXcgU2VyaWFsaXplcihcInN0ZWFsdGhfY29uZmlybWF0aW9uXCIsIHtcbiAgICBvbmVfdGltZV9rZXk6IHB1YmxpY19rZXksXG4gICAgdG86IG9wdGlvbmFsKHB1YmxpY19rZXkpLFxuICAgIGVuY3J5cHRlZF9tZW1vOiBieXRlcygpXG59KTtcblxudmFyIGJsaW5kX291dHB1dCA9IGV4cG9ydHMuYmxpbmRfb3V0cHV0ID0gbmV3IFNlcmlhbGl6ZXIoXCJibGluZF9vdXRwdXRcIiwge1xuICAgIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgICByYW5nZV9wcm9vZjogYnl0ZXMoKSxcbiAgICBvd25lcjogYXV0aG9yaXR5LFxuICAgIHN0ZWFsdGhfbWVtbzogb3B0aW9uYWwoc3RlYWx0aF9jb25maXJtYXRpb24pXG59KTtcblxudmFyIHRyYW5zZmVyX3RvX2JsaW5kID0gZXhwb3J0cy50cmFuc2Zlcl90b19ibGluZCA9IG5ldyBTZXJpYWxpemVyKFwidHJhbnNmZXJfdG9fYmxpbmRcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgYW1vdW50OiBhc3NldCxcbiAgICBmcm9tOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBibGluZGluZ19mYWN0b3I6IGJ5dGVzKDMyKSxcbiAgICBvdXRwdXRzOiBhcnJheShibGluZF9vdXRwdXQpXG59KTtcblxudmFyIGJsaW5kX2lucHV0ID0gZXhwb3J0cy5ibGluZF9pbnB1dCA9IG5ldyBTZXJpYWxpemVyKFwiYmxpbmRfaW5wdXRcIiwge1xuICAgIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgICBvd25lcjogYXV0aG9yaXR5XG59KTtcblxudmFyIGJsaW5kX3RyYW5zZmVyID0gZXhwb3J0cy5ibGluZF90cmFuc2ZlciA9IG5ldyBTZXJpYWxpemVyKFwiYmxpbmRfdHJhbnNmZXJcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgaW5wdXRzOiBhcnJheShibGluZF9pbnB1dCksXG4gICAgb3V0cHV0czogYXJyYXkoYmxpbmRfb3V0cHV0KVxufSk7XG5cbnZhciB0cmFuc2Zlcl9mcm9tX2JsaW5kID0gZXhwb3J0cy50cmFuc2Zlcl9mcm9tX2JsaW5kID0gbmV3IFNlcmlhbGl6ZXIoXCJ0cmFuc2Zlcl9mcm9tX2JsaW5kXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGFtb3VudDogYXNzZXQsXG4gICAgdG86IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGJsaW5kaW5nX2ZhY3RvcjogYnl0ZXMoMzIpLFxuICAgIGlucHV0czogYXJyYXkoYmxpbmRfaW5wdXQpXG59KTtcblxudmFyIGFzc2V0X3NldHRsZV9jYW5jZWwgPSBleHBvcnRzLmFzc2V0X3NldHRsZV9jYW5jZWwgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X3NldHRsZV9jYW5jZWxcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgc2V0dGxlbWVudDogcHJvdG9jb2xfaWRfdHlwZShcImZvcmNlX3NldHRsZW1lbnRcIiksXG4gICAgYWNjb3VudDogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYW1vdW50OiBhc3NldCxcbiAgICBleHRlbnNpb25zOiBzZXQoZnV0dXJlX2V4dGVuc2lvbnMpXG59KTtcblxudmFyIGFzc2V0X2NsYWltX2ZlZXMgPSBleHBvcnRzLmFzc2V0X2NsYWltX2ZlZXMgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2NsYWltX2ZlZXNcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhbW91bnRfdG9fY2xhaW06IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgZmJhX2Rpc3RyaWJ1dGUgPSBleHBvcnRzLmZiYV9kaXN0cmlidXRlID0gbmV3IFNlcmlhbGl6ZXIoXCJmYmFfZGlzdHJpYnV0ZVwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBhY2NvdW50X2lkOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBmYmFfaWQ6IHByb3RvY29sX2lkX3R5cGUoXCJmYmFfYWNjdW11bGF0b3JcIiksXG4gICAgYW1vdW50OiBpbnQ2NFxufSk7XG5cbnZhciBiaWRfY29sbGF0ZXJhbCA9IGV4cG9ydHMuYmlkX2NvbGxhdGVyYWwgPSBuZXcgU2VyaWFsaXplcihcImJpZF9jb2xsYXRlcmFsXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGJpZGRlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYWRkaXRpb25hbF9jb2xsYXRlcmFsOiBhc3NldCxcbiAgICBkZWJ0X2NvdmVyZWQ6IGFzc2V0LFxuICAgIGV4dGVuc2lvbnM6IHNldChmdXR1cmVfZXh0ZW5zaW9ucylcbn0pO1xuXG52YXIgZXhlY3V0ZV9iaWQgPSBleHBvcnRzLmV4ZWN1dGVfYmlkID0gbmV3IFNlcmlhbGl6ZXIoXCJleGVjdXRlX2JpZFwiLCB7XG4gICAgZmVlOiBhc3NldCxcbiAgICBiaWRkZXI6IHByb3RvY29sX2lkX3R5cGUoXCJhY2NvdW50XCIpLFxuICAgIGRlYnQ6IGFzc2V0LFxuICAgIGNvbGxhdGVyYWw6IGFzc2V0XG59KTtcblxudmFyIGFzc2V0X2NsYWltX3Bvb2wgPSBleHBvcnRzLmFzc2V0X2NsYWltX3Bvb2wgPSBuZXcgU2VyaWFsaXplcihcImFzc2V0X2NsYWltX3Bvb2xcIiwge1xuICAgIGZlZTogYXNzZXQsXG4gICAgaXNzdWVyOiBwcm90b2NvbF9pZF90eXBlKFwiYWNjb3VudFwiKSxcbiAgICBhc3NldF9pZDogcHJvdG9jb2xfaWRfdHlwZShcImFzc2V0XCIpLFxuICAgIGFtb3VudF90b19jbGFpbTogYXNzZXQsXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBhc3NldF91cGRhdGVfaXNzdWVyID0gZXhwb3J0cy5hc3NldF91cGRhdGVfaXNzdWVyID0gbmV3IFNlcmlhbGl6ZXIoXCJhc3NldF91cGRhdGVfaXNzdWVyXCIsIHtcbiAgICBmZWU6IGFzc2V0LFxuICAgIGlzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgYXNzZXRfdG9fdXBkYXRlOiBwcm90b2NvbF9pZF90eXBlKFwiYXNzZXRcIiksXG4gICAgbmV3X2lzc3VlcjogcHJvdG9jb2xfaWRfdHlwZShcImFjY291bnRcIiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbm9wZXJhdGlvbi5zdF9vcGVyYXRpb25zID0gW3RyYW5zZmVyLCBsaW1pdF9vcmRlcl9jcmVhdGUsIGxpbWl0X29yZGVyX2NhbmNlbCwgY2FsbF9vcmRlcl91cGRhdGUsIGZpbGxfb3JkZXIsIGFjY291bnRfY3JlYXRlLCBhY2NvdW50X3VwZGF0ZSwgYWNjb3VudF93aGl0ZWxpc3QsIGFjY291bnRfdXBncmFkZSwgYWNjb3VudF90cmFuc2ZlciwgYXNzZXRfY3JlYXRlLCBhc3NldF91cGRhdGUsIGFzc2V0X3VwZGF0ZV9iaXRhc3NldCwgYXNzZXRfdXBkYXRlX2ZlZWRfcHJvZHVjZXJzLCBhc3NldF9pc3N1ZSwgYXNzZXRfcmVzZXJ2ZSwgYXNzZXRfZnVuZF9mZWVfcG9vbCwgYXNzZXRfc2V0dGxlLCBhc3NldF9nbG9iYWxfc2V0dGxlLCBhc3NldF9wdWJsaXNoX2ZlZWQsIHdpdG5lc3NfY3JlYXRlLCB3aXRuZXNzX3VwZGF0ZSwgcHJvcG9zYWxfY3JlYXRlLCBwcm9wb3NhbF91cGRhdGUsIHByb3Bvc2FsX2RlbGV0ZSwgd2l0aGRyYXdfcGVybWlzc2lvbl9jcmVhdGUsIHdpdGhkcmF3X3Blcm1pc3Npb25fdXBkYXRlLCB3aXRoZHJhd19wZXJtaXNzaW9uX2NsYWltLCB3aXRoZHJhd19wZXJtaXNzaW9uX2RlbGV0ZSwgY29tbWl0dGVlX21lbWJlcl9jcmVhdGUsIGNvbW1pdHRlZV9tZW1iZXJfdXBkYXRlLCBjb21taXR0ZWVfbWVtYmVyX3VwZGF0ZV9nbG9iYWxfcGFyYW1ldGVycywgdmVzdGluZ19iYWxhbmNlX2NyZWF0ZSwgdmVzdGluZ19iYWxhbmNlX3dpdGhkcmF3LCB3b3JrZXJfY3JlYXRlLCBjdXN0b20sIGFzc2VydCwgYmFsYW5jZV9jbGFpbSwgb3ZlcnJpZGVfdHJhbnNmZXIsIHRyYW5zZmVyX3RvX2JsaW5kLCBibGluZF90cmFuc2ZlciwgdHJhbnNmZXJfZnJvbV9ibGluZCwgYXNzZXRfc2V0dGxlX2NhbmNlbCwgYXNzZXRfY2xhaW1fZmVlcywgZmJhX2Rpc3RyaWJ1dGUsIGJpZF9jb2xsYXRlcmFsLCBleGVjdXRlX2JpZCwgYXNzZXRfY2xhaW1fcG9vbCwgYXNzZXRfdXBkYXRlX2lzc3Vlcl07XG5cbnZhciB0cmFuc2FjdGlvbiA9IGV4cG9ydHMudHJhbnNhY3Rpb24gPSBuZXcgU2VyaWFsaXplcihcInRyYW5zYWN0aW9uXCIsIHtcbiAgICByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gICAgcmVmX2Jsb2NrX3ByZWZpeDogdWludDMyLFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKVxufSk7XG5cbnZhciBzaWduZWRfdHJhbnNhY3Rpb24gPSBleHBvcnRzLnNpZ25lZF90cmFuc2FjdGlvbiA9IG5ldyBTZXJpYWxpemVyKFwic2lnbmVkX3RyYW5zYWN0aW9uXCIsIHtcbiAgICByZWZfYmxvY2tfbnVtOiB1aW50MTYsXG4gICAgcmVmX2Jsb2NrX3ByZWZpeDogdWludDMyLFxuICAgIGV4cGlyYXRpb246IHRpbWVfcG9pbnRfc2VjLFxuICAgIG9wZXJhdGlvbnM6IGFycmF5KG9wZXJhdGlvbiksXG4gICAgZXh0ZW5zaW9uczogc2V0KGZ1dHVyZV9leHRlbnNpb25zKSxcbiAgICBzaWduYXR1cmVzOiBhcnJheShieXRlcyg2NSkpXG59KTtcbi8vIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyMgIEdlbmVyYXRlZCBjb2RlIGVuZFxuLy8jIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQ3VzdG9tIFR5cGVzXG5cbnZhciBzdGVhbHRoX21lbW9fZGF0YSA9IGV4cG9ydHMuc3RlYWx0aF9tZW1vX2RhdGEgPSBuZXcgU2VyaWFsaXplcihcInN0ZWFsdGhfbWVtb19kYXRhXCIsIHtcbiAgICBmcm9tOiBvcHRpb25hbChwdWJsaWNfa2V5KSxcbiAgICBhbW91bnQ6IGFzc2V0LFxuICAgIGJsaW5kaW5nX2ZhY3RvcjogYnl0ZXMoMzIpLFxuICAgIGNvbW1pdG1lbnQ6IGJ5dGVzKDMzKSxcbiAgICBjaGVjazogdWludDMyXG59KTtcbi8vIHZhciBzdGVhbHRoX2NvbmZpcm1hdGlvbiA9IG5ldyBTZXJpYWxpemVyKFxuLy8gICAgIFwic3RlYWx0aF9jb25maXJtYXRpb25cIiwge1xuLy8gICAgIG9uZV90aW1lX2tleTogcHVibGljX2tleSxcbi8vICAgICB0bzogb3B0aW9uYWwoIHB1YmxpY19rZXkgKSxcbi8vICAgICBlbmNyeXB0ZWRfbWVtbzogc3RlYWx0aF9tZW1vX2RhdGFcbi8vIH0pIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfYnl0ZWJ1ZmZlciA9IHJlcXVpcmUoXCJieXRlYnVmZmVyXCIpO1xuXG52YXIgX2J5dGVidWZmZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYnl0ZWJ1ZmZlcik7XG5cbnZhciBfZXJyb3Jfd2l0aF9jYXVzZSA9IHJlcXVpcmUoXCIuL2Vycm9yX3dpdGhfY2F1c2VcIik7XG5cbnZhciBfZXJyb3Jfd2l0aF9jYXVzZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lcnJvcl93aXRoX2NhdXNlKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoXCJzYWZlLWJ1ZmZlclwiKS5CdWZmZXI7XG5cbnZhciBIRVhfRFVNUCA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX3NlcmlhbGl6ZXJfaGV4X2R1bXA7XG5cbnZhciBTZXJpYWxpemVyID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFNlcmlhbGl6ZXIob3BlcmF0aW9uX25hbWUsIHR5cGVzKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTZXJpYWxpemVyKTtcblxuICAgICAgICB0aGlzLm9wZXJhdGlvbl9uYW1lID0gb3BlcmF0aW9uX25hbWU7XG4gICAgICAgIHRoaXMudHlwZXMgPSB0eXBlcztcbiAgICAgICAgaWYgKHRoaXMudHlwZXMpIHRoaXMua2V5cyA9IE9iamVjdC5rZXlzKHRoaXMudHlwZXMpO1xuXG4gICAgICAgIFNlcmlhbGl6ZXIucHJpbnREZWJ1ZyA9IHRydWU7XG4gICAgfVxuXG4gICAgU2VyaWFsaXplci5wcm90b3R5cGUuZnJvbUJ5dGVCdWZmZXIgPSBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgdmFyIGZpZWxkID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMua2V5cztcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBmaWVsZDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZmllbGQgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IHRoaXMudHlwZXNbZmllbGRdO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChIRVhfRFVNUCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUub3BlcmF0aW9uX25hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHR5cGUub3BlcmF0aW9uX25hbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbzEgPSBiLm9mZnNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvMiA9IGIub2Zmc2V0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIub2Zmc2V0ID0gbzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9iLnJlc2V0KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgX2IgPSBiLmNvcHkobzEsIG8yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKHRoaXMub3BlcmF0aW9uX25hbWUgKyBcIi5cIiArIGZpZWxkICsgXCJcXHRcIiwgX2IudG9IZXgoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0W2ZpZWxkXSA9IHR5cGUuZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoU2VyaWFsaXplci5wcmludERlYnVnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgcmVhZGluZyBcIiArIHRoaXMub3BlcmF0aW9uX25hbWUgKyBcIi5cIiArIGZpZWxkICsgXCIgaW4gZGF0YTpcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBiLnByaW50RGVidWcoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIF9lcnJvcl93aXRoX2NhdXNlMi5kZWZhdWx0LnRocm93KHRoaXMub3BlcmF0aW9uX25hbWUgKyBcIi5cIiArIGZpZWxkLCBlcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH07XG5cbiAgICBTZXJpYWxpemVyLnByb3RvdHlwZS5hcHBlbmRCeXRlQnVmZmVyID0gZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgdmFyIGZpZWxkID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMua2V5cztcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBmaWVsZDsgaSA8IGl0ZXJhYmxlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZmllbGQgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IHRoaXMudHlwZXNbZmllbGRdO1xuICAgICAgICAgICAgICAgIHR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3RbZmllbGRdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgX2Vycm9yX3dpdGhfY2F1c2UyLmRlZmF1bHQudGhyb3codGhpcy5vcGVyYXRpb25fbmFtZSArIFwiLlwiICsgZmllbGQgKyBcIiA9IFwiICsgSlNPTi5zdHJpbmdpZnkob2JqZWN0W2ZpZWxkXSksIGVycm9yKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBjaXJjdWxhciByZWZcbiAgICAgICAgICAgICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgXCIuXCIgKyBmaWVsZCArIFwiID0gXCIgKyBvYmplY3RbZmllbGRdLCBlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH07XG5cbiAgICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChzZXJpYWxpemVkX29iamVjdCkge1xuICAgICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICAgIHZhciBmaWVsZCA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgaXRlcmFibGUgPSB0aGlzLmtleXM7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgZmllbGQ7IGkgPCBpdGVyYWJsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGZpZWxkID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgICAgdmFyIHR5cGUgPSB0aGlzLnR5cGVzW2ZpZWxkXTtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBzZXJpYWxpemVkX29iamVjdFtmaWVsZF07XG4gICAgICAgICAgICAgICAgLy9ERUJVRyB2YWx1ZSA9IHZhbHVlLnJlc29sdmUgaWYgdmFsdWUucmVzb2x2ZVxuICAgICAgICAgICAgICAgIC8vREVCVUcgY29uc29sZS5sb2coJy4uLiB2YWx1ZScsZmllbGQsdmFsdWUpXG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHR5cGUuZnJvbU9iamVjdCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2ZpZWxkXSA9IG9iamVjdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIF9lcnJvcl93aXRoX2NhdXNlMi5kZWZhdWx0LnRocm93KHRoaXMub3BlcmF0aW9uX25hbWUgKyBcIi5cIiArIGZpZWxkLCBlcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgICAgQGFyZyB7Ym9vbGVhbn0gW2RlYnVnLnVzZV9kZWZhdWx0ID0gZmFsc2VdIC0gbW9yZSB0ZW1wbGF0ZSBmcmllbmRseVxuICAgICAgICBAYXJnIHtib29sZWFufSBbZGVidWcuYW5ub3RhdGUgPSBmYWxzZV0gLSBhZGQgdXNlci1mcmllbmRseSBpbmZvcm1hdGlvblxuICAgICovXG5cblxuICAgIFNlcmlhbGl6ZXIucHJvdG90eXBlLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QoKSB7XG4gICAgICAgIHZhciBzZXJpYWxpemVkX29iamVjdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge307XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogeyB1c2VfZGVmYXVsdDogZmFsc2UsIGFubm90YXRlOiBmYWxzZSB9O1xuXG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgICAgdmFyIGZpZWxkID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICghdGhpcy50eXBlcykgcmV0dXJuIHJlc3VsdDtcblxuICAgICAgICAgICAgdmFyIGl0ZXJhYmxlID0gdGhpcy5rZXlzO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGZpZWxkOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBmaWVsZCA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICAgICAgICAgIHZhciB0eXBlID0gdGhpcy50eXBlc1tmaWVsZF07XG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHR5cGUudG9PYmplY3QodHlwZW9mIHNlcmlhbGl6ZWRfb2JqZWN0ICE9PSBcInVuZGVmaW5lZFwiICYmIHNlcmlhbGl6ZWRfb2JqZWN0ICE9PSBudWxsID8gc2VyaWFsaXplZF9vYmplY3RbZmllbGRdIDogdW5kZWZpbmVkLCBkZWJ1Zyk7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2ZpZWxkXSA9IG9iamVjdDtcbiAgICAgICAgICAgICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGIgPSBuZXcgX2J5dGVidWZmZXIyLmRlZmF1bHQoX2J5dGVidWZmZXIyLmRlZmF1bHQuREVGQVVMVF9DQVBBQ0lUWSwgX2J5dGVidWZmZXIyLmRlZmF1bHQuTElUVExFX0VORElBTik7XG4gICAgICAgICAgICAgICAgICAgIHR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcihiLCB0eXBlb2Ygc2VyaWFsaXplZF9vYmplY3QgIT09IFwidW5kZWZpbmVkXCIgJiYgc2VyaWFsaXplZF9vYmplY3QgIT09IG51bGwgPyBzZXJpYWxpemVkX29iamVjdFtmaWVsZF0gOiB1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgICBiID0gYi5jb3B5KDAsIGIub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcih0aGlzLm9wZXJhdGlvbl9uYW1lICsgXCIuXCIgKyBmaWVsZCwgYi50b0hleCgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBfZXJyb3Jfd2l0aF9jYXVzZTIuZGVmYXVsdC50aHJvdyh0aGlzLm9wZXJhdGlvbl9uYW1lICsgXCIuXCIgKyBmaWVsZCwgZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgLyoqIFNvcnQgYnkgdGhlIGZpcnN0IGVsZW1lbnQgaW4gYSBvcGVyYXRpb24gKi9cblxuXG4gICAgU2VyaWFsaXplci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICAgICAgICB2YXIgZmlyc3Rfa2V5ID0gdGhpcy5rZXlzWzBdO1xuICAgICAgICB2YXIgZmlyc3RfdHlwZSA9IHRoaXMudHlwZXNbZmlyc3Rfa2V5XTtcblxuICAgICAgICB2YXIgdmFsQSA9IGFbZmlyc3Rfa2V5XTtcbiAgICAgICAgdmFyIHZhbEIgPSBiW2ZpcnN0X2tleV07XG5cbiAgICAgICAgaWYgKGZpcnN0X3R5cGUuY29tcGFyZSkgcmV0dXJuIGZpcnN0X3R5cGUuY29tcGFyZSh2YWxBLCB2YWxCKTtcblxuICAgICAgICBpZiAodHlwZW9mIHZhbEEgPT09IFwibnVtYmVyXCIgJiYgdHlwZW9mIHZhbEIgPT09IFwibnVtYmVyXCIpIHJldHVybiB2YWxBIC0gdmFsQjtcblxuICAgICAgICB2YXIgZW5jb2RpbmcgPSB2b2lkIDA7XG4gICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsQSkgJiYgQnVmZmVyLmlzQnVmZmVyKHZhbEIpKSB7XG4gICAgICAgICAgICAvLyBBIGJpbmFyeSBzdHJpbmcgY29tcGFyZSBkb2VzIG5vdCB3b3JrLiAgSWYgbG9jYWxlQ29tcGFyZSBpcyB3ZWxsIHN1cHBvcnRlZCB0aGF0IGNvdWxkIHJlcGxhY2UgSEVYLiAgUGVyZm9ybWFuYW5jZSBpcyB2ZXJ5IGdvb2Qgc28gY29tcGFyaW5nIEhFWCB3b3Jrcy5cbiAgICAgICAgICAgIGVuY29kaW5nID0gXCJoZXhcIjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzdHJBID0gdmFsQS50b1N0cmluZyhlbmNvZGluZyk7XG4gICAgICAgIHZhciBzdHJCID0gdmFsQi50b1N0cmluZyhlbmNvZGluZyk7XG4gICAgICAgIHJldHVybiBzdHJBID4gc3RyQiA/IDEgOiBzdHJBIDwgc3RyQiA/IC0xIDogMDtcbiAgICB9O1xuXG4gICAgLy8gPGhlbHBlcl9mdW5jdGlvbnM+XG5cbiAgICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tSGV4ID0gZnVuY3Rpb24gZnJvbUhleChoZXgpIHtcbiAgICAgICAgdmFyIGIgPSBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5mcm9tSGV4KGhleCwgX2J5dGVidWZmZXIyLmRlZmF1bHQuTElUVExFX0VORElBTik7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgIH07XG5cbiAgICBTZXJpYWxpemVyLnByb3RvdHlwZS5mcm9tQnVmZmVyID0gZnVuY3Rpb24gZnJvbUJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdmFyIGIgPSBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5mcm9tQmluYXJ5KGJ1ZmZlci50b1N0cmluZyhcImJpbmFyeVwiKSwgX2J5dGVidWZmZXIyLmRlZmF1bHQuTElUVExFX0VORElBTik7XG4gICAgICAgIHJldHVybiB0aGlzLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgIH07XG5cbiAgICBTZXJpYWxpemVyLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uIHRvSGV4KG9iamVjdCkge1xuICAgICAgICAvLyByZXR1cm4gdGhpcy50b0J1ZmZlcihvYmplY3QpLnRvU3RyaW5nKFwiaGV4XCIpXG4gICAgICAgIHZhciBiID0gdGhpcy50b0J5dGVCdWZmZXIob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIGIudG9IZXgoKTtcbiAgICB9O1xuXG4gICAgU2VyaWFsaXplci5wcm90b3R5cGUudG9CeXRlQnVmZmVyID0gZnVuY3Rpb24gdG9CeXRlQnVmZmVyKG9iamVjdCkge1xuICAgICAgICB2YXIgYiA9IG5ldyBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdChfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5ERUZBVUxUX0NBUEFDSVRZLCBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5MSVRUTEVfRU5ESUFOKTtcbiAgICAgICAgdGhpcy5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCk7XG4gICAgICAgIHJldHVybiBiLmNvcHkoMCwgYi5vZmZzZXQpO1xuICAgIH07XG5cbiAgICBTZXJpYWxpemVyLnByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uIHRvQnVmZmVyKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gQnVmZmVyLmZyb20odGhpcy50b0J5dGVCdWZmZXIob2JqZWN0KS50b0JpbmFyeSgpLCBcImJpbmFyeVwiKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFNlcmlhbGl6ZXI7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IFNlcmlhbGl6ZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5kZWZhdWx0ID0gdGVtcGxhdGU7XG4vKiogQ29uc29sZSBwcmludCBhbnkgdHJhbnNhY3Rpb24gb2JqZWN0IHdpdGggemVybyBkZWZhdWx0IHZhbHVlcy4gKi9cbmZ1bmN0aW9uIHRlbXBsYXRlKG9wKSB7XG4gICAgdmFyIG9iamVjdCA9IG9wLnRvT2JqZWN0KHZvaWQgMCwgeyB1c2VfZGVmYXVsdDogdHJ1ZSwgYW5ub3RhdGU6IHRydWUgfSk7XG5cbiAgICAvLyB2aXN1YWwgKHdpdGggZGVzY3JpcHRpb25zKVxuICAgIGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkob2JqZWN0LCBudWxsLCA0KSk7XG5cbiAgICAvLyB1c2FibGUgaW4gYSBjb3B5LXBhc3RlXG5cbiAgICBvYmplY3QgPSBvcC50b09iamVjdCh2b2lkIDAsIHsgdXNlX2RlZmF1bHQ6IHRydWUsIGFubm90YXRlOiBmYWxzZSB9KTtcblxuICAgIC8vIGNvcHktcGFzdGUgb25lLWxpbmVlclxuICAgIGNvbnNvbGUuZXJyb3IoSlNPTi5zdHJpbmdpZnkob2JqZWN0KSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07IC8vIExvdy1sZXZlbCB0eXBlcyB0aGF0IG1ha2UgdXAgb3BlcmF0aW9uc1xuXG52YXIgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uID0gcmVxdWlyZShcIi4vU2VyaWFsaXplclZhbGlkYXRpb25cIik7XG5cbnZhciBfU2VyaWFsaXplclZhbGlkYXRpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VyaWFsaXplclZhbGlkYXRpb24pO1xuXG52YXIgX0Zhc3RQYXJzZXIgPSByZXF1aXJlKFwiLi9GYXN0UGFyc2VyXCIpO1xuXG52YXIgX0Zhc3RQYXJzZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRmFzdFBhcnNlcik7XG5cbnZhciBfQ2hhaW5UeXBlcyA9IHJlcXVpcmUoXCIuLi8uLi9jaGFpbi9zcmMvQ2hhaW5UeXBlc1wiKTtcblxudmFyIF9DaGFpblR5cGVzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0NoYWluVHlwZXMpO1xuXG52YXIgX09iamVjdElkID0gcmVxdWlyZShcIi4uLy4uL2NoYWluL3NyYy9PYmplY3RJZFwiKTtcblxudmFyIF9PYmplY3RJZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9PYmplY3RJZCk7XG5cbnZhciBfZWNjID0gcmVxdWlyZShcIi4uLy4uL2VjY1wiKTtcblxudmFyIF9iaXRzaGFyZXNqc1dzID0gcmVxdWlyZShcImJpdHNoYXJlc2pzLXdzXCIpO1xuXG52YXIgX2J5dGVidWZmZXIgPSByZXF1aXJlKFwiYnl0ZWJ1ZmZlclwiKTtcblxudmFyIF9ieXRlYnVmZmVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2J5dGVidWZmZXIpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgQnVmZmVyID0gcmVxdWlyZShcInNhZmUtYnVmZmVyXCIpLkJ1ZmZlcjtcblxudmFyIFR5cGVzID0ge307XG5cbnZhciBIRVhfRFVNUCA9IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX3NlcmlhbGl6ZXJfaGV4X2R1bXA7XG5cblR5cGVzLnVpbnQ4ID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRVaW50OCgpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgb2JqZWN0LCBcInVpbnQ4IFwiICsgb2JqZWN0KTtcbiAgICAgICAgYi53cml0ZVVpbnQ4KG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmYsIG9iamVjdCwgXCJ1aW50OCBcIiArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmLCBvYmplY3QsIFwidWludDggXCIgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqZWN0KTtcbiAgICB9XG59O1xuXG5UeXBlcy51aW50MTYgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIGIucmVhZFVpbnQxNigpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmLCBvYmplY3QsIFwidWludDE2IFwiICsgb2JqZWN0KTtcbiAgICAgICAgYi53cml0ZVVpbnQxNihvYmplY3QpO1xuICAgICAgICByZXR1cm47XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmYsIG9iamVjdCwgXCJ1aW50MTYgXCIgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmLCBvYmplY3QsIFwidWludDE2IFwiICsgb2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KG9iamVjdCk7XG4gICAgfVxufTtcblxuVHlwZXMudWludDMyID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRVaW50MzIoKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZmZmZmYsIG9iamVjdCwgXCJ1aW50MzIgXCIgKyBvYmplY3QpO1xuICAgICAgICBiLndyaXRlVWludDMyKG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKDAsIDB4ZmZmZmZmZmYsIG9iamVjdCwgXCJ1aW50MzIgXCIgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmZmZmZiwgb2JqZWN0LCBcInVpbnQzMiBcIiArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiBwYXJzZUludChvYmplY3QpO1xuICAgIH1cbn07XG5cbnZhciBNSU5fU0lHTkVEXzMyID0gLTEgKiBNYXRoLnBvdygyLCAzMSk7XG52YXIgTUFYX1NJR05FRF8zMiA9IE1hdGgucG93KDIsIDMxKSAtIDE7XG5cblR5cGVzLnZhcmludDMyID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRWYXJpbnQzMigpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoTUlOX1NJR05FRF8zMiwgTUFYX1NJR05FRF8zMiwgb2JqZWN0LCBcInVpbnQzMiBcIiArIG9iamVjdCk7XG4gICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QpO1xuICAgICAgICByZXR1cm47XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZShNSU5fU0lHTkVEXzMyLCBNQVhfU0lHTkVEXzMyLCBvYmplY3QsIFwidWludDMyIFwiICsgb2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3JhbmdlKE1JTl9TSUdORURfMzIsIE1BWF9TSUdORURfMzIsIG9iamVjdCwgXCJ1aW50MzIgXCIgKyBvYmplY3QpO1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqZWN0KTtcbiAgICB9XG59O1xuXG5UeXBlcy5pbnQ2NCA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gYi5yZWFkSW50NjQoKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICBiLndyaXRlSW50NjQoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX2xvbmcob2JqZWN0KSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICByZXR1cm4gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX2xvbmcob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBcIjBcIjtcbiAgICAgICAgfVxuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19sb25nKG9iamVjdCkudG9TdHJpbmcoKTtcbiAgICB9XG59O1xuXG5UeXBlcy51aW50NjQgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIGIucmVhZFVpbnQ2NCgpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgYi53cml0ZVVpbnQ2NChfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudG9fbG9uZyhfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudW5zaWduZWQob2JqZWN0KSwgdW5kZWZpbmVkLCB0cnVlKSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudG9fbG9uZyhfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQudW5zaWduZWQob2JqZWN0KSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBcIjBcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnRvX2xvbmcob2JqZWN0LCB1bmRlZmluZWQsIHRydWUpLnRvU3RyaW5nKCk7XG4gICAgfVxufTtcblxuVHlwZXMuc3RyaW5nID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHZhciBiX2NvcHk7XG4gICAgICAgIHZhciBsZW4gPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKSwgYi5za2lwKGxlbik7XG4gICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShiX2NvcHkudG9CaW5hcnkoKSwgXCJiaW5hcnlcIik7XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgYi53cml0ZVZhcmludDMyKG9iamVjdC5sZW5ndGgpO1xuICAgICAgICBiLmFwcGVuZChvYmplY3QudG9TdHJpbmcoXCJiaW5hcnlcIiksIFwiYmluYXJ5XCIpO1xuICAgICAgICByZXR1cm47XG4gICAgfSxcbiAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKG9iamVjdCk7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG4gICAgfVxufTtcblxuVHlwZXMuYnl0ZXMgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgICAgICBpZiAoc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJfY29weTtcbiAgICAgICAgICAgICAgICB2YXIgbGVuID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICAgICAgICAgICAgICBiX2NvcHkgPSBiLmNvcHkoYi5vZmZzZXQsIGIub2Zmc2V0ICsgbGVuKSwgYi5za2lwKGxlbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJfY29weS50b0JpbmFyeSgpLCBcImJpbmFyeVwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYl9jb3B5ID0gYi5jb3B5KGIub2Zmc2V0LCBiLm9mZnNldCArIHNpemUpLCBiLnNraXAoc2l6ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJfY29weS50b0JpbmFyeSgpLCBcImJpbmFyeVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgPT09IFwic3RyaW5nXCIpIG9iamVjdCA9IEJ1ZmZlci5mcm9tKG9iamVjdCwgXCJoZXhcIik7XG5cbiAgICAgICAgICAgIGlmIChzaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBiLmFwcGVuZChvYmplY3QudG9TdHJpbmcoXCJiaW5hcnlcIiksIFwiYmluYXJ5XCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iamVjdCkpIHJldHVybiBvYmplY3Q7XG5cbiAgICAgICAgICAgIHJldHVybiBCdWZmZXIuZnJvbShvYmplY3QsIFwiaGV4XCIpO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgemVyb3MgPSBmdW5jdGlvbiB6ZXJvcyhudW0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBcnJheShudW0pLmpvaW4oXCIwMFwiKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiB6ZXJvcyhzaXplKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdC50b1N0cmluZyhcImhleFwiKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG5UeXBlcy5ib29sID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHJldHVybiBiLnJlYWRVaW50OCgpID09PSAxO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgLy8gc3VwcG9ydHMgYm9vbGVhbiBvciBpbnRlZ2VyXG4gICAgICAgIGIud3JpdGVVaW50OChKU09OLnBhcnNlKG9iamVjdCkgPyAxIDogMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKG9iamVjdCkgPyB0cnVlIDogZmFsc2U7XG4gICAgfSxcbiAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2Uob2JqZWN0KSA/IHRydWUgOiBmYWxzZTtcbiAgICB9XG59O1xuXG5UeXBlcy52b2lkID0ge1xuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIih2b2lkKSB1bmRlZmluZWQgdHlwZVwiKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIih2b2lkKSB1bmRlZmluZWQgdHlwZVwiKTtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIih2b2lkKSB1bmRlZmluZWQgdHlwZVwiKTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiKHZvaWQpIHVuZGVmaW5lZCB0eXBlXCIpO1xuICAgIH1cbn07XG5cblR5cGVzLmFycmF5ID0gZnVuY3Rpb24gKHN0X29wZXJhdGlvbikge1xuICAgIHJldHVybiB7XG4gICAgICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgICAgICB2YXIgc2l6ZSA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgICAgICBpZiAoSEVYX0RVTVApIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcInZhcmludDMyIHNpemUgPSBcIiArIHNpemUudG9TdHJpbmcoMTYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyAwIDwgc2l6ZSA/IGkgPCBzaXplIDogaSA+IHNpemU7IDAgPCBzaXplID8gaSsrIDogaSsrKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goc3Rfb3BlcmF0aW9uLmZyb21CeXRlQnVmZmVyKGIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzb3J0T3BlcmF0aW9uKHJlc3VsdCwgc3Rfb3BlcmF0aW9uKTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgb2JqZWN0ID0gc29ydE9wZXJhdGlvbihvYmplY3QsIHN0X29wZXJhdGlvbik7XG4gICAgICAgICAgICBiLndyaXRlVmFyaW50MzIob2JqZWN0Lmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG8gPSBvYmplY3RbaV07XG4gICAgICAgICAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIG9iamVjdCA9IHNvcnRPcGVyYXRpb24ob2JqZWN0LCBzdF9vcGVyYXRpb24pO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG87IGkgPCBvYmplY3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG8pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdCwgZGVidWcpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgb2JqZWN0ID0gc29ydE9wZXJhdGlvbihvYmplY3QsIHN0X29wZXJhdGlvbik7XG5cbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3QobywgZGVidWcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMudGltZV9wb2ludF9zZWMgPSB7XG4gICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgcmV0dXJuIGIucmVhZFVpbnQzMigpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgIT09IFwibnVtYmVyXCIpIG9iamVjdCA9IFR5cGVzLnRpbWVfcG9pbnRfc2VjLmZyb21PYmplY3Qob2JqZWN0KTtcblxuICAgICAgICBiLndyaXRlVWludDMyKG9iamVjdCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSBcIm51bWJlclwiKSByZXR1cm4gb2JqZWN0O1xuXG4gICAgICAgIGlmIChvYmplY3QuZ2V0VGltZSkgcmV0dXJuIE1hdGguZmxvb3Iob2JqZWN0LmdldFRpbWUoKSAvIDEwMDApO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGRhdGUgdHlwZTogXCIgKyBvYmplY3QpO1xuXG4gICAgICAgIGlmICgvVFswLTJdWzAtOV06WzAtNV1bMC05XTpbMC01XVswLTldJC8udGVzdChvYmplY3QpKSBvYmplY3QgPSBvYmplY3QgKyBcIlpcIjtcblxuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihuZXcgRGF0ZShvYmplY3QpLmdldFRpbWUoKSAvIDEwMDApO1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG5ldyBEYXRlKDApLnRvSVNPU3RyaW5nKCkuc3BsaXQoXCIuXCIpWzBdO1xuXG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gb2JqZWN0O1xuXG4gICAgICAgIGlmIChvYmplY3QuZ2V0VGltZSkgcmV0dXJuIG9iamVjdC50b0lTT1N0cmluZygpLnNwbGl0KFwiLlwiKVswXTtcblxuICAgICAgICB2YXIgaW50ID0gcGFyc2VJbnQob2JqZWN0KTtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZmZmZmZmZiwgaW50LCBcInVpbnQzMiBcIiArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShpbnQgKiAxMDAwKS50b0lTT1N0cmluZygpLnNwbGl0KFwiLlwiKVswXTtcbiAgICB9XG59O1xuXG5UeXBlcy5zZXQgPSBmdW5jdGlvbiAoc3Rfb3BlcmF0aW9uKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWRhdGU6IGZ1bmN0aW9uIHZhbGlkYXRlKGFycmF5KSB7XG4gICAgICAgICAgICB2YXIgZHVwX21hcCA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIG87IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIG8gPSBhcnJheVtpXTtcbiAgICAgICAgICAgICAgICB2YXIgcmVmO1xuICAgICAgICAgICAgICAgIGlmIChyZWYgPSB0eXBlb2YgbyA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiBfdHlwZW9mKG8pLCBbXCJzdHJpbmdcIiwgXCJudW1iZXJcIl0uaW5kZXhPZihyZWYpID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGR1cF9tYXBbb10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZHVwbGljYXRlIChzZXQpXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGR1cF9tYXBbb10gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzb3J0T3BlcmF0aW9uKGFycmF5LCBzdF9vcGVyYXRpb24pO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIHNpemUgPSBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJ2YXJpbnQzMiBzaXplID0gXCIgKyBzaXplLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyAwIDwgc2l6ZSA/IGkgPCBzaXplIDogaSA+IHNpemU7IDAgPCBzaXplID8gaSsrIDogaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICB9LFxuICAgICAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKCFvYmplY3QpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBpdGVyYWJsZSA9IHRoaXMudmFsaWRhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgaXRlcmFibGUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9KCkpO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW3N0X29wZXJhdGlvbi50b09iamVjdChvYmplY3QsIGRlYnVnKV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW9iamVjdCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbzsgaSA8IG9iamVjdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBvID0gb2JqZWN0W2ldO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChzdF9vcGVyYXRpb24udG9PYmplY3QobywgZGVidWcpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0oKSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuLy8gZ2xvYmFsX3BhcmFtZXRlcnNfdXBkYXRlX29wZXJhdGlvbiBjdXJyZW50X2ZlZXNcblR5cGVzLmZpeGVkX2FycmF5ID0gZnVuY3Rpb24gKGNvdW50LCBzdF9vcGVyYXRpb24pIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIGksIGosIHJlZiwgcmVzdWx0cztcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBjb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChzdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24ocmVzdWx0cywgc3Rfb3BlcmF0aW9uKTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBpLCBqLCByZWY7XG4gICAgICAgICAgICBpZiAoY291bnQgIT09IDApIHtcbiAgICAgICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgICAgICBvYmplY3QgPSBzb3J0T3BlcmF0aW9uKG9iamVjdCwgc3Rfb3BlcmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBjb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIHN0X29wZXJhdGlvbi5hcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgaSwgaiwgcmVmLCByZXN1bHRzO1xuICAgICAgICAgICAgaWYgKGNvdW50ICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gY291bnQ7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob2JqZWN0W2ldKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfSxcbiAgICAgICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCwgZGVidWcpIHtcbiAgICAgICAgICAgIHZhciBpLCBqLCBrLCByZWYsIHJlZjEsIHJlc3VsdHMsIHJlc3VsdHMxO1xuICAgICAgICAgICAgaWYgKGRlYnVnID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZWJ1ZyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBjb3VudDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KHZvaWQgMCwgZGVidWcpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY291bnQgIT09IDApIHtcbiAgICAgICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdHMxID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IGNvdW50OyBrIDwgcmVmMTsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHMxLnB1c2goc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdFtpXSwgZGVidWcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzMTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKiBTdXBwb3J0cyBpbnN0YW5jZSBudW1iZXJzICgxMSkgb3Igb2JqZWN0IHR5cGVzICgxLjIuMTEpLiAgT2JqZWN0IHR5cGVcblZhbGlkYXRpb24gaXMgZW5mb3JjZWQgd2hlbiBhbiBvYmplY3QgdHlwZSBpcyB1c2VkLiAqL1xudmFyIGlkX3R5cGUgPSBmdW5jdGlvbiBpZF90eXBlKHJlc2VydmVkX3NwYWNlcywgb2JqZWN0X3R5cGUpIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQocmVzZXJ2ZWRfc3BhY2VzLCBcInJlc2VydmVkX3NwYWNlc1wiKTtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0X3R5cGUsIFwib2JqZWN0X3R5cGVcIik7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZnJvbUJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGZyb21CeXRlQnVmZmVyKGIpIHtcbiAgICAgICAgICAgIHJldHVybiBiLnJlYWRWYXJpbnQzMigpO1xuICAgICAgICB9LFxuICAgICAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gY29udmVydCAxLjIubiBpbnRvIGp1c3QgblxuICAgICAgICAgICAgaWYgKC9eWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rJC8udGVzdChvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LmdldF9pbnN0YW5jZShyZXNlcnZlZF9zcGFjZXMsIG9iamVjdF90eXBlLCBvYmplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYi53cml0ZVZhcmludDMyKF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19udW1iZXIob2JqZWN0KSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gb2JqZWN0LnJlc29sdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LmlzX2RpZ2l0cyhvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC50b19udW1iZXIob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQuZ2V0X2luc3RhbmNlKHJlc2VydmVkX3NwYWNlcywgb2JqZWN0X3R5cGUsIG9iamVjdCk7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIHZhciBvYmplY3RfdHlwZV9pZCA9IF9DaGFpblR5cGVzMi5kZWZhdWx0Lm9iamVjdF90eXBlW29iamVjdF90eXBlXTtcbiAgICAgICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNlcnZlZF9zcGFjZXMgKyBcIi5cIiArIG9iamVjdF90eXBlX2lkICsgXCIuMFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnJlc29sdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC5yZXNvbHZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKC9eWzAtOV0rXFwuWzAtOV0rXFwuWzAtOV0rJC8udGVzdChvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0ID0gX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LmdldF9pbnN0YW5jZShyZXNlcnZlZF9zcGFjZXMsIG9iamVjdF90eXBlLCBvYmplY3QpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzZXJ2ZWRfc3BhY2VzICsgXCIuXCIgKyBvYmplY3RfdHlwZV9pZCArIFwiLlwiICsgb2JqZWN0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG5cblR5cGVzLnByb3RvY29sX2lkX3R5cGUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChuYW1lLCBcIm5hbWVcIik7XG4gICAgcmV0dXJuIGlkX3R5cGUoX0NoYWluVHlwZXMyLmRlZmF1bHQucmVzZXJ2ZWRfc3BhY2VzLnByb3RvY29sX2lkcywgbmFtZSk7XG59O1xuXG5UeXBlcy5vYmplY3RfaWRfdHlwZSA9IHtcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gX09iamVjdElkMi5kZWZhdWx0LmZyb21CeXRlQnVmZmVyKGIpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBfT2JqZWN0SWQyLmRlZmF1bHQuZnJvbVN0cmluZyhvYmplY3QpO1xuICAgICAgICBvYmplY3QuYXBwZW5kQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX09iamVjdElkMi5kZWZhdWx0LmZyb21TdHJpbmcob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBcIjAuMC4wXCI7XG4gICAgICAgIH1cbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBfT2JqZWN0SWQyLmRlZmF1bHQuZnJvbVN0cmluZyhvYmplY3QpO1xuICAgICAgICByZXR1cm4gb2JqZWN0LnRvU3RyaW5nKCk7XG4gICAgfVxufTtcblxuVHlwZXMudm90ZV9pZCA9IHtcbiAgICBUWVBFOiAweDAwMDAwMGZmLFxuICAgIElEOiAweGZmZmZmZjAwLFxuICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGIucmVhZFVpbnQzMigpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogdmFsdWUgJiB0aGlzLlRZUEUsXG4gICAgICAgICAgICBpZDogdmFsdWUgJiB0aGlzLklEXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgaWYgKG9iamVjdCA9PT0gXCJzdHJpbmdcIikgb2JqZWN0ID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KG9iamVjdCk7XG5cbiAgICAgICAgdmFyIHZhbHVlID0gb2JqZWN0LmlkIDw8IDggfCBvYmplY3QudHlwZTtcbiAgICAgICAgYi53cml0ZVVpbnQzMih2YWx1ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QsIFwiKHR5cGUgdm90ZV9pZClcIik7XG4gICAgICAgIGlmICgodHlwZW9mIG9iamVjdCA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiBfdHlwZW9mKG9iamVjdCkpID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0LnR5cGUsIFwidHlwZVwiKTtcbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QuaWQsIFwiaWRcIik7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlX3Rlc3QoL15bMC05XSs6WzAtOV0rJC8sIG9iamVjdCwgXCJ2b3RlX2lkIGZvcm1hdCBcIiArIG9iamVjdCk7XG5cbiAgICAgICAgdmFyIF9vYmplY3Qkc3BsaXQgPSBvYmplY3Quc3BsaXQoXCI6XCIpLFxuICAgICAgICAgICAgdHlwZSA9IF9vYmplY3Qkc3BsaXRbMF0sXG4gICAgICAgICAgICBpZCA9IF9vYmplY3Qkc3BsaXRbMV07XG5cbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfcmFuZ2UoMCwgMHhmZiwgdHlwZSwgXCJ2b3RlIHR5cGUgXCIgKyBvYmplY3QpO1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZV9yYW5nZSgwLCAweGZmZmZmZiwgaWQsIFwidm90ZSBpZCBcIiArIG9iamVjdCk7XG4gICAgICAgIHJldHVybiB7IHR5cGU6IHR5cGUsIGlkOiBpZCB9O1xuICAgIH0sXG4gICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiMDowXCI7XG4gICAgICAgIH1cbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09PSBcInN0cmluZ1wiKSBvYmplY3QgPSBUeXBlcy52b3RlX2lkLmZyb21PYmplY3Qob2JqZWN0KTtcblxuICAgICAgICByZXR1cm4gb2JqZWN0LnR5cGUgKyBcIjpcIiArIG9iamVjdC5pZDtcbiAgICB9LFxuICAgIGNvbXBhcmU6IGZ1bmN0aW9uIGNvbXBhcmUoYSwgYikge1xuICAgICAgICBpZiAoKHR5cGVvZiBhID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YoYSkpICE9PSBcIm9iamVjdFwiKSBhID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KGEpO1xuICAgICAgICBpZiAoKHR5cGVvZiBiID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YoYikpICE9PSBcIm9iamVjdFwiKSBiID0gVHlwZXMudm90ZV9pZC5mcm9tT2JqZWN0KGIpO1xuICAgICAgICByZXR1cm4gcGFyc2VJbnQoYS5pZCkgLSBwYXJzZUludChiLmlkKTtcbiAgICB9XG59O1xuXG5UeXBlcy5vcHRpb25hbCA9IGZ1bmN0aW9uIChzdF9vcGVyYXRpb24pIHtcbiAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCBcInN0X29wZXJhdGlvblwiKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgaWYgKCEoYi5yZWFkVWludDgoKSA9PT0gMSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgIT09IG51bGwgJiYgb2JqZWN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBiLndyaXRlVWludDgoMSk7XG4gICAgICAgICAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYi53cml0ZVVpbnQ4KDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdF9vcGVyYXRpb24uZnJvbU9iamVjdChvYmplY3QpO1xuICAgICAgICB9LFxuICAgICAgICB0b09iamVjdDogZnVuY3Rpb24gdG9PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGVidWcgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuXG4gICAgICAgICAgICAvLyB0b09iamVjdCBpcyBvbmx5IG51bGwgc2F2ZSBpZiB1c2VfZGVmYXVsdCBpcyB0cnVlXG4gICAgICAgICAgICB2YXIgcmVzdWx0X29iamVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0X29wZXJhdGlvbi50b09iamVjdChvYmplY3QsIGRlYnVnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy5hbm5vdGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmICgodHlwZW9mIHJlc3VsdF9vYmplY3QgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihyZXN1bHRfb2JqZWN0KSkgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0X29iamVjdC5fX29wdGlvbmFsID0gXCJwYXJlbnQgaXMgb3B0aW9uYWxcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRfb2JqZWN0ID0geyBfX29wdGlvbmFsOiByZXN1bHRfb2JqZWN0IH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdF9vYmplY3Q7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMuZXh0ZW5zaW9uID0gZnVuY3Rpb24gKGZpZWxkc19kZWYpIHtcbiAgICAvLyBmaWVsZHNfZGVmIGlzIGFuIGFycmF5XG4gICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVfYXJyYXkoZmllbGRzX2RlZiwgZnVuY3Rpb24gKHIpIHtcbiAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnN0cmluZyhyLm5hbWUpO1xuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQoci50eXBlLCBcInN0X29wZXJhdGlvblwiKTtcbiAgICB9KTtcbiAgICAvL3YucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCBcInN0X29wZXJhdGlvblwiKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIGNvdW50ID0gYi5yZWFkVmFyaW50MzIoKTtcbiAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbyA9IHt9O1xuICAgICAgICAgICAgaWYgKGNvdW50ID4gZmllbGRzX2RlZi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3R3byBtYW55IGZpZWxkcycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd2hpbGUgKGNvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID49IGZpZWxkc19kZWYubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBvcGVyYXRpb24gPSBmaWVsZHNfZGVmW2luZGV4XTtcbiAgICAgICAgICAgICAgICBvW29wZXJhdGlvbi5uYW1lXSA9IG9wZXJhdGlvbi50eXBlLmZyb21CeXRlQnVmZmVyKGIpO1xuICAgICAgICAgICAgICAgIGNvdW50LS07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbztcbiAgICAgICAgICAgIC8vIHJldHVybiBzdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYik7XG4gICAgICAgIH0sXG4gICAgICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgICAgICAvL2xldCB0ZW1wQnVmZmVyID0gbmV3IEJ1ZmZlcihbXSk7XG4gICAgICAgICAgICB2YXIgdGVtcEJ1ZmZlciA9IG5ldyBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdChfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5ERUZBVUxUX0NBUEFDSVRZLCBfYnl0ZWJ1ZmZlcjIuZGVmYXVsdC5MSVRUTEVfRU5ESUFOKTtcbiAgICAgICAgICAgIHZhciBjb3VudCA9IDA7XG4gICAgICAgICAgICBpZiAob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgZmllbGRzX2RlZi5mb3JFYWNoKGZ1bmN0aW9uIChmLCBpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmplY3RbZi5uYW1lXSAhPT0gdW5kZWZpbmVkICYmIG9iamVjdFtmLm5hbWVdICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQnVmZmVyLndyaXRlVmFyaW50MzIoaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmLnR5cGUuYXBwZW5kQnl0ZUJ1ZmZlcih0ZW1wQnVmZmVyLCBvYmplY3RbZi5uYW1lXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBiLndyaXRlVmFyaW50MzIoY291bnQpO1xuICAgICAgICAgICAgdGVtcEJ1ZmZlci5mbGlwKCk7XG4gICAgICAgICAgICBiLmFwcGVuZCh0ZW1wQnVmZmVyKTtcblxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tT2JqZWN0OiBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICByZXR1cm4gc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob2JqZWN0KTtcbiAgICAgICAgICAgICovXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICAgICAgICBmaWVsZHNfZGVmLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0W2YubmFtZV0gIT09IHVuZGVmaW5lZCAmJiBvYmplY3RbZi5uYW1lXSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRbZi5uYW1lXSA9IGYudHlwZS5mcm9tT2JqZWN0KG9iamVjdFtmLm5hbWVdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIC8vIHRvT2JqZWN0IGlzIG9ubHkgbnVsbCBzYXZlIGlmIHVzZV9kZWZhdWx0IGlzIHRydWVcbiAgICAgICAgICAgIHZhciByZXN1bHRfb2JqZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJldHVybiBzdF9vcGVyYXRpb24udG9PYmplY3Qob2JqZWN0LCBkZWJ1Zyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgZmllbGRzX2RlZi5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob2JqZWN0W2YubmFtZV0gIT09IHVuZGVmaW5lZCAmJiBvYmplY3RbZi5uYW1lXSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtmLm5hbWVdID0gZi50eXBlLnRvT2JqZWN0KG9iamVjdFtmLm5hbWVdLCBkZWJ1Zyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0oKTtcblxuICAgICAgICAgICAgaWYgKGRlYnVnLmFubm90YXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgcmVzdWx0X29iamVjdCA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiBfdHlwZW9mKHJlc3VsdF9vYmplY3QpKSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRfb2JqZWN0Ll9fb3B0aW9uYWwgPSBcInBhcmVudCBpcyBvcHRpb25hbFwiO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdF9vYmplY3QgPSB7IF9fb3B0aW9uYWw6IHJlc3VsdF9vYmplY3QgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0X29iamVjdDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG5UeXBlcy5zdGF0aWNfdmFyaWFudCA9IGZ1bmN0aW9uIChfc3Rfb3BlcmF0aW9ucykge1xuICAgIHJldHVybiB7XG4gICAgICAgIG5vc29ydDogdHJ1ZSxcbiAgICAgICAgc3Rfb3BlcmF0aW9uczogX3N0X29wZXJhdGlvbnMsXG4gICAgICAgIGZyb21CeXRlQnVmZmVyOiBmdW5jdGlvbiBmcm9tQnl0ZUJ1ZmZlcihiKSB7XG4gICAgICAgICAgICB2YXIgdHlwZV9pZCA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgICAgICAgaWYgKEhFWF9EVU1QKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcInN0YXRpY192YXJpYW50IGlkIDB4XCIgKyB0eXBlX2lkLnRvU3RyaW5nKDE2KSArIFwiIChcIiArIHR5cGVfaWQgKyBcIilcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCBcIm9wZXJhdGlvbiBcIiArIHR5cGVfaWQpO1xuICAgICAgICAgICAgcmV0dXJuIFt0eXBlX2lkLCBzdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYildO1xuICAgICAgICB9LFxuICAgICAgICBhcHBlbmRCeXRlQnVmZmVyOiBmdW5jdGlvbiBhcHBlbmRCeXRlQnVmZmVyKGIsIG9iamVjdCkge1xuICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKG9iamVjdCk7XG4gICAgICAgICAgICB2YXIgdHlwZV9pZCA9IG9iamVjdFswXTtcbiAgICAgICAgICAgIHZhciBzdF9vcGVyYXRpb24gPSB0aGlzLnN0X29wZXJhdGlvbnNbdHlwZV9pZF07XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQoc3Rfb3BlcmF0aW9uLCBcIm9wZXJhdGlvbiBcIiArIHR5cGVfaWQpO1xuICAgICAgICAgICAgYi53cml0ZVZhcmludDMyKHR5cGVfaWQpO1xuICAgICAgICAgICAgc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0WzFdKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICAgICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKHN0X29wZXJhdGlvbiwgXCJvcGVyYXRpb24gXCIgKyB0eXBlX2lkKTtcbiAgICAgICAgICAgIHJldHVybiBbdHlwZV9pZCwgc3Rfb3BlcmF0aW9uLmZyb21PYmplY3Qob2JqZWN0WzFdKV07XG4gICAgICAgIH0sXG4gICAgICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBkZWJ1ZyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICAgICAgICAgIGlmIChkZWJ1Zy51c2VfZGVmYXVsdCAmJiBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbMCwgdGhpcy5zdF9vcGVyYXRpb25zWzBdLnRvT2JqZWN0KHVuZGVmaW5lZCwgZGVidWcpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICAgICAgdmFyIHR5cGVfaWQgPSBvYmplY3RbMF07XG4gICAgICAgICAgICB2YXIgc3Rfb3BlcmF0aW9uID0gdGhpcy5zdF9vcGVyYXRpb25zW3R5cGVfaWRdO1xuICAgICAgICAgICAgX1NlcmlhbGl6ZXJWYWxpZGF0aW9uMi5kZWZhdWx0LnJlcXVpcmVkKHN0X29wZXJhdGlvbiwgXCJvcGVyYXRpb24gXCIgKyB0eXBlX2lkKTtcbiAgICAgICAgICAgIHJldHVybiBbdHlwZV9pZCwgc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KG9iamVjdFsxXSwgZGVidWcpXTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG5UeXBlcy5tYXAgPSBmdW5jdGlvbiAoa2V5X3N0X29wZXJhdGlvbiwgdmFsdWVfc3Rfb3BlcmF0aW9uKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWRhdGU6IGZ1bmN0aW9uIHZhbGlkYXRlKGFycmF5KSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXkpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZXhwZWN0aW5nIGFycmF5XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGR1cF9tYXAgPSB7fTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvID0gYXJyYXlbaV07XG4gICAgICAgICAgICAgICAgdmFyIHJlZjtcbiAgICAgICAgICAgICAgICBpZiAoIShvLmxlbmd0aCA9PT0gMikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZXhwZWN0aW5nIHR3byBlbGVtZW50c1wiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlZiA9IF90eXBlb2Yob1swXSksIFtcIm51bWJlclwiLCBcInN0cmluZ1wiXS5pbmRleE9mKHJlZikgPj0gMCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZHVwX21hcFtvWzBdXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJkdXBsaWNhdGUgKG1hcClcIik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZHVwX21hcFtvWzBdXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNvcnRPcGVyYXRpb24oYXJyYXksIGtleV9zdF9vcGVyYXRpb24pO1xuICAgICAgICB9LFxuICAgICAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGIucmVhZFZhcmludDMyKCk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgMCA8IGVuZCA/IGkgPCBlbmQgOiBpID4gZW5kOyAwIDwgZW5kID8gaSsrIDogaSsrKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goW2tleV9zdF9vcGVyYXRpb24uZnJvbUJ5dGVCdWZmZXIoYiksIHZhbHVlX3N0X29wZXJhdGlvbi5mcm9tQnl0ZUJ1ZmZlcihiKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUocmVzdWx0KTtcbiAgICAgICAgfSxcbiAgICAgICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgICAgIHRoaXMudmFsaWRhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIGIud3JpdGVWYXJpbnQzMihvYmplY3QubGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICAgICAgICBrZXlfc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb1swXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVfc3Rfb3BlcmF0aW9uLmFwcGVuZEJ5dGVCdWZmZXIoYiwgb1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChba2V5X3N0X29wZXJhdGlvbi5mcm9tT2JqZWN0KG9bMF0pLCB2YWx1ZV9zdF9vcGVyYXRpb24uZnJvbU9iamVjdChvWzFdKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGUocmVzdWx0KTtcbiAgICAgICAgfSxcbiAgICAgICAgdG9PYmplY3Q6IGZ1bmN0aW9uIHRvT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICAgICAgaWYgKGRlYnVnLnVzZV9kZWZhdWx0ICYmIG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtba2V5X3N0X29wZXJhdGlvbi50b09iamVjdCh1bmRlZmluZWQsIGRlYnVnKSwgdmFsdWVfc3Rfb3BlcmF0aW9uLnRvT2JqZWN0KHVuZGVmaW5lZCwgZGVidWcpXV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgICAgIG9iamVjdCA9IHRoaXMudmFsaWRhdGUob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgb2JqZWN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbyA9IG9iamVjdFtpXTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChba2V5X3N0X29wZXJhdGlvbi50b09iamVjdChvWzBdLCBkZWJ1ZyksIHZhbHVlX3N0X29wZXJhdGlvbi50b09iamVjdChvWzFdLCBkZWJ1ZyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcblxuVHlwZXMucHVibGljX2tleSA9IHtcbiAgICB0b1B1YmxpYzogZnVuY3Rpb24gdG9QdWJsaWMob2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QucmVzb2x2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QucmVzb2x2ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBvYmplY3QuUSA/IG9iamVjdCA6IF9lY2MuUHVibGljS2V5LmZyb21TdHJpbmdPclRocm93KG9iamVjdCk7XG4gICAgfSxcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gX0Zhc3RQYXJzZXIyLmRlZmF1bHQucHVibGljX2tleShiKTtcbiAgICB9LFxuICAgIGFwcGVuZEJ5dGVCdWZmZXI6IGZ1bmN0aW9uIGFwcGVuZEJ5dGVCdWZmZXIoYiwgb2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICBfRmFzdFBhcnNlcjIuZGVmYXVsdC5wdWJsaWNfa2V5KGIsIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9LFxuICAgIGZyb21PYmplY3Q6IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICBpZiAob2JqZWN0LlEpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFR5cGVzLnB1YmxpY19rZXkudG9QdWJsaWMob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeCArIFwiODU5Z3hmblh5VXJpTWdVZVRoaDFmV3Yzb3FjcExGeUhhM1RmRllDNFBLMkhxaFRvVk1cIjtcbiAgICAgICAgfVxuICAgICAgICBfU2VyaWFsaXplclZhbGlkYXRpb24yLmRlZmF1bHQucmVxdWlyZWQob2JqZWN0KTtcbiAgICAgICAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xuICAgIH0sXG4gICAgY29tcGFyZTogZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gICAgICAgIHJldHVybiBUeXBlcy5wdWJsaWNfa2V5LmZyb21PYmplY3QoYSkudG9CbG9ja2NoYWluQWRkcmVzcygpLmNvbXBhcmUoVHlwZXMucHVibGljX2tleS5mcm9tT2JqZWN0KGIpLnRvQmxvY2tjaGFpbkFkZHJlc3MoKSk7XG4gICAgfVxufTtcblxuVHlwZXMuYWRkcmVzcyA9IHtcbiAgICBfdG9fYWRkcmVzczogZnVuY3Rpb24gX3RvX2FkZHJlc3Mob2JqZWN0KSB7XG4gICAgICAgIF9TZXJpYWxpemVyVmFsaWRhdGlvbjIuZGVmYXVsdC5yZXF1aXJlZChvYmplY3QpO1xuICAgICAgICBpZiAob2JqZWN0LmFkZHkpIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9lY2MuQWRkcmVzcy5mcm9tU3RyaW5nKG9iamVjdCk7XG4gICAgfSxcbiAgICBmcm9tQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gZnJvbUJ5dGVCdWZmZXIoYikge1xuICAgICAgICByZXR1cm4gbmV3IF9lY2MuQWRkcmVzcyhfRmFzdFBhcnNlcjIuZGVmYXVsdC5yaXBlbWQxNjAoYikpO1xuICAgIH0sXG4gICAgYXBwZW5kQnl0ZUJ1ZmZlcjogZnVuY3Rpb24gYXBwZW5kQnl0ZUJ1ZmZlcihiLCBvYmplY3QpIHtcbiAgICAgICAgX0Zhc3RQYXJzZXIyLmRlZmF1bHQucmlwZW1kMTYwKGIsIFR5cGVzLmFkZHJlc3MuX3RvX2FkZHJlc3Mob2JqZWN0KS50b0J1ZmZlcigpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH0sXG4gICAgZnJvbU9iamVjdDogZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIFR5cGVzLmFkZHJlc3MuX3RvX2FkZHJlc3Mob2JqZWN0KTtcbiAgICB9LFxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbiB0b09iamVjdChvYmplY3QpIHtcbiAgICAgICAgdmFyIGRlYnVnID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICBpZiAoZGVidWcudXNlX2RlZmF1bHQgJiYgb2JqZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBfYml0c2hhcmVzanNXcy5DaGFpbkNvbmZpZy5hZGRyZXNzX3ByZWZpeCArIFwiNjY0S21IeFN1UXlEc2Z3bzRXRUp2V3B6ZzFRS2RnNjdTXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFR5cGVzLmFkZHJlc3MuX3RvX2FkZHJlc3Mob2JqZWN0KS50b1N0cmluZygpO1xuICAgIH0sXG4gICAgY29tcGFyZTogZnVuY3Rpb24gY29tcGFyZShhLCBiKSB7XG4gICAgICAgIHJldHVybiBzdHJDbXAoYS50b1N0cmluZygpLCBiLnRvU3RyaW5nKCkpO1xuICAgIH1cbn07XG5cbnZhciBzdHJDbXAgPSBmdW5jdGlvbiBzdHJDbXAoYSwgYikge1xuICAgIHJldHVybiBhID4gYiA/IDEgOiBhIDwgYiA/IC0xIDogMDtcbn07XG52YXIgZmlyc3RFbCA9IGZ1bmN0aW9uIGZpcnN0RWwoZWwpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShlbCkgPyBlbFswXSA6IGVsO1xufTtcbnZhciBzb3J0T3BlcmF0aW9uID0gZnVuY3Rpb24gc29ydE9wZXJhdGlvbihhcnJheSwgc3Rfb3BlcmF0aW9uKSB7XG4gICAgcmV0dXJuIHN0X29wZXJhdGlvbi5ub3NvcnQgPyBhcnJheSA6IHN0X29wZXJhdGlvbi5jb21wYXJlID8gYXJyYXkuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gc3Rfb3BlcmF0aW9uLmNvbXBhcmUoZmlyc3RFbChhKSwgZmlyc3RFbChiKSk7XG4gICAgfSkgLy8gY3VzdG9tIGNvbXBhcmUgb3BlcmF0aW9uXG4gICAgOiBhcnJheS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgZmlyc3RFbChhKSA9PT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgZmlyc3RFbChiKSA9PT0gXCJudW1iZXJcIiA/IGZpcnN0RWwoYSkgLSBmaXJzdEVsKGIpIDogLy8gQSBiaW5hcnkgc3RyaW5nIGNvbXBhcmUgZG9lcyBub3Qgd29yay4gUGVyZm9ybWFuYW5jZSBpcyB2ZXJ5IGdvb2Qgc28gSEVYIGlzIHVzZWQuLiAgbG9jYWxlQ29tcGFyZSBpcyBhbm90aGVyIG9wdGlvbi5cbiAgICAgICAgQnVmZmVyLmlzQnVmZmVyKGZpcnN0RWwoYSkpICYmIEJ1ZmZlci5pc0J1ZmZlcihmaXJzdEVsKGIpKSA/IHN0ckNtcChmaXJzdEVsKGEpLnRvU3RyaW5nKFwiaGV4XCIpLCBmaXJzdEVsKGIpLnRvU3RyaW5nKFwiaGV4XCIpKSA6IHN0ckNtcChmaXJzdEVsKGEpLnRvU3RyaW5nKCksIGZpcnN0RWwoYikudG9TdHJpbmcoKSk7XG4gICAgfSk7XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBUeXBlcztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07IiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBjb21wYXJlIGFuZCBpc0J1ZmZlciB0YWtlbiBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2Jsb2IvNjgwZTllNWU0ODhmMjJhYWMyNzU5OWE1N2RjODQ0YTYzMTU5MjhkZC9pbmRleC5qc1xuLy8gb3JpZ2luYWwgbm90aWNlOlxuXG4vKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5mdW5jdGlvbiBjb21wYXJlKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHZhciB4ID0gYS5sZW5ndGg7XG4gIHZhciB5ID0gYi5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV07XG4gICAgICB5ID0gYltpXTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuICBpZiAoeSA8IHgpIHtcbiAgICByZXR1cm4gMTtcbiAgfVxuICByZXR1cm4gMDtcbn1cbmZ1bmN0aW9uIGlzQnVmZmVyKGIpIHtcbiAgaWYgKGdsb2JhbC5CdWZmZXIgJiYgdHlwZW9mIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihiKTtcbiAgfVxuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKTtcbn1cblxuLy8gYmFzZWQgb24gbm9kZSBhc3NlcnQsIG9yaWdpbmFsIG5vdGljZTpcblxuLy8gaHR0cDovL3dpa2kuY29tbW9uanMub3JnL3dpa2kvVW5pdF9UZXN0aW5nLzEuMFxuLy9cbi8vIFRISVMgSVMgTk9UIFRFU1RFRCBOT1IgTElLRUxZIFRPIFdPUksgT1VUU0lERSBWOCFcbi8vXG4vLyBPcmlnaW5hbGx5IGZyb20gbmFyd2hhbC5qcyAoaHR0cDovL25hcndoYWxqcy5vcmcpXG4vLyBDb3B5cmlnaHQgKGMpIDIwMDkgVGhvbWFzIFJvYmluc29uIDwyODBub3J0aC5jb20+XG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuLy8gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvXG4vLyBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4vLyBBVVRIT1JTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTlxuLy8gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTlxuLy8gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbC8nKTtcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHBTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciBmdW5jdGlvbnNIYXZlTmFtZXMgPSAoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9vKCkge30ubmFtZSA9PT0gJ2Zvbyc7XG59KCkpO1xuZnVuY3Rpb24gcFRvU3RyaW5nIChvYmopIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xufVxuZnVuY3Rpb24gaXNWaWV3KGFycmJ1Zikge1xuICBpZiAoaXNCdWZmZXIoYXJyYnVmKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIGdsb2JhbC5BcnJheUJ1ZmZlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXcoYXJyYnVmKTtcbiAgfVxuICBpZiAoIWFycmJ1Zikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoYXJyYnVmIGluc3RhbmNlb2YgRGF0YVZpZXcpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoYXJyYnVmLmJ1ZmZlciAmJiBhcnJidWYuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG52YXIgcmVnZXggPSAvXFxzKmZ1bmN0aW9uXFxzKyhbXlxcKFxcc10qKVxccyovO1xuLy8gYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2xqaGFyYi9mdW5jdGlvbi5wcm90b3R5cGUubmFtZS9ibG9iL2FkZWVlZWM4YmZjYzYwNjhiMTg3ZDdkOWZiM2Q1YmIxZDNhMzA4OTkvaW1wbGVtZW50YXRpb24uanNcbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICBpZiAoIXV0aWwuaXNGdW5jdGlvbihmdW5jKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzKSB7XG4gICAgcmV0dXJuIGZ1bmMubmFtZTtcbiAgfVxuICB2YXIgc3RyID0gZnVuYy50b1N0cmluZygpO1xuICB2YXIgbWF0Y2ggPSBzdHIubWF0Y2gocmVnZXgpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV07XG59XG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgaWYgKG9wdGlvbnMubWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG9wdGlvbnMubWVzc2FnZTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBnZXRNZXNzYWdlKHRoaXMpO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IHRydWU7XG4gIH1cbiAgdmFyIHN0YWNrU3RhcnRGdW5jdGlvbiA9IG9wdGlvbnMuc3RhY2tTdGFydEZ1bmN0aW9uIHx8IGZhaWw7XG4gIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHN0YWNrU3RhcnRGdW5jdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gbm9uIHY4IGJyb3dzZXJzIHNvIHdlIGNhbiBoYXZlIGEgc3RhY2t0cmFjZVxuICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoKTtcbiAgICBpZiAoZXJyLnN0YWNrKSB7XG4gICAgICB2YXIgb3V0ID0gZXJyLnN0YWNrO1xuXG4gICAgICAvLyB0cnkgdG8gc3RyaXAgdXNlbGVzcyBmcmFtZXNcbiAgICAgIHZhciBmbl9uYW1lID0gZ2V0TmFtZShzdGFja1N0YXJ0RnVuY3Rpb24pO1xuICAgICAgdmFyIGlkeCA9IG91dC5pbmRleE9mKCdcXG4nICsgZm5fbmFtZSk7XG4gICAgICBpZiAoaWR4ID49IDApIHtcbiAgICAgICAgLy8gb25jZSB3ZSBoYXZlIGxvY2F0ZWQgdGhlIGZ1bmN0aW9uIGZyYW1lXG4gICAgICAgIC8vIHdlIG5lZWQgdG8gc3RyaXAgb3V0IGV2ZXJ5dGhpbmcgYmVmb3JlIGl0IChhbmQgaXRzIGxpbmUpXG4gICAgICAgIHZhciBuZXh0X2xpbmUgPSBvdXQuaW5kZXhPZignXFxuJywgaWR4ICsgMSk7XG4gICAgICAgIG91dCA9IG91dC5zdWJzdHJpbmcobmV4dF9saW5lICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc3RhY2sgPSBvdXQ7XG4gICAgfVxuICB9XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gdHJ1bmNhdGUocywgbikge1xuICBpZiAodHlwZW9mIHMgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5mdW5jdGlvbiBpbnNwZWN0KHNvbWV0aGluZykge1xuICBpZiAoZnVuY3Rpb25zSGF2ZU5hbWVzIHx8ICF1dGlsLmlzRnVuY3Rpb24oc29tZXRoaW5nKSkge1xuICAgIHJldHVybiB1dGlsLmluc3BlY3Qoc29tZXRoaW5nKTtcbiAgfVxuICB2YXIgcmF3bmFtZSA9IGdldE5hbWUoc29tZXRoaW5nKTtcbiAgdmFyIG5hbWUgPSByYXduYW1lID8gJzogJyArIHJhd25hbWUgOiAnJztcbiAgcmV0dXJuICdbRnVuY3Rpb24nICsgIG5hbWUgKyAnXSc7XG59XG5mdW5jdGlvbiBnZXRNZXNzYWdlKHNlbGYpIHtcbiAgcmV0dXJuIHRydW5jYXRlKGluc3BlY3Qoc2VsZi5hY3R1YWwpLCAxMjgpICsgJyAnICtcbiAgICAgICAgIHNlbGYub3BlcmF0b3IgKyAnICcgK1xuICAgICAgICAgdHJ1bmNhdGUoaW5zcGVjdChzZWxmLmV4cGVjdGVkKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgZmFsc2UpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcEVxdWFsJywgYXNzZXJ0LmRlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmFzc2VydC5kZWVwU3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBkZWVwU3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwU3RyaWN0RXF1YWwnLCBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBzdHJpY3QsIG1lbW9zKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgJiYgaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGNvbXBhcmUoYWN0dWFsLCBleHBlY3RlZCkgPT09IDA7XG5cbiAgLy8gNy4yLiBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBEYXRlIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBEYXRlIG9iamVjdCB0aGF0IHJlZmVycyB0byB0aGUgc2FtZSB0aW1lLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNEYXRlKGFjdHVhbCkgJiYgdXRpbC5pc0RhdGUoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMgSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgUmVnRXhwIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBSZWdFeHAgb2JqZWN0IHdpdGggdGhlIHNhbWUgc291cmNlIGFuZFxuICAvLyBwcm9wZXJ0aWVzIChgZ2xvYmFsYCwgYG11bHRpbGluZWAsIGBsYXN0SW5kZXhgLCBgaWdub3JlQ2FzZWApLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNSZWdFeHAoYWN0dWFsKSAmJiB1dGlsLmlzUmVnRXhwKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuc291cmNlID09PSBleHBlY3RlZC5zb3VyY2UgJiZcbiAgICAgICAgICAgYWN0dWFsLmdsb2JhbCA9PT0gZXhwZWN0ZWQuZ2xvYmFsICYmXG4gICAgICAgICAgIGFjdHVhbC5tdWx0aWxpbmUgPT09IGV4cGVjdGVkLm11bHRpbGluZSAmJlxuICAgICAgICAgICBhY3R1YWwubGFzdEluZGV4ID09PSBleHBlY3RlZC5sYXN0SW5kZXggJiZcbiAgICAgICAgICAgYWN0dWFsLmlnbm9yZUNhc2UgPT09IGV4cGVjdGVkLmlnbm9yZUNhc2U7XG5cbiAgLy8gNy40LiBPdGhlciBwYWlycyB0aGF0IGRvIG5vdCBib3RoIHBhc3MgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnLFxuICAvLyBlcXVpdmFsZW5jZSBpcyBkZXRlcm1pbmVkIGJ5ID09LlxuICB9IGVsc2UgaWYgKChhY3R1YWwgPT09IG51bGwgfHwgdHlwZW9mIGFjdHVhbCAhPT0gJ29iamVjdCcpICYmXG4gICAgICAgICAgICAgKGV4cGVjdGVkID09PSBudWxsIHx8IHR5cGVvZiBleHBlY3RlZCAhPT0gJ29iamVjdCcpKSB7XG4gICAgcmV0dXJuIHN0cmljdCA/IGFjdHVhbCA9PT0gZXhwZWN0ZWQgOiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gSWYgYm90aCB2YWx1ZXMgYXJlIGluc3RhbmNlcyBvZiB0eXBlZCBhcnJheXMsIHdyYXAgdGhlaXIgdW5kZXJseWluZ1xuICAvLyBBcnJheUJ1ZmZlcnMgaW4gYSBCdWZmZXIgZWFjaCB0byBpbmNyZWFzZSBwZXJmb3JtYW5jZVxuICAvLyBUaGlzIG9wdGltaXphdGlvbiByZXF1aXJlcyB0aGUgYXJyYXlzIHRvIGhhdmUgdGhlIHNhbWUgdHlwZSBhcyBjaGVja2VkIGJ5XG4gIC8vIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcgKGFrYSBwVG9TdHJpbmcpLiBOZXZlciBwZXJmb3JtIGJpbmFyeVxuICAvLyBjb21wYXJpc29ucyBmb3IgRmxvYXQqQXJyYXlzLCB0aG91Z2gsIHNpbmNlIGUuZy4gKzAgPT09IC0wIGJ1dCB0aGVpclxuICAvLyBiaXQgcGF0dGVybnMgYXJlIG5vdCBpZGVudGljYWwuXG4gIH0gZWxzZSBpZiAoaXNWaWV3KGFjdHVhbCkgJiYgaXNWaWV3KGV4cGVjdGVkKSAmJlxuICAgICAgICAgICAgIHBUb1N0cmluZyhhY3R1YWwpID09PSBwVG9TdHJpbmcoZXhwZWN0ZWQpICYmXG4gICAgICAgICAgICAgIShhY3R1YWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgfHxcbiAgICAgICAgICAgICAgIGFjdHVhbCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSkpIHtcbiAgICByZXR1cm4gY29tcGFyZShuZXcgVWludDhBcnJheShhY3R1YWwuYnVmZmVyKSxcbiAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShleHBlY3RlZC5idWZmZXIpKSA9PT0gMDtcblxuICAvLyA3LjUgRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2UgaWYgKGlzQnVmZmVyKGFjdHVhbCkgIT09IGlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICBtZW1vcyA9IG1lbW9zIHx8IHthY3R1YWw6IFtdLCBleHBlY3RlZDogW119O1xuXG4gICAgdmFyIGFjdHVhbEluZGV4ID0gbWVtb3MuYWN0dWFsLmluZGV4T2YoYWN0dWFsKTtcbiAgICBpZiAoYWN0dWFsSW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoYWN0dWFsSW5kZXggPT09IG1lbW9zLmV4cGVjdGVkLmluZGV4T2YoZXhwZWN0ZWQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1lbW9zLmFjdHVhbC5wdXNoKGFjdHVhbCk7XG4gICAgbWVtb3MuZXhwZWN0ZWQucHVzaChleHBlY3RlZCk7XG5cbiAgICByZXR1cm4gb2JqRXF1aXYoYWN0dWFsLCBleHBlY3RlZCwgc3RyaWN0LCBtZW1vcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcbn1cblxuZnVuY3Rpb24gb2JqRXF1aXYoYSwgYiwgc3RyaWN0LCBhY3R1YWxWaXNpdGVkT2JqZWN0cykge1xuICBpZiAoYSA9PT0gbnVsbCB8fCBhID09PSB1bmRlZmluZWQgfHwgYiA9PT0gbnVsbCB8fCBiID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvLyBpZiBvbmUgaXMgYSBwcmltaXRpdmUsIHRoZSBvdGhlciBtdXN0IGJlIHNhbWVcbiAgaWYgKHV0aWwuaXNQcmltaXRpdmUoYSkgfHwgdXRpbC5pc1ByaW1pdGl2ZShiKSlcbiAgICByZXR1cm4gYSA9PT0gYjtcbiAgaWYgKHN0cmljdCAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkgIT09IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIHZhciBhSXNBcmdzID0gaXNBcmd1bWVudHMoYSk7XG4gIHZhciBiSXNBcmdzID0gaXNBcmd1bWVudHMoYik7XG4gIGlmICgoYUlzQXJncyAmJiAhYklzQXJncykgfHwgKCFhSXNBcmdzICYmIGJJc0FyZ3MpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgaWYgKGFJc0FyZ3MpIHtcbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIsIHN0cmljdCk7XG4gIH1cbiAgdmFyIGthID0gb2JqZWN0S2V5cyhhKTtcbiAgdmFyIGtiID0gb2JqZWN0S2V5cyhiKTtcbiAgdmFyIGtleSwgaTtcbiAgLy8gaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChrZXlzIGluY29ycG9yYXRlc1xuICAvLyBoYXNPd25Qcm9wZXJ0eSlcbiAgaWYgKGthLmxlbmd0aCAhPT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT09IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFfZGVlcEVxdWFsKGFba2V5XSwgYltrZXldLCBzdHJpY3QsIGFjdHVhbFZpc2l0ZWRPYmplY3RzKSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gOC4gVGhlIG5vbi1lcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgZm9yIGFueSBkZWVwIGluZXF1YWxpdHkuXG4vLyBhc3NlcnQubm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIG5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIGZhbHNlKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG5hc3NlcnQubm90RGVlcFN0cmljdEVxdWFsID0gbm90RGVlcFN0cmljdEVxdWFsO1xuZnVuY3Rpb24gbm90RGVlcFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgdHJ1ZSkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwU3RyaWN0RXF1YWwnLCBub3REZWVwU3RyaWN0RXF1YWwpO1xuICB9XG59XG5cblxuLy8gOS4gVGhlIHN0cmljdCBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc3RyaWN0IGVxdWFsaXR5LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbi8vIGFzc2VydC5zdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5zdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIHN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PT0nLCBhc3NlcnQuc3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG4vLyAxMC4gVGhlIHN0cmljdCBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciBzdHJpY3QgaW5lcXVhbGl0eSwgYXNcbi8vIGRldGVybWluZWQgYnkgIT09LiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gbm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9PScsIGFzc2VydC5ub3RTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgaWYgKCFhY3R1YWwgfHwgIWV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChleHBlY3RlZCkgPT0gJ1tvYmplY3QgUmVnRXhwXScpIHtcbiAgICByZXR1cm4gZXhwZWN0ZWQudGVzdChhY3R1YWwpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElnbm9yZS4gIFRoZSBpbnN0YW5jZW9mIGNoZWNrIGRvZXNuJ3Qgd29yayBmb3IgYXJyb3cgZnVuY3Rpb25zLlxuICB9XG5cbiAgaWYgKEVycm9yLmlzUHJvdG90eXBlT2YoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIGV4cGVjdGVkLmNhbGwoe30sIGFjdHVhbCkgPT09IHRydWU7XG59XG5cbmZ1bmN0aW9uIF90cnlCbG9jayhibG9jaykge1xuICB2YXIgZXJyb3I7XG4gIHRyeSB7XG4gICAgYmxvY2soKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVycm9yID0gZTtcbiAgfVxuICByZXR1cm4gZXJyb3I7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh0eXBlb2YgYmxvY2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJsb2NrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cGVjdGVkID09PSAnc3RyaW5nJykge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICBhY3R1YWwgPSBfdHJ5QmxvY2soYmxvY2spO1xuXG4gIG1lc3NhZ2UgPSAoZXhwZWN0ZWQgJiYgZXhwZWN0ZWQubmFtZSA/ICcgKCcgKyBleHBlY3RlZC5uYW1lICsgJykuJyA6ICcuJykgK1xuICAgICAgICAgICAgKG1lc3NhZ2UgPyAnICcgKyBtZXNzYWdlIDogJy4nKTtcblxuICBpZiAoc2hvdWxkVGhyb3cgJiYgIWFjdHVhbCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ01pc3NpbmcgZXhwZWN0ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgdmFyIHVzZXJQcm92aWRlZE1lc3NhZ2UgPSB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZyc7XG4gIHZhciBpc1Vud2FudGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIHV0aWwuaXNFcnJvcihhY3R1YWwpO1xuICB2YXIgaXNVbmV4cGVjdGVkRXhjZXB0aW9uID0gIXNob3VsZFRocm93ICYmIGFjdHVhbCAmJiAhZXhwZWN0ZWQ7XG5cbiAgaWYgKChpc1Vud2FudGVkRXhjZXB0aW9uICYmXG4gICAgICB1c2VyUHJvdmlkZWRNZXNzYWdlICYmXG4gICAgICBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHxcbiAgICAgIGlzVW5leHBlY3RlZEV4Y2VwdGlvbikge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ0dvdCB1bndhbnRlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoKHNob3VsZFRocm93ICYmIGFjdHVhbCAmJiBleHBlY3RlZCAmJlxuICAgICAgIWV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fCAoIXNob3VsZFRocm93ICYmIGFjdHVhbCkpIHtcbiAgICB0aHJvdyBhY3R1YWw7XG4gIH1cbn1cblxuLy8gMTEuIEV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yOlxuLy8gYXNzZXJ0LnRocm93cyhibG9jaywgRXJyb3Jfb3B0LCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC50aHJvd3MgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cyh0cnVlLCBibG9jaywgZXJyb3IsIG1lc3NhZ2UpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MoZmFsc2UsIGJsb2NrLCBlcnJvciwgbWVzc2FnZSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB0aHJvdyBlcnI7IH07XG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKGhhc093bi5jYWxsKG9iaiwga2V5KSkga2V5cy5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIGtleXM7XG59O1xuIiwiLy8gYmFzZS14IGVuY29kaW5nXG4vLyBGb3JrZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2JzNThcbi8vIE9yaWdpbmFsbHkgd3JpdHRlbiBieSBNaWtlIEhlYXJuIGZvciBCaXRjb2luSlxuLy8gQ29weXJpZ2h0IChjKSAyMDExIEdvb2dsZSBJbmNcbi8vIFBvcnRlZCB0byBKYXZhU2NyaXB0IGJ5IFN0ZWZhbiBUaG9tYXNcbi8vIE1lcmdlZCBCdWZmZXIgcmVmYWN0b3JpbmdzIGZyb20gYmFzZTU4LW5hdGl2ZSBieSBTdGVwaGVuIFBhaXJcbi8vIENvcHlyaWdodCAoYykgMjAxMyBCaXRQYXkgSW5jXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGJhc2UgKEFMUEhBQkVUKSB7XG4gIHZhciBBTFBIQUJFVF9NQVAgPSB7fVxuICB2YXIgQkFTRSA9IEFMUEhBQkVULmxlbmd0aFxuICB2YXIgTEVBREVSID0gQUxQSEFCRVQuY2hhckF0KDApXG5cbiAgLy8gcHJlLWNvbXB1dGUgbG9va3VwIHRhYmxlXG4gIGZvciAodmFyIHogPSAwOyB6IDwgQUxQSEFCRVQubGVuZ3RoOyB6KyspIHtcbiAgICB2YXIgeCA9IEFMUEhBQkVULmNoYXJBdCh6KVxuXG4gICAgaWYgKEFMUEhBQkVUX01BUFt4XSAhPT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKHggKyAnIGlzIGFtYmlndW91cycpXG4gICAgQUxQSEFCRVRfTUFQW3hdID0gelxuICB9XG5cbiAgZnVuY3Rpb24gZW5jb2RlIChzb3VyY2UpIHtcbiAgICBpZiAoc291cmNlLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG5cbiAgICB2YXIgZGlnaXRzID0gWzBdXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyArK2kpIHtcbiAgICAgIGZvciAodmFyIGogPSAwLCBjYXJyeSA9IHNvdXJjZVtpXTsgaiA8IGRpZ2l0cy5sZW5ndGg7ICsraikge1xuICAgICAgICBjYXJyeSArPSBkaWdpdHNbal0gPDwgOFxuICAgICAgICBkaWdpdHNbal0gPSBjYXJyeSAlIEJBU0VcbiAgICAgICAgY2FycnkgPSAoY2FycnkgLyBCQVNFKSB8IDBcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKGNhcnJ5ID4gMCkge1xuICAgICAgICBkaWdpdHMucHVzaChjYXJyeSAlIEJBU0UpXG4gICAgICAgIGNhcnJ5ID0gKGNhcnJ5IC8gQkFTRSkgfCAwXG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHN0cmluZyA9ICcnXG5cbiAgICAvLyBkZWFsIHdpdGggbGVhZGluZyB6ZXJvc1xuICAgIGZvciAodmFyIGsgPSAwOyBzb3VyY2Vba10gPT09IDAgJiYgayA8IHNvdXJjZS5sZW5ndGggLSAxOyArK2spIHN0cmluZyArPSBBTFBIQUJFVFswXVxuICAgIC8vIGNvbnZlcnQgZGlnaXRzIHRvIGEgc3RyaW5nXG4gICAgZm9yICh2YXIgcSA9IGRpZ2l0cy5sZW5ndGggLSAxOyBxID49IDA7IC0tcSkgc3RyaW5nICs9IEFMUEhBQkVUW2RpZ2l0c1txXV1cblxuICAgIHJldHVybiBzdHJpbmdcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY29kZVVuc2FmZSAoc3RyaW5nKSB7XG4gICAgaWYgKHN0cmluZy5sZW5ndGggPT09IDApIHJldHVybiBCdWZmZXIuYWxsb2NVbnNhZmUoMClcblxuICAgIHZhciBieXRlcyA9IFswXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdmFsdWUgPSBBTFBIQUJFVF9NQVBbc3RyaW5nW2ldXVxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVyblxuXG4gICAgICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSB2YWx1ZTsgaiA8IGJ5dGVzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIGNhcnJ5ICs9IGJ5dGVzW2pdICogQkFTRVxuICAgICAgICBieXRlc1tqXSA9IGNhcnJ5ICYgMHhmZlxuICAgICAgICBjYXJyeSA+Pj0gOFxuICAgICAgfVxuXG4gICAgICB3aGlsZSAoY2FycnkgPiAwKSB7XG4gICAgICAgIGJ5dGVzLnB1c2goY2FycnkgJiAweGZmKVxuICAgICAgICBjYXJyeSA+Pj0gOFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRlYWwgd2l0aCBsZWFkaW5nIHplcm9zXG4gICAgZm9yICh2YXIgayA9IDA7IHN0cmluZ1trXSA9PT0gTEVBREVSICYmIGsgPCBzdHJpbmcubGVuZ3RoIC0gMTsgKytrKSB7XG4gICAgICBieXRlcy5wdXNoKDApXG4gICAgfVxuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ5dGVzLnJldmVyc2UoKSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY29kZSAoc3RyaW5nKSB7XG4gICAgdmFyIGJ1ZmZlciA9IGRlY29kZVVuc2FmZShzdHJpbmcpXG4gICAgaWYgKGJ1ZmZlcikgcmV0dXJuIGJ1ZmZlclxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdOb24tYmFzZScgKyBCQVNFICsgJyBjaGFyYWN0ZXInKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlbmNvZGU6IGVuY29kZSxcbiAgICBkZWNvZGVVbnNhZmU6IGRlY29kZVVuc2FmZSxcbiAgICBkZWNvZGU6IGRlY29kZVxuICB9XG59XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8vIChwdWJsaWMpIENvbnN0cnVjdG9yXG5mdW5jdGlvbiBCaWdJbnRlZ2VyKGEsIGIsIGMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJpZ0ludGVnZXIpKVxuICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcihhLCBiLCBjKVxuXG4gIGlmIChhICE9IG51bGwpIHtcbiAgICBpZiAoXCJudW1iZXJcIiA9PSB0eXBlb2YgYSkgdGhpcy5mcm9tTnVtYmVyKGEsIGIsIGMpXG4gICAgZWxzZSBpZiAoYiA9PSBudWxsICYmIFwic3RyaW5nXCIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLCAyNTYpXG4gICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSwgYilcbiAgfVxufVxuXG52YXIgcHJvdG8gPSBCaWdJbnRlZ2VyLnByb3RvdHlwZVxuXG4vLyBkdWNrLXR5cGVkIGlzQmlnSW50ZWdlclxucHJvdG8uX19iaWdpID0gcmVxdWlyZSgnLi4vcGFja2FnZS5qc29uJykudmVyc2lvblxuQmlnSW50ZWdlci5pc0JpZ0ludGVnZXIgPSBmdW5jdGlvbiAob2JqLCBjaGVja192ZXIpIHtcbiAgcmV0dXJuIG9iaiAmJiBvYmouX19iaWdpICYmICghY2hlY2tfdmVyIHx8IG9iai5fX2JpZ2kgPT09IHByb3RvLl9fYmlnaSlcbn1cblxuLy8gQml0cyBwZXIgZGlnaXRcbnZhciBkYml0c1xuXG4vLyBhbTogQ29tcHV0ZSB3X2ogKz0gKHgqdGhpc19pKSwgcHJvcGFnYXRlIGNhcnJpZXMsXG4vLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuXG4vLyBjIDwgMypkdmFsdWUsIHggPCAyKmR2YWx1ZSwgdGhpc19pIDwgZHZhbHVlXG4vLyBXZSBuZWVkIHRvIHNlbGVjdCB0aGUgZmFzdGVzdCBvbmUgdGhhdCB3b3JrcyBpbiB0aGlzIGVudmlyb25tZW50LlxuXG4vLyBhbTE6IHVzZSBhIHNpbmdsZSBtdWx0IGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSBoaWdoIGJpdHMsXG4vLyBtYXggZGlnaXQgYml0cyBzaG91bGQgYmUgMjYgYmVjYXVzZVxuLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKVxuZnVuY3Rpb24gYW0xKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIHYgPSB4ICogdGhpc1tpKytdICsgd1tqXSArIGNcbiAgICBjID0gTWF0aC5mbG9vcih2IC8gMHg0MDAwMDAwKVxuICAgIHdbaisrXSA9IHYgJiAweDNmZmZmZmZcbiAgfVxuICByZXR1cm4gY1xufVxuLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuXG4vLyBNYXggZGlnaXQgYml0cyBzaG91bGQgYmUgPD0gMzAgYmVjYXVzZSB3ZSBkbyBiaXR3aXNlIG9wc1xuLy8gb24gdmFsdWVzIHVwIHRvIDIqaGR2YWx1ZV4yLWhkdmFsdWUtMSAoPCAyXjMxKVxuZnVuY3Rpb24gYW0yKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4N2ZmZixcbiAgICB4aCA9IHggPj4gMTVcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHg3ZmZmXG4gICAgdmFyIGggPSB0aGlzW2krK10gPj4gMTVcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bFxuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDdmZmYpIDw8IDE1KSArIHdbal0gKyAoYyAmIDB4M2ZmZmZmZmYpXG4gICAgYyA9IChsID4+PiAzMCkgKyAobSA+Pj4gMTUpICsgeGggKiBoICsgKGMgPj4+IDMwKVxuICAgIHdbaisrXSA9IGwgJiAweDNmZmZmZmZmXG4gIH1cbiAgcmV0dXJuIGNcbn1cbi8vIEFsdGVybmF0ZWx5LCBzZXQgbWF4IGRpZ2l0IGJpdHMgdG8gMjggc2luY2Ugc29tZVxuLy8gYnJvd3NlcnMgc2xvdyBkb3duIHdoZW4gZGVhbGluZyB3aXRoIDMyLWJpdCBudW1iZXJzLlxuZnVuY3Rpb24gYW0zKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4M2ZmZixcbiAgICB4aCA9IHggPj4gMTRcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHgzZmZmXG4gICAgdmFyIGggPSB0aGlzW2krK10gPj4gMTRcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bFxuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDNmZmYpIDw8IDE0KSArIHdbal0gKyBjXG4gICAgYyA9IChsID4+IDI4KSArIChtID4+IDE0KSArIHhoICogaFxuICAgIHdbaisrXSA9IGwgJiAweGZmZmZmZmZcbiAgfVxuICByZXR1cm4gY1xufVxuXG4vLyB3dGY/XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMVxuZGJpdHMgPSAyNlxuXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMSA8PCBkYml0cykgLSAxKVxudmFyIERWID0gQmlnSW50ZWdlci5wcm90b3R5cGUuRFYgPSAoMSA8PCBkYml0cylcblxudmFyIEJJX0ZQID0gNTJcbkJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMiwgQklfRlApXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5GMSA9IEJJX0ZQIC0gZGJpdHNcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYyID0gMiAqIGRiaXRzIC0gQklfRlBcblxuLy8gRGlnaXQgY29udmVyc2lvbnNcbnZhciBCSV9STSA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCJcbnZhciBCSV9SQyA9IG5ldyBBcnJheSgpXG52YXIgcnIsIHZ2XG5yciA9IFwiMFwiLmNoYXJDb2RlQXQoMClcbmZvciAodnYgPSAwOyB2diA8PSA5OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2XG5yciA9IFwiYVwiLmNoYXJDb2RlQXQoMClcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2dlxucnIgPSBcIkFcIi5jaGFyQ29kZUF0KDApXG5mb3IgKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnZcblxuZnVuY3Rpb24gaW50MmNoYXIobikge1xuICByZXR1cm4gQklfUk0uY2hhckF0KG4pXG59XG5cbmZ1bmN0aW9uIGludEF0KHMsIGkpIHtcbiAgdmFyIGMgPSBCSV9SQ1tzLmNoYXJDb2RlQXQoaSldXG4gIHJldHVybiAoYyA9PSBudWxsKSA/IC0xIDogY1xufVxuXG4vLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gclxuZnVuY3Rpb24gYm5wQ29weVRvKHIpIHtcbiAgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gdGhpc1tpXVxuICByLnQgPSB0aGlzLnRcbiAgci5zID0gdGhpcy5zXG59XG5cbi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVlxuZnVuY3Rpb24gYm5wRnJvbUludCh4KSB7XG4gIHRoaXMudCA9IDFcbiAgdGhpcy5zID0gKHggPCAwKSA/IC0xIDogMFxuICBpZiAoeCA+IDApIHRoaXNbMF0gPSB4XG4gIGVsc2UgaWYgKHggPCAtMSkgdGhpc1swXSA9IHggKyBEVlxuICBlbHNlIHRoaXMudCA9IDBcbn1cblxuLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuZnVuY3Rpb24gbmJ2KGkpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHIuZnJvbUludChpKVxuICByZXR1cm4gclxufVxuXG4vLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG5mdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsIGIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgdmFyIGtcbiAgaWYgKGIgPT0gMTYpIGsgPSA0XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDNcbiAgZWxzZSBpZiAoYiA9PSAyNTYpIGsgPSA4OyAvLyBieXRlIGFycmF5XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDFcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDVcbiAgZWxzZSBpZiAoYiA9PSA0KSBrID0gMlxuICBlbHNlIHtcbiAgICBzZWxmLmZyb21SYWRpeChzLCBiKVxuICAgIHJldHVyblxuICB9XG4gIHNlbGYudCA9IDBcbiAgc2VsZi5zID0gMFxuICB2YXIgaSA9IHMubGVuZ3RoLFxuICAgIG1pID0gZmFsc2UsXG4gICAgc2ggPSAwXG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHZhciB4ID0gKGsgPT0gOCkgPyBzW2ldICYgMHhmZiA6IGludEF0KHMsIGkpXG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIpIG1pID0gdHJ1ZVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgbWkgPSBmYWxzZVxuICAgIGlmIChzaCA9PSAwKVxuICAgICAgc2VsZltzZWxmLnQrK10gPSB4XG4gICAgZWxzZSBpZiAoc2ggKyBrID4gc2VsZi5EQikge1xuICAgICAgc2VsZltzZWxmLnQgLSAxXSB8PSAoeCAmICgoMSA8PCAoc2VsZi5EQiAtIHNoKSkgLSAxKSkgPDwgc2hcbiAgICAgIHNlbGZbc2VsZi50KytdID0gKHggPj4gKHNlbGYuREIgLSBzaCkpXG4gICAgfSBlbHNlXG4gICAgICBzZWxmW3NlbGYudCAtIDFdIHw9IHggPDwgc2hcbiAgICBzaCArPSBrXG4gICAgaWYgKHNoID49IHNlbGYuREIpIHNoIC09IHNlbGYuREJcbiAgfVxuICBpZiAoayA9PSA4ICYmIChzWzBdICYgMHg4MCkgIT0gMCkge1xuICAgIHNlbGYucyA9IC0xXG4gICAgaWYgKHNoID4gMCkgc2VsZltzZWxmLnQgLSAxXSB8PSAoKDEgPDwgKHNlbGYuREIgLSBzaCkpIC0gMSkgPDwgc2hcbiAgfVxuICBzZWxmLmNsYW1wKClcbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oc2VsZiwgc2VsZilcbn1cblxuLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG5mdW5jdGlvbiBibnBDbGFtcCgpIHtcbiAgdmFyIGMgPSB0aGlzLnMgJiB0aGlzLkRNXG4gIHdoaWxlICh0aGlzLnQgPiAwICYmIHRoaXNbdGhpcy50IC0gMV0gPT0gYyktLXRoaXMudFxufVxuXG4vLyAocHVibGljKSByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIGluIGdpdmVuIHJhZGl4XG5mdW5jdGlvbiBiblRvU3RyaW5nKGIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIGlmIChzZWxmLnMgPCAwKSByZXR1cm4gXCItXCIgKyBzZWxmLm5lZ2F0ZSgpXG4gICAgLnRvU3RyaW5nKGIpXG4gIHZhciBrXG4gIGlmIChiID09IDE2KSBrID0gNFxuICBlbHNlIGlmIChiID09IDgpIGsgPSAzXG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDFcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDVcbiAgZWxzZSBpZiAoYiA9PSA0KSBrID0gMlxuICBlbHNlIHJldHVybiBzZWxmLnRvUmFkaXgoYilcbiAgdmFyIGttID0gKDEgPDwgaykgLSAxLFxuICAgIGQsIG0gPSBmYWxzZSxcbiAgICByID0gXCJcIixcbiAgICBpID0gc2VsZi50XG4gIHZhciBwID0gc2VsZi5EQiAtIChpICogc2VsZi5EQikgJSBrXG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCBzZWxmLkRCICYmIChkID0gc2VsZltpXSA+PiBwKSA+IDApIHtcbiAgICAgIG0gPSB0cnVlXG4gICAgICByID0gaW50MmNoYXIoZClcbiAgICB9XG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgaWYgKHAgPCBrKSB7XG4gICAgICAgIGQgPSAoc2VsZltpXSAmICgoMSA8PCBwKSAtIDEpKSA8PCAoayAtIHApXG4gICAgICAgIGQgfD0gc2VsZlstLWldID4+IChwICs9IHNlbGYuREIgLSBrKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZCA9IChzZWxmW2ldID4+IChwIC09IGspKSAmIGttXG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHNlbGYuREJcbiAgICAgICAgICAtLWlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGQgPiAwKSBtID0gdHJ1ZVxuICAgICAgaWYgKG0pIHIgKz0gaW50MmNoYXIoZClcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG0gPyByIDogXCIwXCJcbn1cblxuLy8gKHB1YmxpYykgLXRoaXNcbmZ1bmN0aW9uIGJuTmVnYXRlKCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHx0aGlzfFxuZnVuY3Rpb24gYm5BYnMoKSB7XG4gIHJldHVybiAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpc1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gKyBpZiB0aGlzID4gYSwgLSBpZiB0aGlzIDwgYSwgMCBpZiBlcXVhbFxuZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkge1xuICB2YXIgciA9IHRoaXMucyAtIGEuc1xuICBpZiAociAhPSAwKSByZXR1cm4gclxuICB2YXIgaSA9IHRoaXMudFxuICByID0gaSAtIGEudFxuICBpZiAociAhPSAwKSByZXR1cm4gKHRoaXMucyA8IDApID8gLXIgOiByXG4gIHdoaWxlICgtLWkgPj0gMClcbiAgICBpZiAoKHIgPSB0aGlzW2ldIC0gYVtpXSkgIT0gMCkgcmV0dXJuIHJcbiAgcmV0dXJuIDBcbn1cblxuLy8gcmV0dXJucyBiaXQgbGVuZ3RoIG9mIHRoZSBpbnRlZ2VyIHhcbmZ1bmN0aW9uIG5iaXRzKHgpIHtcbiAgdmFyIHIgPSAxLFxuICAgIHRcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gMTZcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDgpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gOFxuICB9XG4gIGlmICgodCA9IHggPj4gNCkgIT0gMCkge1xuICAgIHggPSB0XG4gICAgciArPSA0XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHRcbiAgICByICs9IDJcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDEpICE9IDApIHtcbiAgICB4ID0gdFxuICAgIHIgKz0gMVxuICB9XG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gXCJ0aGlzXCJcbmZ1bmN0aW9uIGJuQml0TGVuZ3RoKCkge1xuICBpZiAodGhpcy50IDw9IDApIHJldHVybiAwXG4gIHJldHVybiB0aGlzLkRCICogKHRoaXMudCAtIDEpICsgbmJpdHModGhpc1t0aGlzLnQgLSAxXSBeICh0aGlzLnMgJiB0aGlzLkRNKSlcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gXCJ0aGlzXCJcbmZ1bmN0aW9uIGJuQnl0ZUxlbmd0aCgpIHtcbiAgcmV0dXJuIHRoaXMuYml0TGVuZ3RoKCkgPj4gM1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuKkRCXG5mdW5jdGlvbiBibnBETFNoaWZ0VG8obiwgcikge1xuICB2YXIgaVxuICBmb3IgKGkgPSB0aGlzLnQgLSAxOyBpID49IDA7IC0taSkgcltpICsgbl0gPSB0aGlzW2ldXG4gIGZvciAoaSA9IG4gLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDBcbiAgci50ID0gdGhpcy50ICsgblxuICByLnMgPSB0aGlzLnNcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQlxuZnVuY3Rpb24gYm5wRFJTaGlmdFRvKG4sIHIpIHtcbiAgZm9yICh2YXIgaSA9IG47IGkgPCB0aGlzLnQ7ICsraSkgcltpIC0gbl0gPSB0aGlzW2ldXG4gIHIudCA9IE1hdGgubWF4KHRoaXMudCAtIG4sIDApXG4gIHIucyA9IHRoaXMuc1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuXG5mdW5jdGlvbiBibnBMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgYnMgPSBuICUgc2VsZi5EQlxuICB2YXIgY2JzID0gc2VsZi5EQiAtIGJzXG4gIHZhciBibSA9ICgxIDw8IGNicykgLSAxXG4gIHZhciBkcyA9IE1hdGguZmxvb3IobiAvIHNlbGYuREIpLFxuICAgIGMgPSAoc2VsZi5zIDw8IGJzKSAmIHNlbGYuRE0sXG4gICAgaVxuICBmb3IgKGkgPSBzZWxmLnQgLSAxOyBpID49IDA7IC0taSkge1xuICAgIHJbaSArIGRzICsgMV0gPSAoc2VsZltpXSA+PiBjYnMpIHwgY1xuICAgIGMgPSAoc2VsZltpXSAmIGJtKSA8PCBic1xuICB9XG4gIGZvciAoaSA9IGRzIC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwXG4gIHJbZHNdID0gY1xuICByLnQgPSBzZWxmLnQgKyBkcyArIDFcbiAgci5zID0gc2VsZi5zXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuXG5mdW5jdGlvbiBibnBSU2hpZnRUbyhuLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICByLnMgPSBzZWxmLnNcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gc2VsZi5EQilcbiAgaWYgKGRzID49IHNlbGYudCkge1xuICAgIHIudCA9IDBcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgYnMgPSBuICUgc2VsZi5EQlxuICB2YXIgY2JzID0gc2VsZi5EQiAtIGJzXG4gIHZhciBibSA9ICgxIDw8IGJzKSAtIDFcbiAgclswXSA9IHNlbGZbZHNdID4+IGJzXG4gIGZvciAodmFyIGkgPSBkcyArIDE7IGkgPCBzZWxmLnQ7ICsraSkge1xuICAgIHJbaSAtIGRzIC0gMV0gfD0gKHNlbGZbaV0gJiBibSkgPDwgY2JzXG4gICAgcltpIC0gZHNdID0gc2VsZltpXSA+PiBic1xuICB9XG4gIGlmIChicyA+IDApIHJbc2VsZi50IC0gZHMgLSAxXSB8PSAoc2VsZi5zICYgYm0pIDw8IGNic1xuICByLnQgPSBzZWxmLnQgLSBkc1xuICByLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG5mdW5jdGlvbiBibnBTdWJUbyhhLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgaSA9IDAsXG4gICAgYyA9IDAsXG4gICAgbSA9IE1hdGgubWluKGEudCwgc2VsZi50KVxuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHNlbGZbaV0gLSBhW2ldXG4gICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICBjID4+PSBzZWxmLkRCXG4gIH1cbiAgaWYgKGEudCA8IHNlbGYudCkge1xuICAgIGMgLT0gYS5zXG4gICAgd2hpbGUgKGkgPCBzZWxmLnQpIHtcbiAgICAgIGMgKz0gc2VsZltpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyArPSBzZWxmLnNcbiAgfSBlbHNlIHtcbiAgICBjICs9IHNlbGYuc1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjIC09IGFbaV1cbiAgICAgIHJbaSsrXSA9IGMgJiBzZWxmLkRNXG4gICAgICBjID4+PSBzZWxmLkRCXG4gICAgfVxuICAgIGMgLT0gYS5zXG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMFxuICBpZiAoYyA8IC0xKSByW2krK10gPSBzZWxmLkRWICsgY1xuICBlbHNlIGlmIChjID4gMCkgcltpKytdID0gY1xuICByLnQgPSBpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5mdW5jdGlvbiBibnBNdWx0aXBseVRvKGEsIHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpLFxuICAgIHkgPSBhLmFicygpXG4gIHZhciBpID0geC50XG4gIHIudCA9IGkgKyB5LnRcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgeS50OyArK2kpIHJbaSArIHgudF0gPSB4LmFtKDAsIHlbaV0sIHIsIGksIDAsIHgudClcbiAgci5zID0gMFxuICByLmNsYW1wKClcbiAgaWYgKHRoaXMucyAhPSBhLnMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcbmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpXG4gIHZhciBpID0gci50ID0gMiAqIHgudFxuICB3aGlsZSAoLS1pID49IDApIHJbaV0gPSAwXG4gIGZvciAoaSA9IDA7IGkgPCB4LnQgLSAxOyArK2kpIHtcbiAgICB2YXIgYyA9IHguYW0oaSwgeFtpXSwgciwgMiAqIGksIDAsIDEpXG4gICAgaWYgKChyW2kgKyB4LnRdICs9IHguYW0oaSArIDEsIDIgKiB4W2ldLCByLCAyICogaSArIDEsIGMsIHgudCAtIGkgLSAxKSkgPj0geC5EVikge1xuICAgICAgcltpICsgeC50XSAtPSB4LkRWXG4gICAgICByW2kgKyB4LnQgKyAxXSA9IDFcbiAgICB9XG4gIH1cbiAgaWYgKHIudCA+IDApIHJbci50IC0gMV0gKz0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSlcbiAgci5zID0gMFxuICByLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApXG4vLyByICE9IHEsIHRoaXMgIT0gbS4gIHEgb3IgciBtYXkgYmUgbnVsbC5cbmZ1bmN0aW9uIGJucERpdlJlbVRvKG0sIHEsIHIpIHtcbiAgdmFyIHNlbGYgPSB0aGlzXG4gIHZhciBwbSA9IG0uYWJzKClcbiAgaWYgKHBtLnQgPD0gMCkgcmV0dXJuXG4gIHZhciBwdCA9IHNlbGYuYWJzKClcbiAgaWYgKHB0LnQgPCBwbS50KSB7XG4gICAgaWYgKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApXG4gICAgaWYgKHIgIT0gbnVsbCkgc2VsZi5jb3B5VG8ocilcbiAgICByZXR1cm5cbiAgfVxuICBpZiAociA9PSBudWxsKSByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB2YXIgeSA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgdHMgPSBzZWxmLnMsXG4gICAgbXMgPSBtLnNcbiAgdmFyIG5zaCA9IHNlbGYuREIgLSBuYml0cyhwbVtwbS50IC0gMV0pOyAvLyBub3JtYWxpemUgbW9kdWx1c1xuICBpZiAobnNoID4gMCkge1xuICAgIHBtLmxTaGlmdFRvKG5zaCwgeSlcbiAgICBwdC5sU2hpZnRUbyhuc2gsIHIpXG4gIH0gZWxzZSB7XG4gICAgcG0uY29weVRvKHkpXG4gICAgcHQuY29weVRvKHIpXG4gIH1cbiAgdmFyIHlzID0geS50XG4gIHZhciB5MCA9IHlbeXMgLSAxXVxuICBpZiAoeTAgPT0gMCkgcmV0dXJuXG4gIHZhciB5dCA9IHkwICogKDEgPDwgc2VsZi5GMSkgKyAoKHlzID4gMSkgPyB5W3lzIC0gMl0gPj4gc2VsZi5GMiA6IDApXG4gIHZhciBkMSA9IHNlbGYuRlYgLyB5dCxcbiAgICBkMiA9ICgxIDw8IHNlbGYuRjEpIC8geXQsXG4gICAgZSA9IDEgPDwgc2VsZi5GMlxuICB2YXIgaSA9IHIudCxcbiAgICBqID0gaSAtIHlzLFxuICAgIHQgPSAocSA9PSBudWxsKSA/IG5ldyBCaWdJbnRlZ2VyKCkgOiBxXG4gIHkuZGxTaGlmdFRvKGosIHQpXG4gIGlmIChyLmNvbXBhcmVUbyh0KSA+PSAwKSB7XG4gICAgcltyLnQrK10gPSAxXG4gICAgci5zdWJUbyh0LCByKVxuICB9XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cywgdClcbiAgdC5zdWJUbyh5LCB5KTsgLy8gXCJuZWdhdGl2ZVwiIHkgc28gd2UgY2FuIHJlcGxhY2Ugc3ViIHdpdGggYW0gbGF0ZXJcbiAgd2hpbGUgKHkudCA8IHlzKSB5W3kudCsrXSA9IDBcbiAgd2hpbGUgKC0taiA+PSAwKSB7XG4gICAgLy8gRXN0aW1hdGUgcXVvdGllbnQgZGlnaXRcbiAgICB2YXIgcWQgPSAoclstLWldID09IHkwKSA/IHNlbGYuRE0gOiBNYXRoLmZsb29yKHJbaV0gKiBkMSArIChyW2kgLSAxXSArIGUpICogZDIpXG4gICAgaWYgKChyW2ldICs9IHkuYW0oMCwgcWQsIHIsIGosIDAsIHlzKSkgPCBxZCkgeyAvLyBUcnkgaXQgb3V0XG4gICAgICB5LmRsU2hpZnRUbyhqLCB0KVxuICAgICAgci5zdWJUbyh0LCByKVxuICAgICAgd2hpbGUgKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQsIHIpXG4gICAgfVxuICB9XG4gIGlmIChxICE9IG51bGwpIHtcbiAgICByLmRyU2hpZnRUbyh5cywgcSlcbiAgICBpZiAodHMgIT0gbXMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhxLCBxKVxuICB9XG4gIHIudCA9IHlzXG4gIHIuY2xhbXAoKVxuICBpZiAobnNoID4gMCkgci5yU2hpZnRUbyhuc2gsIHIpOyAvLyBEZW5vcm1hbGl6ZSByZW1haW5kZXJcbiAgaWYgKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgbW9kIGFcbmZ1bmN0aW9uIGJuTW9kKGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuYWJzKClcbiAgICAuZGl2UmVtVG8oYSwgbnVsbCwgcilcbiAgaWYgKHRoaXMucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIGEuc3ViVG8ociwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gTW9kdWxhciByZWR1Y3Rpb24gdXNpbmcgXCJjbGFzc2ljXCIgYWxnb3JpdGhtXG5mdW5jdGlvbiBDbGFzc2ljKG0pIHtcbiAgdGhpcy5tID0gbVxufVxuXG5mdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSlcbiAgZWxzZSByZXR1cm4geFxufVxuXG5mdW5jdGlvbiBjUmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHhcbn1cblxuZnVuY3Rpb24gY1JlZHVjZSh4KSB7XG4gIHguZGl2UmVtVG8odGhpcy5tLCBudWxsLCB4KVxufVxuXG5mdW5jdGlvbiBjTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuZnVuY3Rpb24gY1NxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5DbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnRcbkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnRcbkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2VcbkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvXG5DbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUb1xuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4gXCItMS90aGlzICUgMl5EQlwiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvblxuLy8ganVzdGlmaWNhdGlvbjpcbi8vICAgICAgICAgeHkgPT0gMSAobW9kIG0pXG4vLyAgICAgICAgIHh5ID0gIDEra21cbi8vICAgeHkoMi14eSkgPSAoMStrbSkoMS1rbSlcbi8vIHhbeSgyLXh5KV0gPSAxLWteMm1eMlxuLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKVxuLy8gaWYgeSBpcyAxL3ggbW9kIG0sIHRoZW4geSgyLXh5KSBpcyAxL3ggbW9kIG1eMlxuLy8gc2hvdWxkIHJlZHVjZSB4IGFuZCB5KDIteHkpIGJ5IG1eMiBhdCBlYWNoIHN0ZXAgdG8ga2VlcCBzaXplIGJvdW5kZWQuXG4vLyBKUyBtdWx0aXBseSBcIm92ZXJmbG93c1wiIGRpZmZlcmVudGx5IGZyb20gQy9DKyssIHNvIGNhcmUgaXMgbmVlZGVkIGhlcmUuXG5mdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgaWYgKHRoaXMudCA8IDEpIHJldHVybiAwXG4gIHZhciB4ID0gdGhpc1swXVxuICBpZiAoKHggJiAxKSA9PSAwKSByZXR1cm4gMFxuICB2YXIgeSA9IHggJiAzOyAvLyB5ID09IDEveCBtb2QgMl4yXG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGYpICogeSkpICYgMHhmOyAvLyB5ID09IDEveCBtb2QgMl40XG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGZmKSAqIHkpKSAmIDB4ZmY7IC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgeSA9ICh5ICogKDIgLSAoKCh4ICYgMHhmZmZmKSAqIHkpICYgMHhmZmZmKSkpICYgMHhmZmZmOyAvLyB5ID09IDEveCBtb2QgMl4xNlxuICAvLyBsYXN0IHN0ZXAgLSBjYWxjdWxhdGUgaW52ZXJzZSBtb2QgRFYgZGlyZWN0bHlcbiAgLy8gYXNzdW1lcyAxNiA8IERCIDw9IDMyIGFuZCBhc3N1bWVzIGFiaWxpdHkgdG8gaGFuZGxlIDQ4LWJpdCBpbnRzXG4gIHkgPSAoeSAqICgyIC0geCAqIHkgJSB0aGlzLkRWKSkgJSB0aGlzLkRWOyAvLyB5ID09IDEveCBtb2QgMl5kYml0c1xuICAvLyB3ZSByZWFsbHkgd2FudCB0aGUgbmVnYXRpdmUgaW52ZXJzZSwgYW5kIC1EViA8IHkgPCBEVlxuICByZXR1cm4gKHkgPiAwKSA/IHRoaXMuRFYgLSB5IDogLXlcbn1cblxuLy8gTW9udGdvbWVyeSByZWR1Y3Rpb25cbmZ1bmN0aW9uIE1vbnRnb21lcnkobSkge1xuICB0aGlzLm0gPSBtXG4gIHRoaXMubXAgPSBtLmludkRpZ2l0KClcbiAgdGhpcy5tcGwgPSB0aGlzLm1wICYgMHg3ZmZmXG4gIHRoaXMubXBoID0gdGhpcy5tcCA+PiAxNVxuICB0aGlzLnVtID0gKDEgPDwgKG0uREIgLSAxNSkpIC0gMVxuICB0aGlzLm10MiA9IDIgKiBtLnRcbn1cblxuLy8geFIgbW9kIG1cbmZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHguYWJzKClcbiAgICAuZGxTaGlmdFRvKHRoaXMubS50LCByKVxuICByLmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgcilcbiAgaWYgKHgucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIHRoaXMubS5zdWJUbyhyLCByKVxuICByZXR1cm4gclxufVxuXG4vLyB4L1IgbW9kIG1cbmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgeC5jb3B5VG8ocilcbiAgdGhpcy5yZWR1Y2UocilcbiAgcmV0dXJuIHJcbn1cblxuLy8geCA9IHgvUiBtb2QgbSAoSEFDIDE0LjMyKVxuZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gIHdoaWxlICh4LnQgPD0gdGhpcy5tdDIpIC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgIHhbeC50KytdID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubS50OyArK2kpIHtcbiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geFtpXSptcCBtb2QgRFZcbiAgICB2YXIgaiA9IHhbaV0gJiAweDdmZmZcbiAgICB2YXIgdTAgPSAoaiAqIHRoaXMubXBsICsgKCgoaiAqIHRoaXMubXBoICsgKHhbaV0gPj4gMTUpICogdGhpcy5tcGwpICYgdGhpcy51bSkgPDwgMTUpKSAmIHguRE1cbiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICBqID0gaSArIHRoaXMubS50XG4gICAgeFtqXSArPSB0aGlzLm0uYW0oMCwgdTAsIHgsIGksIDAsIHRoaXMubS50KVxuICAgIC8vIHByb3BhZ2F0ZSBjYXJyeVxuICAgIHdoaWxlICh4W2pdID49IHguRFYpIHtcbiAgICAgIHhbal0gLT0geC5EVlxuICAgICAgeFsrK2pdKytcbiAgICB9XG4gIH1cbiAgeC5jbGFtcCgpXG4gIHguZHJTaGlmdFRvKHRoaXMubS50LCB4KVxuICBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeClcbn1cblxuLy8gciA9IFwieF4yL1IgbW9kIG1cIjsgeCAhPSByXG5mdW5jdGlvbiBtb250U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbi8vIHIgPSBcInh5L1IgbW9kIG1cIjsgeCx5ICE9IHJcbmZ1bmN0aW9uIG1vbnRNdWxUbyh4LCB5LCByKSB7XG4gIHgubXVsdGlwbHlUbyh5LCByKVxuICB0aGlzLnJlZHVjZShyKVxufVxuXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0ID0gbW9udENvbnZlcnRcbk1vbnRnb21lcnkucHJvdG90eXBlLnJldmVydCA9IG1vbnRSZXZlcnRcbk1vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZSA9IG1vbnRSZWR1Y2Vcbk1vbnRnb21lcnkucHJvdG90eXBlLm11bFRvID0gbW9udE11bFRvXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5zcXJUbyA9IG1vbnRTcXJUb1xuXG4vLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW5cbmZ1bmN0aW9uIGJucElzRXZlbigpIHtcbiAgcmV0dXJuICgodGhpcy50ID4gMCkgPyAodGhpc1swXSAmIDEpIDogdGhpcy5zKSA9PSAwXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggXCJyXCIgKEhBQyAxNC43OSlcbmZ1bmN0aW9uIGJucEV4cChlLCB6KSB7XG4gIGlmIChlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FXG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKSxcbiAgICByMiA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgZyA9IHouY29udmVydCh0aGlzKSxcbiAgICBpID0gbmJpdHMoZSkgLSAxXG4gIGcuY29weVRvKHIpXG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHouc3FyVG8ociwgcjIpXG4gICAgaWYgKChlICYgKDEgPDwgaSkpID4gMCkgei5tdWxUbyhyMiwgZywgcilcbiAgICBlbHNlIHtcbiAgICAgIHZhciB0ID0gclxuICAgICAgciA9IHIyXG4gICAgICByMiA9IHRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpXG59XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0sIDAgPD0gZSA8IDJeMzJcbmZ1bmN0aW9uIGJuTW9kUG93SW50KGUsIG0pIHtcbiAgdmFyIHpcbiAgaWYgKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pXG4gIGVsc2UgeiA9IG5ldyBNb250Z29tZXJ5KG0pXG4gIHJldHVybiB0aGlzLmV4cChlLCB6KVxufVxuXG4vLyBwcm90ZWN0ZWRcbnByb3RvLmNvcHlUbyA9IGJucENvcHlUb1xucHJvdG8uZnJvbUludCA9IGJucEZyb21JbnRcbnByb3RvLmZyb21TdHJpbmcgPSBibnBGcm9tU3RyaW5nXG5wcm90by5jbGFtcCA9IGJucENsYW1wXG5wcm90by5kbFNoaWZ0VG8gPSBibnBETFNoaWZ0VG9cbnByb3RvLmRyU2hpZnRUbyA9IGJucERSU2hpZnRUb1xucHJvdG8ubFNoaWZ0VG8gPSBibnBMU2hpZnRUb1xucHJvdG8uclNoaWZ0VG8gPSBibnBSU2hpZnRUb1xucHJvdG8uc3ViVG8gPSBibnBTdWJUb1xucHJvdG8ubXVsdGlwbHlUbyA9IGJucE11bHRpcGx5VG9cbnByb3RvLnNxdWFyZVRvID0gYm5wU3F1YXJlVG9cbnByb3RvLmRpdlJlbVRvID0gYm5wRGl2UmVtVG9cbnByb3RvLmludkRpZ2l0ID0gYm5wSW52RGlnaXRcbnByb3RvLmlzRXZlbiA9IGJucElzRXZlblxucHJvdG8uZXhwID0gYm5wRXhwXG5cbi8vIHB1YmxpY1xucHJvdG8udG9TdHJpbmcgPSBiblRvU3RyaW5nXG5wcm90by5uZWdhdGUgPSBibk5lZ2F0ZVxucHJvdG8uYWJzID0gYm5BYnNcbnByb3RvLmNvbXBhcmVUbyA9IGJuQ29tcGFyZVRvXG5wcm90by5iaXRMZW5ndGggPSBibkJpdExlbmd0aFxucHJvdG8uYnl0ZUxlbmd0aCA9IGJuQnl0ZUxlbmd0aFxucHJvdG8ubW9kID0gYm5Nb2RcbnByb3RvLm1vZFBvd0ludCA9IGJuTW9kUG93SW50XG5cbi8vIChwdWJsaWMpXG5mdW5jdGlvbiBibkNsb25lKCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5jb3B5VG8ocilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGludGVnZXJcbmZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7XG4gIGlmICh0aGlzLnMgPCAwKSB7XG4gICAgaWYgKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpc1swXSAtIHRoaXMuRFZcbiAgICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIC0xXG4gIH0gZWxzZSBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdXG4gIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gMFxuICAvLyBhc3N1bWVzIDE2IDwgREIgPCAzMlxuICByZXR1cm4gKCh0aGlzWzFdICYgKCgxIDw8ICgzMiAtIHRoaXMuREIpKSAtIDEpKSA8PCB0aGlzLkRCKSB8IHRoaXNbMF1cbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGVcbmZ1bmN0aW9uIGJuQnl0ZVZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDI0KSA+PiAyNFxufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCkge1xuICByZXR1cm4gKHRoaXMudCA9PSAwKSA/IHRoaXMucyA6ICh0aGlzWzBdIDw8IDE2KSA+PiAxNlxufVxuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWXG5mdW5jdGlvbiBibnBDaHVua1NpemUocikge1xuICByZXR1cm4gTWF0aC5mbG9vcihNYXRoLkxOMiAqIHRoaXMuREIgLyBNYXRoLmxvZyhyKSlcbn1cblxuLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDBcbmZ1bmN0aW9uIGJuU2lnTnVtKCkge1xuICBpZiAodGhpcy5zIDwgMCkgcmV0dXJuIC0xXG4gIGVsc2UgaWYgKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMFxuICBlbHNlIHJldHVybiAxXG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgdG8gcmFkaXggc3RyaW5nXG5mdW5jdGlvbiBibnBUb1JhZGl4KGIpIHtcbiAgaWYgKGIgPT0gbnVsbCkgYiA9IDEwXG4gIGlmICh0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gXCIwXCJcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYilcbiAgdmFyIGEgPSBNYXRoLnBvdyhiLCBjcylcbiAgdmFyIGQgPSBuYnYoYSksXG4gICAgeSA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgeiA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgciA9IFwiXCJcbiAgdGhpcy5kaXZSZW1UbyhkLCB5LCB6KVxuICB3aGlsZSAoeS5zaWdudW0oKSA+IDApIHtcbiAgICByID0gKGEgKyB6LmludFZhbHVlKCkpXG4gICAgICAudG9TdHJpbmcoYilcbiAgICAgIC5zdWJzdHIoMSkgKyByXG4gICAgeS5kaXZSZW1UbyhkLCB5LCB6KVxuICB9XG4gIHJldHVybiB6LmludFZhbHVlKClcbiAgICAudG9TdHJpbmcoYikgKyByXG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmdcbmZ1bmN0aW9uIGJucEZyb21SYWRpeChzLCBiKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBzZWxmLmZyb21JbnQoMClcbiAgaWYgKGIgPT0gbnVsbCkgYiA9IDEwXG4gIHZhciBjcyA9IHNlbGYuY2h1bmtTaXplKGIpXG4gIHZhciBkID0gTWF0aC5wb3coYiwgY3MpLFxuICAgIG1pID0gZmFsc2UsXG4gICAgaiA9IDAsXG4gICAgdyA9IDBcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHggPSBpbnRBdChzLCBpKVxuICAgIGlmICh4IDwgMCkge1xuICAgICAgaWYgKHMuY2hhckF0KGkpID09IFwiLVwiICYmIHNlbGYuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICB3ID0gYiAqIHcgKyB4XG4gICAgaWYgKCsraiA+PSBjcykge1xuICAgICAgc2VsZi5kTXVsdGlwbHkoZClcbiAgICAgIHNlbGYuZEFkZE9mZnNldCh3LCAwKVxuICAgICAgaiA9IDBcbiAgICAgIHcgPSAwXG4gICAgfVxuICB9XG4gIGlmIChqID4gMCkge1xuICAgIHNlbGYuZE11bHRpcGx5KE1hdGgucG93KGIsIGopKVxuICAgIHNlbGYuZEFkZE9mZnNldCh3LCAwKVxuICB9XG4gIGlmIChtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHNlbGYsIHNlbGYpXG59XG5cbi8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3RvclxuZnVuY3Rpb24gYm5wRnJvbU51bWJlcihhLCBiLCBjKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICBpZiAoXCJudW1iZXJcIiA9PSB0eXBlb2YgYikge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKVxuICAgIGlmIChhIDwgMikgc2VsZi5mcm9tSW50KDEpXG4gICAgZWxzZSB7XG4gICAgICBzZWxmLmZyb21OdW1iZXIoYSwgYylcbiAgICAgIGlmICghc2VsZi50ZXN0Qml0KGEgLSAxKSkgLy8gZm9yY2UgTVNCIHNldFxuICAgICAgICBzZWxmLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYSAtIDEpLCBvcF9vciwgc2VsZilcbiAgICAgIGlmIChzZWxmLmlzRXZlbigpKSBzZWxmLmRBZGRPZmZzZXQoMSwgMCk7IC8vIGZvcmNlIG9kZFxuICAgICAgd2hpbGUgKCFzZWxmLmlzUHJvYmFibGVQcmltZShiKSkge1xuICAgICAgICBzZWxmLmRBZGRPZmZzZXQoMiwgMClcbiAgICAgICAgaWYgKHNlbGYuYml0TGVuZ3RoKCkgPiBhKSBzZWxmLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhIC0gMSksIHNlbGYpXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgdmFyIHggPSBuZXcgQXJyYXkoKSxcbiAgICAgIHQgPSBhICYgN1xuICAgIHgubGVuZ3RoID0gKGEgPj4gMykgKyAxXG4gICAgYi5uZXh0Qnl0ZXMoeClcbiAgICBpZiAodCA+IDApIHhbMF0gJj0gKCgxIDw8IHQpIC0gMSlcbiAgICBlbHNlIHhbMF0gPSAwXG4gICAgc2VsZi5mcm9tU3RyaW5nKHgsIDI1NilcbiAgfVxufVxuXG4vLyAocHVibGljKSBjb252ZXJ0IHRvIGJpZ2VuZGlhbiBieXRlIGFycmF5XG5mdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgdmFyIGkgPSBzZWxmLnQsXG4gICAgciA9IG5ldyBBcnJheSgpXG4gIHJbMF0gPSBzZWxmLnNcbiAgdmFyIHAgPSBzZWxmLkRCIC0gKGkgKiBzZWxmLkRCKSAlIDgsXG4gICAgZCwgayA9IDBcbiAgaWYgKGktLSA+IDApIHtcbiAgICBpZiAocCA8IHNlbGYuREIgJiYgKGQgPSBzZWxmW2ldID4+IHApICE9IChzZWxmLnMgJiBzZWxmLkRNKSA+PiBwKVxuICAgICAgcltrKytdID0gZCB8IChzZWxmLnMgPDwgKHNlbGYuREIgLSBwKSlcbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IDgpIHtcbiAgICAgICAgZCA9IChzZWxmW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8ICg4IC0gcClcbiAgICAgICAgZCB8PSBzZWxmWy0taV0gPj4gKHAgKz0gc2VsZi5EQiAtIDgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkID0gKHNlbGZbaV0gPj4gKHAgLT0gOCkpICYgMHhmZlxuICAgICAgICBpZiAocCA8PSAwKSB7XG4gICAgICAgICAgcCArPSBzZWxmLkRCXG4gICAgICAgICAgLS1pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICgoZCAmIDB4ODApICE9IDApIGQgfD0gLTI1NlxuICAgICAgaWYgKGsgPT09IDAgJiYgKHNlbGYucyAmIDB4ODApICE9IChkICYgMHg4MCkpKytrXG4gICAgICBpZiAoayA+IDAgfHwgZCAhPSBzZWxmLnMpIHJbaysrXSA9IGRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuZnVuY3Rpb24gYm5FcXVhbHMoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID09IDApXG59XG5cbmZ1bmN0aW9uIGJuTWluKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA8IDApID8gdGhpcyA6IGFcbn1cblxuZnVuY3Rpb24gYm5NYXgoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID4gMCkgPyB0aGlzIDogYVxufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyBvcCBhIChiaXR3aXNlKVxuZnVuY3Rpb24gYm5wQml0d2lzZVRvKGEsIG9wLCByKSB7XG4gIHZhciBzZWxmID0gdGhpc1xuICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCwgc2VsZi50KVxuICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3Aoc2VsZltpXSwgYVtpXSlcbiAgaWYgKGEudCA8IHNlbGYudCkge1xuICAgIGYgPSBhLnMgJiBzZWxmLkRNXG4gICAgZm9yIChpID0gbTsgaSA8IHNlbGYudDsgKytpKSByW2ldID0gb3Aoc2VsZltpXSwgZilcbiAgICByLnQgPSBzZWxmLnRcbiAgfSBlbHNlIHtcbiAgICBmID0gc2VsZi5zICYgc2VsZi5ETVxuICAgIGZvciAoaSA9IG07IGkgPCBhLnQ7ICsraSkgcltpXSA9IG9wKGYsIGFbaV0pXG4gICAgci50ID0gYS50XG4gIH1cbiAgci5zID0gb3Aoc2VsZi5zLCBhLnMpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHVibGljKSB0aGlzICYgYVxuZnVuY3Rpb24gb3BfYW5kKHgsIHkpIHtcbiAgcmV0dXJuIHggJiB5XG59XG5cbmZ1bmN0aW9uIGJuQW5kKGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX2FuZCwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyB8IGFcbmZ1bmN0aW9uIG9wX29yKHgsIHkpIHtcbiAgcmV0dXJuIHggfCB5XG59XG5cbmZ1bmN0aW9uIGJuT3IoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3Bfb3IsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiBhXG5mdW5jdGlvbiBvcF94b3IoeCwgeSkge1xuICByZXR1cm4geCBeIHlcbn1cblxuZnVuY3Rpb24gYm5Yb3IoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfeG9yLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzICYgfmFcbmZ1bmN0aW9uIG9wX2FuZG5vdCh4LCB5KSB7XG4gIHJldHVybiB4ICYgfnlcbn1cblxuZnVuY3Rpb24gYm5BbmROb3QoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kbm90LCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB+dGhpc1xuZnVuY3Rpb24gYm5Ob3QoKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSAmIH50aGlzW2ldXG4gIHIudCA9IHRoaXMudFxuICByLnMgPSB+dGhpcy5zXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPDwgblxuZnVuY3Rpb24gYm5TaGlmdExlZnQobikge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgaWYgKG4gPCAwKSB0aGlzLnJTaGlmdFRvKC1uLCByKVxuICBlbHNlIHRoaXMubFNoaWZ0VG8obiwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdGhpcyA+PiBuXG5mdW5jdGlvbiBiblNoaWZ0UmlnaHQobikge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgaWYgKG4gPCAwKSB0aGlzLmxTaGlmdFRvKC1uLCByKVxuICBlbHNlIHRoaXMuclNoaWZ0VG8obiwgcilcbiAgcmV0dXJuIHJcbn1cblxuLy8gcmV0dXJuIGluZGV4IG9mIGxvd2VzdCAxLWJpdCBpbiB4LCB4IDwgMl4zMVxuZnVuY3Rpb24gbGJpdCh4KSB7XG4gIGlmICh4ID09IDApIHJldHVybiAtMVxuICB2YXIgciA9IDBcbiAgaWYgKCh4ICYgMHhmZmZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gMTZcbiAgICByICs9IDE2XG4gIH1cbiAgaWYgKCh4ICYgMHhmZikgPT0gMCkge1xuICAgIHggPj49IDhcbiAgICByICs9IDhcbiAgfVxuICBpZiAoKHggJiAweGYpID09IDApIHtcbiAgICB4ID4+PSA0XG4gICAgciArPSA0XG4gIH1cbiAgaWYgKCh4ICYgMykgPT0gMCkge1xuICAgIHggPj49IDJcbiAgICByICs9IDJcbiAgfVxuICBpZiAoKHggJiAxKSA9PSAwKSsrclxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSByZXR1cm5zIGluZGV4IG9mIGxvd2VzdCAxLWJpdCAob3IgLTEgaWYgbm9uZSlcbmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKVxuICAgIGlmICh0aGlzW2ldICE9IDApIHJldHVybiBpICogdGhpcy5EQiArIGxiaXQodGhpc1tpXSlcbiAgaWYgKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQgKiB0aGlzLkRCXG4gIHJldHVybiAtMVxufVxuXG4vLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG5mdW5jdGlvbiBjYml0KHgpIHtcbiAgdmFyIHIgPSAwXG4gIHdoaWxlICh4ICE9IDApIHtcbiAgICB4ICY9IHggLSAxXG4gICAgKytyXG4gIH1cbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuZnVuY3Rpb24gYm5CaXRDb3VudCgpIHtcbiAgdmFyIHIgPSAwLFxuICAgIHggPSB0aGlzLnMgJiB0aGlzLkRNXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldIF4geClcbiAgcmV0dXJuIHJcbn1cblxuLy8gKHB1YmxpYykgdHJ1ZSBpZmYgbnRoIGJpdCBpcyBzZXRcbmZ1bmN0aW9uIGJuVGVzdEJpdChuKSB7XG4gIHZhciBqID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQilcbiAgaWYgKGogPj0gdGhpcy50KSByZXR1cm4gKHRoaXMucyAhPSAwKVxuICByZXR1cm4gKCh0aGlzW2pdICYgKDEgPDwgKG4gJSB0aGlzLkRCKSkpICE9IDApXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgb3AgKDE8PG4pXG5mdW5jdGlvbiBibnBDaGFuZ2VCaXQobiwgb3ApIHtcbiAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobilcbiAgdGhpcy5iaXR3aXNlVG8ociwgb3AsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcbmZ1bmN0aW9uIGJuU2V0Qml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX29yKVxufVxuXG4vLyAocHVibGljKSB0aGlzICYgfigxPDxuKVxuZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF9hbmRub3QpXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiAoMTw8bilcbmZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7XG4gIHJldHVybiB0aGlzLmNoYW5nZUJpdChuLCBvcF94b3IpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuZnVuY3Rpb24gYm5wQWRkVG8oYSwgcikge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICB2YXIgaSA9IDAsXG4gICAgYyA9IDAsXG4gICAgbSA9IE1hdGgubWluKGEudCwgc2VsZi50KVxuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHNlbGZbaV0gKyBhW2ldXG4gICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICBjID4+PSBzZWxmLkRCXG4gIH1cbiAgaWYgKGEudCA8IHNlbGYudCkge1xuICAgIGMgKz0gYS5zXG4gICAgd2hpbGUgKGkgPCBzZWxmLnQpIHtcbiAgICAgIGMgKz0gc2VsZltpXVxuICAgICAgcltpKytdID0gYyAmIHNlbGYuRE1cbiAgICAgIGMgPj49IHNlbGYuREJcbiAgICB9XG4gICAgYyArPSBzZWxmLnNcbiAgfSBlbHNlIHtcbiAgICBjICs9IHNlbGYuc1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjICs9IGFbaV1cbiAgICAgIHJbaSsrXSA9IGMgJiBzZWxmLkRNXG4gICAgICBjID4+PSBzZWxmLkRCXG4gICAgfVxuICAgIGMgKz0gYS5zXG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMFxuICBpZiAoYyA+IDApIHJbaSsrXSA9IGNcbiAgZWxzZSBpZiAoYyA8IC0xKSByW2krK10gPSBzZWxmLkRWICsgY1xuICByLnQgPSBpXG4gIHIuY2xhbXAoKVxufVxuXG4vLyAocHVibGljKSB0aGlzICsgYVxuZnVuY3Rpb24gYm5BZGQoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5hZGRUbyhhLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzIC0gYVxuZnVuY3Rpb24gYm5TdWJ0cmFjdChhKSB7XG4gIHZhciByID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLnN1YlRvKGEsIHIpXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKiBhXG5mdW5jdGlvbiBibk11bHRpcGx5KGEpIHtcbiAgdmFyIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMubXVsdGlwbHlUbyhhLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzXjJcbmZ1bmN0aW9uIGJuU3F1YXJlKCkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5zcXVhcmVUbyhyKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzIC8gYVxuZnVuY3Rpb24gYm5EaXZpZGUoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5kaXZSZW1UbyhhLCByLCBudWxsKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSB0aGlzICUgYVxuZnVuY3Rpb24gYm5SZW1haW5kZXIoYSkge1xuICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgdGhpcy5kaXZSZW1UbyhhLCBudWxsLCByKVxuICByZXR1cm4gclxufVxuXG4vLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV1cbmZ1bmN0aW9uIGJuRGl2aWRlQW5kUmVtYWluZGVyKGEpIHtcbiAgdmFyIHEgPSBuZXcgQmlnSW50ZWdlcigpLFxuICAgIHIgPSBuZXcgQmlnSW50ZWdlcigpXG4gIHRoaXMuZGl2UmVtVG8oYSwgcSwgcilcbiAgcmV0dXJuIG5ldyBBcnJheShxLCByKVxufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVlxuZnVuY3Rpb24gYm5wRE11bHRpcGx5KG4pIHtcbiAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLCBuIC0gMSwgdGhpcywgMCwgMCwgdGhpcy50KVxuICArK3RoaXMudFxuICB0aGlzLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuZnVuY3Rpb24gYm5wREFkZE9mZnNldChuLCB3KSB7XG4gIGlmIChuID09IDApIHJldHVyblxuICB3aGlsZSAodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMFxuICB0aGlzW3ddICs9IG5cbiAgd2hpbGUgKHRoaXNbd10gPj0gdGhpcy5EVikge1xuICAgIHRoaXNbd10gLT0gdGhpcy5EVlxuICAgIGlmICgrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDBcbiAgICArK3RoaXNbd11cbiAgfVxufVxuXG4vLyBBIFwibnVsbFwiIHJlZHVjZXJcbmZ1bmN0aW9uIE51bGxFeHAoKSB7fVxuXG5mdW5jdGlvbiBuTm9wKHgpIHtcbiAgcmV0dXJuIHhcbn1cblxuZnVuY3Rpb24gbk11bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpXG59XG5cbmZ1bmN0aW9uIG5TcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocilcbn1cblxuTnVsbEV4cC5wcm90b3R5cGUuY29udmVydCA9IG5Ob3Bcbk51bGxFeHAucHJvdG90eXBlLnJldmVydCA9IG5Ob3Bcbk51bGxFeHAucHJvdG90eXBlLm11bFRvID0gbk11bFRvXG5OdWxsRXhwLnByb3RvdHlwZS5zcXJUbyA9IG5TcXJUb1xuXG4vLyAocHVibGljKSB0aGlzXmVcbmZ1bmN0aW9uIGJuUG93KGUpIHtcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIG5ldyBOdWxsRXhwKCkpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mIFwidGhpcyAqIGFcIiwgYS50IDw9IG5cbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5TG93ZXJUbyhhLCBuLCByKSB7XG4gIHZhciBpID0gTWF0aC5taW4odGhpcy50ICsgYS50LCBuKVxuICByLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwXG4gIHIudCA9IGlcbiAgd2hpbGUgKGkgPiAwKSByWy0taV0gPSAwXG4gIHZhciBqXG4gIGZvciAoaiA9IHIudCAtIHRoaXMudDsgaSA8IGo7ICsraSkgcltpICsgdGhpcy50XSA9IHRoaXMuYW0oMCwgYVtpXSwgciwgaSwgMCwgdGhpcy50KVxuICBmb3IgKGogPSBNYXRoLm1pbihhLnQsIG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsIGFbaV0sIHIsIGksIDAsIG4gLSBpKVxuICByLmNsYW1wKClcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IFwidGhpcyAqIGFcIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5mdW5jdGlvbiBibnBNdWx0aXBseVVwcGVyVG8oYSwgbiwgcikge1xuICAtLW5cbiAgdmFyIGkgPSByLnQgPSB0aGlzLnQgKyBhLnQgLSBuXG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMFxuICBmb3IgKGkgPSBNYXRoLm1heChuIC0gdGhpcy50LCAwKTsgaSA8IGEudDsgKytpKVxuICAgIHJbdGhpcy50ICsgaSAtIG5dID0gdGhpcy5hbShuIC0gaSwgYVtpXSwgciwgMCwgMCwgdGhpcy50ICsgaSAtIG4pXG4gIHIuY2xhbXAoKVxuICByLmRyU2hpZnRUbygxLCByKVxufVxuXG4vLyBCYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uXG5mdW5jdGlvbiBCYXJyZXR0KG0pIHtcbiAgLy8gc2V0dXAgQmFycmV0dFxuICB0aGlzLnIyID0gbmV3IEJpZ0ludGVnZXIoKVxuICB0aGlzLnEzID0gbmV3IEJpZ0ludGVnZXIoKVxuICBCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oMiAqIG0udCwgdGhpcy5yMilcbiAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pXG4gIHRoaXMubSA9IG1cbn1cblxuZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoeCkge1xuICBpZiAoeC5zIDwgMCB8fCB4LnQgPiAyICogdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pXG4gIGVsc2UgaWYgKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geFxuICBlbHNlIHtcbiAgICB2YXIgciA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgICB4LmNvcHlUbyhyKVxuICAgIHRoaXMucmVkdWNlKHIpXG4gICAgcmV0dXJuIHJcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXJyZXR0UmV2ZXJ0KHgpIHtcbiAgcmV0dXJuIHhcbn1cblxuLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcbmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkge1xuICB2YXIgc2VsZiA9IHRoaXNcbiAgeC5kclNoaWZ0VG8oc2VsZi5tLnQgLSAxLCBzZWxmLnIyKVxuICBpZiAoeC50ID4gc2VsZi5tLnQgKyAxKSB7XG4gICAgeC50ID0gc2VsZi5tLnQgKyAxXG4gICAgeC5jbGFtcCgpXG4gIH1cbiAgc2VsZi5tdS5tdWx0aXBseVVwcGVyVG8oc2VsZi5yMiwgc2VsZi5tLnQgKyAxLCBzZWxmLnEzKVxuICBzZWxmLm0ubXVsdGlwbHlMb3dlclRvKHNlbGYucTMsIHNlbGYubS50ICsgMSwgc2VsZi5yMilcbiAgd2hpbGUgKHguY29tcGFyZVRvKHNlbGYucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsIHNlbGYubS50ICsgMSlcbiAgeC5zdWJUbyhzZWxmLnIyLCB4KVxuICB3aGlsZSAoeC5jb21wYXJlVG8oc2VsZi5tKSA+PSAwKSB4LnN1YlRvKHNlbGYubSwgeClcbn1cblxuLy8gciA9IHheMiBtb2QgbTsgeCAhPSByXG5mdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpXG4gIHRoaXMucmVkdWNlKHIpXG59XG5cbi8vIHIgPSB4KnkgbW9kIG07IHgseSAhPSByXG5mdW5jdGlvbiBiYXJyZXR0TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcilcbiAgdGhpcy5yZWR1Y2Uocilcbn1cblxuQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0XG5CYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0XG5CYXJyZXR0LnByb3RvdHlwZS5yZWR1Y2UgPSBiYXJyZXR0UmVkdWNlXG5CYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUb1xuQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG9cblxuLy8gKHB1YmxpYykgdGhpc15lICUgbSAoSEFDIDE0Ljg1KVxuZnVuY3Rpb24gYm5Nb2RQb3coZSwgbSkge1xuICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksXG4gICAgaywgciA9IG5idigxKSxcbiAgICB6XG4gIGlmIChpIDw9IDApIHJldHVybiByXG4gIGVsc2UgaWYgKGkgPCAxOCkgayA9IDFcbiAgZWxzZSBpZiAoaSA8IDQ4KSBrID0gM1xuICBlbHNlIGlmIChpIDwgMTQ0KSBrID0gNFxuICBlbHNlIGlmIChpIDwgNzY4KSBrID0gNVxuICBlbHNlIGsgPSA2XG4gIGlmIChpIDwgOClcbiAgICB6ID0gbmV3IENsYXNzaWMobSlcbiAgZWxzZSBpZiAobS5pc0V2ZW4oKSlcbiAgICB6ID0gbmV3IEJhcnJldHQobSlcbiAgZWxzZVxuICAgIHogPSBuZXcgTW9udGdvbWVyeShtKVxuXG4gIC8vIHByZWNvbXB1dGF0aW9uXG4gIHZhciBnID0gbmV3IEFycmF5KCksXG4gICAgbiA9IDMsXG4gICAgazEgPSBrIC0gMSxcbiAgICBrbSA9ICgxIDw8IGspIC0gMVxuICBnWzFdID0gei5jb252ZXJ0KHRoaXMpXG4gIGlmIChrID4gMSkge1xuICAgIHZhciBnMiA9IG5ldyBCaWdJbnRlZ2VyKClcbiAgICB6LnNxclRvKGdbMV0sIGcyKVxuICAgIHdoaWxlIChuIDw9IGttKSB7XG4gICAgICBnW25dID0gbmV3IEJpZ0ludGVnZXIoKVxuICAgICAgei5tdWxUbyhnMiwgZ1tuIC0gMl0sIGdbbl0pXG4gICAgICBuICs9IDJcbiAgICB9XG4gIH1cblxuICB2YXIgaiA9IGUudCAtIDEsXG4gICAgdywgaXMxID0gdHJ1ZSxcbiAgICByMiA9IG5ldyBCaWdJbnRlZ2VyKCksXG4gICAgdFxuICBpID0gbmJpdHMoZVtqXSkgLSAxXG4gIHdoaWxlIChqID49IDApIHtcbiAgICBpZiAoaSA+PSBrMSkgdyA9IChlW2pdID4+IChpIC0gazEpKSAmIGttXG4gICAgZWxzZSB7XG4gICAgICB3ID0gKGVbal0gJiAoKDEgPDwgKGkgKyAxKSkgLSAxKSkgPDwgKGsxIC0gaSlcbiAgICAgIGlmIChqID4gMCkgdyB8PSBlW2ogLSAxXSA+PiAodGhpcy5EQiArIGkgLSBrMSlcbiAgICB9XG5cbiAgICBuID0ga1xuICAgIHdoaWxlICgodyAmIDEpID09IDApIHtcbiAgICAgIHcgPj49IDFcbiAgICAgIC0tblxuICAgIH1cbiAgICBpZiAoKGkgLT0gbikgPCAwKSB7XG4gICAgICBpICs9IHRoaXMuREJcbiAgICAgIC0talxuICAgIH1cbiAgICBpZiAoaXMxKSB7IC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXRcbiAgICAgIGdbd10uY29weVRvKHIpXG4gICAgICBpczEgPSBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAobiA+IDEpIHtcbiAgICAgICAgei5zcXJUbyhyLCByMilcbiAgICAgICAgei5zcXJUbyhyMiwgcilcbiAgICAgICAgbiAtPSAyXG4gICAgICB9XG4gICAgICBpZiAobiA+IDApIHouc3FyVG8ociwgcjIpXG4gICAgICBlbHNlIHtcbiAgICAgICAgdCA9IHJcbiAgICAgICAgciA9IHIyXG4gICAgICAgIHIyID0gdFxuICAgICAgfVxuICAgICAgei5tdWxUbyhyMiwgZ1t3XSwgcilcbiAgICB9XG5cbiAgICB3aGlsZSAoaiA+PSAwICYmIChlW2pdICYgKDEgPDwgaSkpID09IDApIHtcbiAgICAgIHouc3FyVG8ociwgcjIpXG4gICAgICB0ID0gclxuICAgICAgciA9IHIyXG4gICAgICByMiA9IHRcbiAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgIGkgPSB0aGlzLkRCIC0gMVxuICAgICAgICAtLWpcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpXG59XG5cbi8vIChwdWJsaWMpIGdjZCh0aGlzLGEpIChIQUMgMTQuNTQpXG5mdW5jdGlvbiBibkdDRChhKSB7XG4gIHZhciB4ID0gKHRoaXMucyA8IDApID8gdGhpcy5uZWdhdGUoKSA6IHRoaXMuY2xvbmUoKVxuICB2YXIgeSA9IChhLnMgPCAwKSA/IGEubmVnYXRlKCkgOiBhLmNsb25lKClcbiAgaWYgKHguY29tcGFyZVRvKHkpIDwgMCkge1xuICAgIHZhciB0ID0geFxuICAgIHggPSB5XG4gICAgeSA9IHRcbiAgfVxuICB2YXIgaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCksXG4gICAgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KClcbiAgaWYgKGcgPCAwKSByZXR1cm4geFxuICBpZiAoaSA8IGcpIGcgPSBpXG4gIGlmIChnID4gMCkge1xuICAgIHguclNoaWZ0VG8oZywgeClcbiAgICB5LnJTaGlmdFRvKGcsIHkpXG4gIH1cbiAgd2hpbGUgKHguc2lnbnVtKCkgPiAwKSB7XG4gICAgaWYgKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGksIHgpXG4gICAgaWYgKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGksIHkpXG4gICAgaWYgKHguY29tcGFyZVRvKHkpID49IDApIHtcbiAgICAgIHguc3ViVG8oeSwgeClcbiAgICAgIHguclNoaWZ0VG8oMSwgeClcbiAgICB9IGVsc2Uge1xuICAgICAgeS5zdWJUbyh4LCB5KVxuICAgICAgeS5yU2hpZnRUbygxLCB5KVxuICAgIH1cbiAgfVxuICBpZiAoZyA+IDApIHkubFNoaWZ0VG8oZywgeSlcbiAgcmV0dXJuIHlcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyAlIG4sIG4gPCAyXjI2XG5mdW5jdGlvbiBibnBNb2RJbnQobikge1xuICBpZiAobiA8PSAwKSByZXR1cm4gMFxuICB2YXIgZCA9IHRoaXMuRFYgJSBuLFxuICAgIHIgPSAodGhpcy5zIDwgMCkgPyBuIC0gMSA6IDBcbiAgaWYgKHRoaXMudCA+IDApXG4gICAgaWYgKGQgPT0gMCkgciA9IHRoaXNbMF0gJSBuXG4gICAgZWxzZVxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudCAtIDE7IGkgPj0gMDsgLS1pKSByID0gKGQgKiByICsgdGhpc1tpXSkgJSBuXG4gIHJldHVybiByXG59XG5cbi8vIChwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSlcbmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gIHZhciBhYyA9IG0uaXNFdmVuKClcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT09IDApIHRocm93IG5ldyBFcnJvcignZGl2aXNpb24gYnkgemVybycpXG4gIGlmICgodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPXG4gIHZhciB1ID0gbS5jbG9uZSgpLFxuICAgIHYgPSB0aGlzLmNsb25lKClcbiAgdmFyIGEgPSBuYnYoMSksXG4gICAgYiA9IG5idigwKSxcbiAgICBjID0gbmJ2KDApLFxuICAgIGQgPSBuYnYoMSlcbiAgd2hpbGUgKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgIHdoaWxlICh1LmlzRXZlbigpKSB7XG4gICAgICB1LnJTaGlmdFRvKDEsIHUpXG4gICAgICBpZiAoYWMpIHtcbiAgICAgICAgaWYgKCFhLmlzRXZlbigpIHx8ICFiLmlzRXZlbigpKSB7XG4gICAgICAgICAgYS5hZGRUbyh0aGlzLCBhKVxuICAgICAgICAgIGIuc3ViVG8obSwgYilcbiAgICAgICAgfVxuICAgICAgICBhLnJTaGlmdFRvKDEsIGEpXG4gICAgICB9IGVsc2UgaWYgKCFiLmlzRXZlbigpKSBiLnN1YlRvKG0sIGIpXG4gICAgICBiLnJTaGlmdFRvKDEsIGIpXG4gICAgfVxuICAgIHdoaWxlICh2LmlzRXZlbigpKSB7XG4gICAgICB2LnJTaGlmdFRvKDEsIHYpXG4gICAgICBpZiAoYWMpIHtcbiAgICAgICAgaWYgKCFjLmlzRXZlbigpIHx8ICFkLmlzRXZlbigpKSB7XG4gICAgICAgICAgYy5hZGRUbyh0aGlzLCBjKVxuICAgICAgICAgIGQuc3ViVG8obSwgZClcbiAgICAgICAgfVxuICAgICAgICBjLnJTaGlmdFRvKDEsIGMpXG4gICAgICB9IGVsc2UgaWYgKCFkLmlzRXZlbigpKSBkLnN1YlRvKG0sIGQpXG4gICAgICBkLnJTaGlmdFRvKDEsIGQpXG4gICAgfVxuICAgIGlmICh1LmNvbXBhcmVUbyh2KSA+PSAwKSB7XG4gICAgICB1LnN1YlRvKHYsIHUpXG4gICAgICBpZiAoYWMpIGEuc3ViVG8oYywgYSlcbiAgICAgIGIuc3ViVG8oZCwgYilcbiAgICB9IGVsc2Uge1xuICAgICAgdi5zdWJUbyh1LCB2KVxuICAgICAgaWYgKGFjKSBjLnN1YlRvKGEsIGMpXG4gICAgICBkLnN1YlRvKGIsIGQpXG4gICAgfVxuICB9XG4gIGlmICh2LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVST1xuICB3aGlsZSAoZC5jb21wYXJlVG8obSkgPj0gMCkgZC5zdWJUbyhtLCBkKVxuICB3aGlsZSAoZC5zaWdudW0oKSA8IDApIGQuYWRkVG8obSwgZClcbiAgcmV0dXJuIGRcbn1cblxudmFyIGxvd3ByaW1lcyA9IFtcbiAgMiwgMywgNSwgNywgMTEsIDEzLCAxNywgMTksIDIzLCAyOSwgMzEsIDM3LCA0MSwgNDMsIDQ3LCA1MywgNTksIDYxLCA2NywgNzEsXG4gIDczLCA3OSwgODMsIDg5LCA5NywgMTAxLCAxMDMsIDEwNywgMTA5LCAxMTMsIDEyNywgMTMxLCAxMzcsIDEzOSwgMTQ5LCAxNTEsXG4gIDE1NywgMTYzLCAxNjcsIDE3MywgMTc5LCAxODEsIDE5MSwgMTkzLCAxOTcsIDE5OSwgMjExLCAyMjMsIDIyNywgMjI5LCAyMzMsXG4gIDIzOSwgMjQxLCAyNTEsIDI1NywgMjYzLCAyNjksIDI3MSwgMjc3LCAyODEsIDI4MywgMjkzLCAzMDcsIDMxMSwgMzEzLCAzMTcsXG4gIDMzMSwgMzM3LCAzNDcsIDM0OSwgMzUzLCAzNTksIDM2NywgMzczLCAzNzksIDM4MywgMzg5LCAzOTcsIDQwMSwgNDA5LCA0MTksXG4gIDQyMSwgNDMxLCA0MzMsIDQzOSwgNDQzLCA0NDksIDQ1NywgNDYxLCA0NjMsIDQ2NywgNDc5LCA0ODcsIDQ5MSwgNDk5LCA1MDMsXG4gIDUwOSwgNTIxLCA1MjMsIDU0MSwgNTQ3LCA1NTcsIDU2MywgNTY5LCA1NzEsIDU3NywgNTg3LCA1OTMsIDU5OSwgNjAxLCA2MDcsXG4gIDYxMywgNjE3LCA2MTksIDYzMSwgNjQxLCA2NDMsIDY0NywgNjUzLCA2NTksIDY2MSwgNjczLCA2NzcsIDY4MywgNjkxLCA3MDEsXG4gIDcwOSwgNzE5LCA3MjcsIDczMywgNzM5LCA3NDMsIDc1MSwgNzU3LCA3NjEsIDc2OSwgNzczLCA3ODcsIDc5NywgODA5LCA4MTEsXG4gIDgyMSwgODIzLCA4MjcsIDgyOSwgODM5LCA4NTMsIDg1NywgODU5LCA4NjMsIDg3NywgODgxLCA4ODMsIDg4NywgOTA3LCA5MTEsXG4gIDkxOSwgOTI5LCA5MzcsIDk0MSwgOTQ3LCA5NTMsIDk2NywgOTcxLCA5NzcsIDk4MywgOTkxLCA5OTdcbl1cblxudmFyIGxwbGltID0gKDEgPDwgMjYpIC8gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGggLSAxXVxuXG4vLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcbmZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgdmFyIGksIHggPSB0aGlzLmFicygpXG4gIGlmICh4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoIC0gMV0pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGlmICh4LmlzRXZlbigpKSByZXR1cm4gZmFsc2VcbiAgaSA9IDFcbiAgd2hpbGUgKGkgPCBsb3dwcmltZXMubGVuZ3RoKSB7XG4gICAgdmFyIG0gPSBsb3dwcmltZXNbaV0sXG4gICAgICBqID0gaSArIDFcbiAgICB3aGlsZSAoaiA8IGxvd3ByaW1lcy5sZW5ndGggJiYgbSA8IGxwbGltKSBtICo9IGxvd3ByaW1lc1tqKytdXG4gICAgbSA9IHgubW9kSW50KG0pXG4gICAgd2hpbGUgKGkgPCBqKSBpZiAobSAlIGxvd3ByaW1lc1tpKytdID09IDApIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB4Lm1pbGxlclJhYmluKHQpXG59XG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pXG5mdW5jdGlvbiBibnBNaWxsZXJSYWJpbih0KSB7XG4gIHZhciBuMSA9IHRoaXMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpXG4gIHZhciBrID0gbjEuZ2V0TG93ZXN0U2V0Qml0KClcbiAgaWYgKGsgPD0gMCkgcmV0dXJuIGZhbHNlXG4gIHZhciByID0gbjEuc2hpZnRSaWdodChrKVxuICB0ID0gKHQgKyAxKSA+PiAxXG4gIGlmICh0ID4gbG93cHJpbWVzLmxlbmd0aCkgdCA9IGxvd3ByaW1lcy5sZW5ndGhcbiAgdmFyIGEgPSBuZXcgQmlnSW50ZWdlcihudWxsKVxuICB2YXIgaiwgYmFzZXMgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHQ7ICsraSkge1xuICAgIGZvciAoOzspIHtcbiAgICAgIGogPSBsb3dwcmltZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogbG93cHJpbWVzLmxlbmd0aCldXG4gICAgICBpZiAoYmFzZXMuaW5kZXhPZihqKSA9PSAtMSkgYnJlYWtcbiAgICB9XG4gICAgYmFzZXMucHVzaChqKVxuICAgIGEuZnJvbUludChqKVxuICAgIHZhciB5ID0gYS5tb2RQb3cociwgdGhpcylcbiAgICBpZiAoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgIHZhciBqID0gMVxuICAgICAgd2hpbGUgKGorKyA8IGsgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgICAgeSA9IHkubW9kUG93SW50KDIsIHRoaXMpXG4gICAgICAgIGlmICh5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICBpZiAoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG4vLyBwcm90ZWN0ZWRcbnByb3RvLmNodW5rU2l6ZSA9IGJucENodW5rU2l6ZVxucHJvdG8udG9SYWRpeCA9IGJucFRvUmFkaXhcbnByb3RvLmZyb21SYWRpeCA9IGJucEZyb21SYWRpeFxucHJvdG8uZnJvbU51bWJlciA9IGJucEZyb21OdW1iZXJcbnByb3RvLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUb1xucHJvdG8uY2hhbmdlQml0ID0gYm5wQ2hhbmdlQml0XG5wcm90by5hZGRUbyA9IGJucEFkZFRvXG5wcm90by5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHlcbnByb3RvLmRBZGRPZmZzZXQgPSBibnBEQWRkT2Zmc2V0XG5wcm90by5tdWx0aXBseUxvd2VyVG8gPSBibnBNdWx0aXBseUxvd2VyVG9cbnByb3RvLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUb1xucHJvdG8ubW9kSW50ID0gYm5wTW9kSW50XG5wcm90by5taWxsZXJSYWJpbiA9IGJucE1pbGxlclJhYmluXG5cbi8vIHB1YmxpY1xucHJvdG8uY2xvbmUgPSBibkNsb25lXG5wcm90by5pbnRWYWx1ZSA9IGJuSW50VmFsdWVcbnByb3RvLmJ5dGVWYWx1ZSA9IGJuQnl0ZVZhbHVlXG5wcm90by5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlXG5wcm90by5zaWdudW0gPSBiblNpZ051bVxucHJvdG8udG9CeXRlQXJyYXkgPSBiblRvQnl0ZUFycmF5XG5wcm90by5lcXVhbHMgPSBibkVxdWFsc1xucHJvdG8ubWluID0gYm5NaW5cbnByb3RvLm1heCA9IGJuTWF4XG5wcm90by5hbmQgPSBibkFuZFxucHJvdG8ub3IgPSBibk9yXG5wcm90by54b3IgPSBiblhvclxucHJvdG8uYW5kTm90ID0gYm5BbmROb3RcbnByb3RvLm5vdCA9IGJuTm90XG5wcm90by5zaGlmdExlZnQgPSBiblNoaWZ0TGVmdFxucHJvdG8uc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodFxucHJvdG8uZ2V0TG93ZXN0U2V0Qml0ID0gYm5HZXRMb3dlc3RTZXRCaXRcbnByb3RvLmJpdENvdW50ID0gYm5CaXRDb3VudFxucHJvdG8udGVzdEJpdCA9IGJuVGVzdEJpdFxucHJvdG8uc2V0Qml0ID0gYm5TZXRCaXRcbnByb3RvLmNsZWFyQml0ID0gYm5DbGVhckJpdFxucHJvdG8uZmxpcEJpdCA9IGJuRmxpcEJpdFxucHJvdG8uYWRkID0gYm5BZGRcbnByb3RvLnN1YnRyYWN0ID0gYm5TdWJ0cmFjdFxucHJvdG8ubXVsdGlwbHkgPSBibk11bHRpcGx5XG5wcm90by5kaXZpZGUgPSBibkRpdmlkZVxucHJvdG8ucmVtYWluZGVyID0gYm5SZW1haW5kZXJcbnByb3RvLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyXG5wcm90by5tb2RQb3cgPSBibk1vZFBvd1xucHJvdG8ubW9kSW52ZXJzZSA9IGJuTW9kSW52ZXJzZVxucHJvdG8ucG93ID0gYm5Qb3dcbnByb3RvLmdjZCA9IGJuR0NEXG5wcm90by5pc1Byb2JhYmxlUHJpbWUgPSBibklzUHJvYmFibGVQcmltZVxuXG4vLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxucHJvdG8uc3F1YXJlID0gYm5TcXVhcmVcblxuLy8gY29uc3RhbnRzXG5CaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMClcbkJpZ0ludGVnZXIuT05FID0gbmJ2KDEpXG5CaWdJbnRlZ2VyLnZhbHVlT2YgPSBuYnZcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyXG4iLCIvLyBGSVhNRTogS2luZCBvZiBhIHdlaXJkIHdheSB0byB0aHJvdyBleGNlcHRpb25zLCBjb25zaWRlciByZW1vdmluZ1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vYmlnaScpXG5cbi8qKlxuICogVHVybnMgYSBieXRlIGFycmF5IGludG8gYSBiaWcgaW50ZWdlci5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgaW50ZXJwcmV0IGEgYnl0ZSBhcnJheSBhcyBhIGJpZyBpbnRlZ2VyIGluIGJpZ1xuICogZW5kaWFuIG5vdGF0aW9uLlxuICovXG5CaWdJbnRlZ2VyLmZyb21CeXRlQXJyYXlVbnNpZ25lZCA9IGZ1bmN0aW9uKGJ5dGVBcnJheSkge1xuICAvLyBCaWdJbnRlZ2VyIGV4cGVjdHMgYSBERVIgaW50ZWdlciBjb25mb3JtYW50IGJ5dGUgYXJyYXlcbiAgaWYgKGJ5dGVBcnJheVswXSAmIDB4ODApIHtcbiAgICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoWzBdLmNvbmNhdChieXRlQXJyYXkpKVxuICB9XG5cbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGJ5dGVBcnJheSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgYnl0ZSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgYmlnIGludGVnZXIuXG4gKlxuICogVGhpcyByZXR1cm5zIHRoZSBhYnNvbHV0ZSBvZiB0aGUgY29udGFpbmVkIHZhbHVlIGluIGJpZyBlbmRpYW5cbiAqIGZvcm0uIEEgdmFsdWUgb2YgemVybyByZXN1bHRzIGluIGFuIGVtcHR5IGFycmF5LlxuICovXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheVVuc2lnbmVkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBieXRlQXJyYXkgPSB0aGlzLnRvQnl0ZUFycmF5KClcbiAgcmV0dXJuIGJ5dGVBcnJheVswXSA9PT0gMCA/IGJ5dGVBcnJheS5zbGljZSgxKSA6IGJ5dGVBcnJheVxufVxuXG5CaWdJbnRlZ2VyLmZyb21ERVJJbnRlZ2VyID0gZnVuY3Rpb24oYnl0ZUFycmF5KSB7XG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihieXRlQXJyYXkpXG59XG5cbi8qXG4gKiBDb252ZXJ0cyBCaWdJbnRlZ2VyIHRvIGEgREVSIGludGVnZXIgcmVwcmVzZW50YXRpb24uXG4gKlxuICogVGhlIGZvcm1hdCBmb3IgdGhpcyB2YWx1ZSB1c2VzIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBhcyBhIHNpZ25cbiAqIGJpdC4gIElmIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBpcyBhbHJlYWR5IHNldCBhbmQgdGhlIGludGVnZXIgaXNcbiAqIHBvc2l0aXZlLCBhIDB4MDAgaXMgcHJlcGVuZGVkLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgMCA9PiAgICAgMHgwMFxuICogICAgICAxID0+ICAgICAweDAxXG4gKiAgICAgLTEgPT4gICAgIDB4ZmZcbiAqICAgIDEyNyA9PiAgICAgMHg3ZlxuICogICAtMTI3ID0+ICAgICAweDgxXG4gKiAgICAxMjggPT4gICAweDAwODBcbiAqICAgLTEyOCA9PiAgICAgMHg4MFxuICogICAgMjU1ID0+ICAgMHgwMGZmXG4gKiAgIC0yNTUgPT4gICAweGZmMDFcbiAqICAxNjMwMCA9PiAgIDB4M2ZhY1xuICogLTE2MzAwID0+ICAgMHhjMDU0XG4gKiAgNjIzMDAgPT4gMHgwMGYzNWNcbiAqIC02MjMwMCA9PiAweGZmMGNhNFxuKi9cbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvREVSSW50ZWdlciA9IEJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5XG5cbkJpZ0ludGVnZXIuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBCaWdJbnRlZ2VyIGV4cGVjdHMgYSBERVIgaW50ZWdlciBjb25mb3JtYW50IGJ5dGUgYXJyYXlcbiAgaWYgKGJ1ZmZlclswXSAmIDB4ODApIHtcbiAgICB2YXIgYnl0ZUFycmF5ID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYnVmZmVyKVxuXG4gICAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKFswXS5jb25jYXQoYnl0ZUFycmF5KSlcbiAgfVxuXG4gIHJldHVybiBuZXcgQmlnSW50ZWdlcihidWZmZXIpXG59XG5cbkJpZ0ludGVnZXIuZnJvbUhleCA9IGZ1bmN0aW9uKGhleCkge1xuICBpZiAoaGV4ID09PSAnJykgcmV0dXJuIEJpZ0ludGVnZXIuWkVST1xuXG4gIGFzc2VydC5lcXVhbChoZXgsIGhleC5tYXRjaCgvXltBLUZhLWYwLTldKy8pLCAnSW52YWxpZCBoZXggc3RyaW5nJylcbiAgYXNzZXJ0LmVxdWFsKGhleC5sZW5ndGggJSAyLCAwLCAnSW5jb21wbGV0ZSBoZXgnKVxuICByZXR1cm4gbmV3IEJpZ0ludGVnZXIoaGV4LCAxNilcbn1cblxuQmlnSW50ZWdlci5wcm90b3R5cGUudG9CdWZmZXIgPSBmdW5jdGlvbihzaXplKSB7XG4gIHZhciBieXRlQXJyYXkgPSB0aGlzLnRvQnl0ZUFycmF5VW5zaWduZWQoKVxuICB2YXIgemVyb3MgPSBbXVxuXG4gIHZhciBwYWRkaW5nID0gc2l6ZSAtIGJ5dGVBcnJheS5sZW5ndGhcbiAgd2hpbGUgKHplcm9zLmxlbmd0aCA8IHBhZGRpbmcpIHplcm9zLnB1c2goMClcblxuICByZXR1cm4gbmV3IEJ1ZmZlcih6ZXJvcy5jb25jYXQoYnl0ZUFycmF5KSlcbn1cblxuQmlnSW50ZWdlci5wcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbihzaXplKSB7XG4gIHJldHVybiB0aGlzLnRvQnVmZmVyKHNpemUpLnRvU3RyaW5nKCdoZXgnKVxufVxuIiwidmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2JpZ2knKVxuXG4vL2FkZG9uc1xucmVxdWlyZSgnLi9jb252ZXJ0JylcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIl9hcmdzXCI6IFtcbiAgICBbXG4gICAgICBcImJpZ2lAMS40LjJcIixcbiAgICAgIFwiL2hvbWUvc2lndmUvRGV2L0JpdHNoYXJlcy9iaXRzaGFyZXNqc1wiXG4gICAgXVxuICBdLFxuICBcIl9mcm9tXCI6IFwiYmlnaUAxLjQuMlwiLFxuICBcIl9pZFwiOiBcImJpZ2lAMS40LjJcIixcbiAgXCJfaW5CdW5kbGVcIjogZmFsc2UsXG4gIFwiX2ludGVncml0eVwiOiBcInNoYTEtbkdaYWxmaUxpd2o4QmMvWE1mVmhoWjF5V0NVPVwiLFxuICBcIl9sb2NhdGlvblwiOiBcIi9iaWdpXCIsXG4gIFwiX3BoYW50b21DaGlsZHJlblwiOiB7fSxcbiAgXCJfcmVxdWVzdGVkXCI6IHtcbiAgICBcInR5cGVcIjogXCJ2ZXJzaW9uXCIsXG4gICAgXCJyZWdpc3RyeVwiOiB0cnVlLFxuICAgIFwicmF3XCI6IFwiYmlnaUAxLjQuMlwiLFxuICAgIFwibmFtZVwiOiBcImJpZ2lcIixcbiAgICBcImVzY2FwZWROYW1lXCI6IFwiYmlnaVwiLFxuICAgIFwicmF3U3BlY1wiOiBcIjEuNC4yXCIsXG4gICAgXCJzYXZlU3BlY1wiOiBudWxsLFxuICAgIFwiZmV0Y2hTcGVjXCI6IFwiMS40LjJcIlxuICB9LFxuICBcIl9yZXF1aXJlZEJ5XCI6IFtcbiAgICBcIi9cIixcbiAgICBcIi9lY3VydmVcIlxuICBdLFxuICBcIl9yZXNvbHZlZFwiOiBcImh0dHBzOi8vcmVnaXN0cnkubnBtanMub3JnL2JpZ2kvLS9iaWdpLTEuNC4yLnRnelwiLFxuICBcIl9zcGVjXCI6IFwiMS40LjJcIixcbiAgXCJfd2hlcmVcIjogXCIvaG9tZS9zaWd2ZS9EZXYvQml0c2hhcmVzL2JpdHNoYXJlc2pzXCIsXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvY29pbmpzL2JpZ2kvaXNzdWVzXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge30sXG4gIFwiZGVzY3JpcHRpb25cIjogXCJCaWcgaW50ZWdlcnMuXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjJcIixcbiAgICBcImlzdGFuYnVsXCI6IFwiXjAuMy41XCIsXG4gICAgXCJqc2hpbnRcIjogXCJeMi41LjFcIixcbiAgICBcIm1vY2hhXCI6IFwiXjIuMS4wXCIsXG4gICAgXCJtb2NoaWZ5XCI6IFwiXjIuMS4wXCJcbiAgfSxcbiAgXCJob21lcGFnZVwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9jb2luanMvYmlnaSNyZWFkbWVcIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJjcnlwdG9ncmFwaHlcIixcbiAgICBcIm1hdGhcIixcbiAgICBcImJpdGNvaW5cIixcbiAgICBcImFyYml0cmFyeVwiLFxuICAgIFwicHJlY2lzaW9uXCIsXG4gICAgXCJhcml0aG1ldGljXCIsXG4gICAgXCJiaWdcIixcbiAgICBcImludGVnZXJcIixcbiAgICBcImludFwiLFxuICAgIFwibnVtYmVyXCIsXG4gICAgXCJiaWdpbnRlZ2VyXCIsXG4gICAgXCJiaWdpbnRcIixcbiAgICBcImJpZ251bWJlclwiLFxuICAgIFwiZGVjaW1hbFwiLFxuICAgIFwiZmxvYXRcIlxuICBdLFxuICBcIm1haW5cIjogXCIuL2xpYi9pbmRleC5qc1wiLFxuICBcIm5hbWVcIjogXCJiaWdpXCIsXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ1cmxcIjogXCJnaXQraHR0cHM6Ly9naXRodWIuY29tL2NyeXB0b2NvaW5qcy9iaWdpLmdpdFwiLFxuICAgIFwidHlwZVwiOiBcImdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJicm93c2VyLXRlc3RcIjogXCJtb2NoaWZ5IC0td2QgLVIgc3BlY1wiLFxuICAgIFwiY292ZXJhZ2VcIjogXCJpc3RhbmJ1bCBjb3ZlciAuL25vZGVfbW9kdWxlcy8uYmluL19tb2NoYSAtLSAtLXJlcG9ydGVyIGxpc3QgdGVzdC8qLmpzXCIsXG4gICAgXCJjb3ZlcmFsbHNcIjogXCJucG0gcnVuLXNjcmlwdCBjb3ZlcmFnZSAmJiBub2RlIC4vbm9kZV9tb2R1bGVzLy5iaW4vY292ZXJhbGxzIDwgY292ZXJhZ2UvbGNvdi5pbmZvXCIsXG4gICAgXCJqc2hpbnRcIjogXCJqc2hpbnQgLS1jb25maWcganNoaW50Lmpzb24gbGliLyouanMgOyB0cnVlXCIsXG4gICAgXCJ0ZXN0XCI6IFwiX21vY2hhIC0tIHRlc3QvKi5qc1wiLFxuICAgIFwidW5pdFwiOiBcIm1vY2hhXCJcbiAgfSxcbiAgXCJ0ZXN0bGluZ1wiOiB7XG4gICAgXCJmaWxlc1wiOiBcInRlc3QvKi5qc1wiLFxuICAgIFwiaGFybmVzc1wiOiBcIm1vY2hhXCIsXG4gICAgXCJicm93c2Vyc1wiOiBbXG4gICAgICBcImllLzkuLmxhdGVzdFwiLFxuICAgICAgXCJmaXJlZm94L2xhdGVzdFwiLFxuICAgICAgXCJjaHJvbWUvbGF0ZXN0XCIsXG4gICAgICBcInNhZmFyaS82LjAuLmxhdGVzdFwiLFxuICAgICAgXCJpcGhvbmUvNi4wLi5sYXRlc3RcIixcbiAgICAgIFwiYW5kcm9pZC1icm93c2VyLzQuMi4ubGF0ZXN0XCJcbiAgICBdXG4gIH0sXG4gIFwidmVyc2lvblwiOiBcIjEuNC4yXCJcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0cy5NYW5hZ2VyID0gZXhwb3J0cy5DaGFpbkNvbmZpZyA9IGV4cG9ydHMuQXBpcyA9IHVuZGVmaW5lZDtcblxudmFyIF9BcGlJbnN0YW5jZXMgPSByZXF1aXJlKFwiLi9zcmMvQXBpSW5zdGFuY2VzXCIpO1xuXG52YXIgX0FwaUluc3RhbmNlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BcGlJbnN0YW5jZXMpO1xuXG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyID0gcmVxdWlyZShcIi4vc3JjL0Nvbm5lY3Rpb25NYW5hZ2VyXCIpO1xuXG52YXIgX0Nvbm5lY3Rpb25NYW5hZ2VyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0Nvbm5lY3Rpb25NYW5hZ2VyKTtcblxudmFyIF9DaGFpbkNvbmZpZyA9IHJlcXVpcmUoXCIuL3NyYy9DaGFpbkNvbmZpZ1wiKTtcblxudmFyIF9DaGFpbkNvbmZpZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9DaGFpbkNvbmZpZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuQXBpcyA9IF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQ7XG5leHBvcnRzLkNoYWluQ29uZmlnID0gX0NoYWluQ29uZmlnMi5kZWZhdWx0O1xuZXhwb3J0cy5NYW5hZ2VyID0gX0Nvbm5lY3Rpb25NYW5hZ2VyMi5kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX0NoYWluV2ViU29ja2V0ID0gcmVxdWlyZShcIi4vQ2hhaW5XZWJTb2NrZXRcIik7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5XZWJTb2NrZXQpO1xuXG52YXIgX0dyYXBoZW5lQXBpID0gcmVxdWlyZShcIi4vR3JhcGhlbmVBcGlcIik7XG5cbnZhciBfR3JhcGhlbmVBcGkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfR3JhcGhlbmVBcGkpO1xuXG52YXIgX0NoYWluQ29uZmlnID0gcmVxdWlyZShcIi4vQ2hhaW5Db25maWdcIik7XG5cbnZhciBfQ2hhaW5Db25maWcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5Db25maWcpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfSAvLyB2YXIgeyBMaXN0IH0gPSByZXF1aXJlKFwiaW1tdXRhYmxlXCIpO1xuXG5cbmlmIChnbG9iYWwpIHtcbiAgICBnbG9iYWwuaW5zdCA9IFwiXCI7XG59IGVsc2Uge1xuICAgIHZhciBfaW5zdCA9IHZvaWQgMDtcbn07XG52YXIgYXV0b1JlY29ubmVjdCA9IGZhbHNlOyAvLyBieSBkZWZhdWx0IGRvbid0IHVzZSByZWNvbm5lY3Rpbmctd2Vic29ja2V0XG4vKipcbiAgICBDb25maWd1cmU6IGNvbmZpZ3VyZSBhcyBmb2xsb3dzIGBBcGlzLmluc3RhbmNlKFwid3M6Ly9sb2NhbGhvc3Q6ODA5MFwiKS5pbml0X3Byb21pc2VgLiAgVGhpcyByZXR1cm5zIGEgcHJvbWlzZSwgb25jZSByZXNvbHZlZCB0aGUgY29ubmVjdGlvbiBpcyByZWFkeS5cblxuICAgIEltcG9ydDogaW1wb3J0IHsgQXBpcyB9IGZyb20gXCJAZ3JhcGhlbmUvY2hhaW5cIlxuXG4gICAgU2hvcnQtaGFuZDogQXBpcy5kYihcIm1ldGhvZFwiLCBcInBhcm0xXCIsIDIsIDMsIC4uLikuICBSZXR1cm5zIGEgcHJvbWlzZSB3aXRoIHJlc3VsdHMuXG5cbiAgICBBZGRpdGlvbmFsIHVzYWdlOiBBcGlzLmluc3RhbmNlKCkuZGJfYXBpKCkuZXhlYyhcIm1ldGhvZFwiLCBbXCJtZXRob2RcIiwgXCJwYXJtMVwiLCAyLCAzLCAuLi5dKS4gIFJldHVybnMgYSBwcm9taXNlIHdpdGggcmVzdWx0cy5cbiovXG5cbmV4cG9ydHMuZGVmYXVsdCA9IHtcblxuICAgIHNldFJwY0Nvbm5lY3Rpb25TdGF0dXNDYWxsYmFjazogZnVuY3Rpb24gc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc3RhdHVzQ2IgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKGluc3QpIGluc3Quc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICAgIEBhcmcge2Jvb2xlYW59IGF1dG8gbWVhbnMgYXV0b21hdGljIHJlY29ubmVjdCBpZiBwb3NzaWJsZSggYnJvd3NlciBjYXNlKSwgZGVmYXVsdCB0cnVlXG4gICAgKi9cbiAgICBzZXRBdXRvUmVjb25uZWN0OiBmdW5jdGlvbiBzZXRBdXRvUmVjb25uZWN0KGF1dG8pIHtcbiAgICAgICAgYXV0b1JlY29ubmVjdCA9IGF1dG87XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAgICBAYXJnIHtzdHJpbmd9IGNzIGlzIG9ubHkgcHJvdmlkZWQgaW4gdGhlIGZpcnN0IGNhbGxcbiAgICAgICAgQHJldHVybiB7QXBpc30gc2luZ2xldG9uIC4uIENoZWNrIEFwaXMuaW5zdGFuY2UoKS5pbml0X3Byb21pc2UgdG8ga25vdyB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkXG4gICAgKi9cbiAgICByZXNldDogZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgICAgIHZhciBjcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogXCJ3czovL2xvY2FsaG9zdDo4MDkwXCI7XG4gICAgICAgIHZhciBjb25uZWN0ID0gYXJndW1lbnRzWzFdO1xuICAgICAgICB2YXIgY29ubmVjdFRpbWVvdXQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDQwMDA7XG5cbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgb3B0aW9uYWxBcGlzID0gYXJndW1lbnRzWzNdO1xuICAgICAgICB2YXIgY2xvc2VDYiA9IGFyZ3VtZW50c1s0XTtcblxuICAgICAgICByZXR1cm4gdGhpcy5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaW5zdCA9IG5ldyBBcGlzSW5zdGFuY2UoKTtcbiAgICAgICAgICAgIGluc3Quc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKF90aGlzLnN0YXR1c0NiKTtcblxuICAgICAgICAgICAgaWYgKGluc3QgJiYgY29ubmVjdCkge1xuICAgICAgICAgICAgICAgIGluc3QuY29ubmVjdChjcywgY29ubmVjdFRpbWVvdXQsIG9wdGlvbmFsQXBpcywgY2xvc2VDYik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBpbnN0O1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIGluc3RhbmNlOiBmdW5jdGlvbiBpbnN0YW5jZSgpIHtcbiAgICAgICAgdmFyIGNzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBcIndzOi8vbG9jYWxob3N0OjgwOTBcIjtcbiAgICAgICAgdmFyIGNvbm5lY3QgPSBhcmd1bWVudHNbMV07XG4gICAgICAgIHZhciBjb25uZWN0VGltZW91dCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogNDAwMDtcbiAgICAgICAgdmFyIG9wdGlvbmFsQXBpcyA9IGFyZ3VtZW50c1szXTtcbiAgICAgICAgdmFyIGNsb3NlQ2IgPSBhcmd1bWVudHNbNF07XG5cbiAgICAgICAgaWYgKCFpbnN0KSB7XG4gICAgICAgICAgICBpbnN0ID0gbmV3IEFwaXNJbnN0YW5jZSgpO1xuICAgICAgICAgICAgaW5zdC5zZXRScGNDb25uZWN0aW9uU3RhdHVzQ2FsbGJhY2sodGhpcy5zdGF0dXNDYik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5zdCAmJiBjb25uZWN0KSB7XG4gICAgICAgICAgICBpbnN0LmNvbm5lY3QoY3MsIGNvbm5lY3RUaW1lb3V0LCBvcHRpb25hbEFwaXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjbG9zZUNiKSBpbnN0LmNsb3NlQ2IgPSBjbG9zZUNiO1xuICAgICAgICByZXR1cm4gaW5zdDtcbiAgICB9LFxuICAgIGNoYWluSWQ6IGZ1bmN0aW9uIGNoYWluSWQoKSB7XG4gICAgICAgIHJldHVybiBBcGlzLmluc3RhbmNlKCkuY2hhaW5faWQ7XG4gICAgfSxcblxuICAgIGNsb3NlOiBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgICAgaWYgKGluc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgaW5zdC5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpbnN0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgcmVzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgLy8gZGI6IChtZXRob2QsIC4uLmFyZ3MpID0+IEFwaXMuaW5zdGFuY2UoKS5kYl9hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKSxcbiAgICAvLyBuZXR3b3JrOiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkubmV0d29ya19hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKSxcbiAgICAvLyBoaXN0b3J5OiAobWV0aG9kLCAuLi5hcmdzKSA9PiBBcGlzLmluc3RhbmNlKCkuaGlzdG9yeV9hcGkoKS5leGVjKG1ldGhvZCwgdG9TdHJpbmdzKGFyZ3MpKSxcbiAgICAvLyBjcnlwdG86IChtZXRob2QsIC4uLmFyZ3MpID0+IEFwaXMuaW5zdGFuY2UoKS5jcnlwdG9fYXBpKCkuZXhlYyhtZXRob2QsIHRvU3RyaW5ncyhhcmdzKSlcbiAgICAvLyBvcmRlcnM6IChtZXRob2QsIC4uLmFyZ3MpID0+IEFwaXMuaW5zdGFuY2UoKS5vcmRlcnNfYXBpKCkuZXhlYyhtZXRob2QsIHRvU3RyaW5ncyhhcmdzKSlcbn07XG5cbnZhciBBcGlzSW5zdGFuY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQXBpc0luc3RhbmNlKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQXBpc0luc3RhbmNlKTtcbiAgICB9XG5cbiAgICAvKiogQGFyZyB7c3RyaW5nfSBjb25uZWN0aW9uIC4uICovXG4gICAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24gY29ubmVjdChjcywgY29ubmVjdFRpbWVvdXQpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIG9wdGlvbmFsQXBpcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogeyBlbmFibGVDcnlwdG86IGZhbHNlLCBlbmFibGVPcmRlcnM6IGZhbHNlIH07XG5cbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJJTkZPXFx0QXBpSW5zdGFuY2VzXFx0Y29ubmVjdFxcdFwiLCBjcyk7XG4gICAgICAgIHRoaXMudXJsID0gY3M7XG4gICAgICAgIHZhciBycGNfdXNlciA9IFwiXCIsXG4gICAgICAgICAgICBycGNfcGFzc3dvcmQgPSBcIlwiO1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSBcImh0dHBzOlwiICYmIGNzLmluZGV4T2YoXCJ3c3M6Ly9cIikgPCAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTZWN1cmUgZG9tYWlucyByZXF1aXJlIHdzcyBjb25uZWN0aW9uXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMud3NfcnBjKSB7XG4gICAgICAgICAgICB0aGlzLndzX3JwYy5zdGF0dXNDYiA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLndzX3JwYy5rZWVwQWxpdmVDYiA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLndzX3JwYy5vbl9jbG9zZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLndzX3JwYy5vbl9yZWNvbm5lY3QgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud3NfcnBjID0gbmV3IF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdChjcywgdGhpcy5zdGF0dXNDYiwgY29ubmVjdFRpbWVvdXQsIGF1dG9SZWNvbm5lY3QsIGZ1bmN0aW9uIChjbG9zZWQpIHtcbiAgICAgICAgICAgIGlmIChfdGhpczIuX2RiICYmICFjbG9zZWQpIHtcbiAgICAgICAgICAgICAgICBfdGhpczIuX2RiLmV4ZWMoJ2dldF9vYmplY3RzJywgW1snMi4xLjAnXV0pLmNhdGNoKGZ1bmN0aW9uIChlKSB7fSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmluaXRfcHJvbWlzZSA9IHRoaXMud3NfcnBjLmxvZ2luKHJwY191c2VyLCBycGNfcGFzc3dvcmQpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIkNvbm5lY3RlZCB0byBBUEkgbm9kZTpcIiwgY3MpO1xuICAgICAgICAgICAgX3RoaXMyLl9kYiA9IG5ldyBfR3JhcGhlbmVBcGkyLmRlZmF1bHQoX3RoaXMyLndzX3JwYywgXCJkYXRhYmFzZVwiKTtcbiAgICAgICAgICAgIF90aGlzMi5fbmV0ID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpczIud3NfcnBjLCBcIm5ldHdvcmtfYnJvYWRjYXN0XCIpO1xuICAgICAgICAgICAgX3RoaXMyLl9oaXN0ID0gbmV3IF9HcmFwaGVuZUFwaTIuZGVmYXVsdChfdGhpczIud3NfcnBjLCBcImhpc3RvcnlcIik7XG4gICAgICAgICAgICBpZiAob3B0aW9uYWxBcGlzLmVuYWJsZU9yZGVycykgX3RoaXMyLl9vcmRlcnMgPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzMi53c19ycGMsIFwib3JkZXJzXCIpO1xuICAgICAgICAgICAgaWYgKG9wdGlvbmFsQXBpcy5lbmFibGVDcnlwdG8pIF90aGlzMi5fY3J5cHQgPSBuZXcgX0dyYXBoZW5lQXBpMi5kZWZhdWx0KF90aGlzMi53c19ycGMsIFwiY3J5cHRvXCIpO1xuICAgICAgICAgICAgdmFyIGRiX3Byb21pc2UgPSBfdGhpczIuX2RiLmluaXQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAvL2h0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG9ub21leC9ncmFwaGVuZS93aWtpL2NoYWluLWxvY2tlZC10eFxuICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX2RiLmV4ZWMoXCJnZXRfY2hhaW5faWRcIiwgW10pLnRoZW4oZnVuY3Rpb24gKF9jaGFpbl9pZCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczIuY2hhaW5faWQgPSBfY2hhaW5faWQ7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfQ2hhaW5Db25maWcyLmRlZmF1bHQuc2V0Q2hhaW5JZChfY2hhaW5faWQpO1xuICAgICAgICAgICAgICAgICAgICAvL0RFQlVHIGNvbnNvbGUubG9nKFwiY2hhaW5faWQxXCIsdGhpcy5jaGFpbl9pZClcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX3RoaXMyLndzX3JwYy5vbl9yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFfdGhpczIud3NfcnBjKSByZXR1cm47XG4gICAgICAgICAgICAgICAgX3RoaXMyLndzX3JwYy5sb2dpbihcIlwiLCBcIlwiKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLl9kYi5pbml0KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMyLnN0YXR1c0NiKSBfdGhpczIuc3RhdHVzQ2IoXCJyZWNvbm5lY3RcIik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBfdGhpczIuX25ldC5pbml0KCk7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMi5faGlzdC5pbml0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25hbEFwaXMuZW5hYmxlT3JkZXJzKSBfdGhpczIuX29yZGVycy5pbml0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25hbEFwaXMuZW5hYmxlQ3J5cHRvKSBfdGhpczIuX2NyeXB0LmluaXQoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBfdGhpczIud3NfcnBjLm9uX2Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMi5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMyLmNsb3NlQ2IpIF90aGlzMi5jbG9zZUNiKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIGluaXRQcm9taXNlcyA9IFtkYl9wcm9taXNlLCBfdGhpczIuX25ldC5pbml0KCksIF90aGlzMi5faGlzdC5pbml0KCldO1xuXG4gICAgICAgICAgICBpZiAob3B0aW9uYWxBcGlzLmVuYWJsZU9yZGVycykgaW5pdFByb21pc2VzLnB1c2goX3RoaXMyLl9vcmRlcnMuaW5pdCgpKTtcbiAgICAgICAgICAgIGlmIChvcHRpb25hbEFwaXMuZW5hYmxlQ3J5cHRvKSBpbml0UHJvbWlzZXMucHVzaChfdGhpczIuX2NyeXB0LmluaXQoKSk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoaW5pdFByb21pc2VzKTtcbiAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihjcywgXCJGYWlsZWQgdG8gaW5pdGlhbGl6ZSB3aXRoIGVycm9yXCIsIGVyciAmJiBlcnIubWVzc2FnZSk7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMyLmNsb3NlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLndzX3JwYyAmJiB0aGlzLndzX3JwYy53cy5yZWFkeVN0YXRlID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53c19ycGMuY2xvc2UoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpczMud3NfcnBjID0gbnVsbDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLndzX3JwYyA9IG51bGw7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5kYl9hcGkgPSBmdW5jdGlvbiBkYl9hcGkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYjtcbiAgICB9O1xuXG4gICAgQXBpc0luc3RhbmNlLnByb3RvdHlwZS5uZXR3b3JrX2FwaSA9IGZ1bmN0aW9uIG5ldHdvcmtfYXBpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbmV0O1xuICAgIH07XG5cbiAgICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmhpc3RvcnlfYXBpID0gZnVuY3Rpb24gaGlzdG9yeV9hcGkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9oaXN0O1xuICAgIH07XG5cbiAgICBBcGlzSW5zdGFuY2UucHJvdG90eXBlLmNyeXB0b19hcGkgPSBmdW5jdGlvbiBjcnlwdG9fYXBpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3J5cHQ7XG4gICAgfTtcblxuICAgIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUub3JkZXJzX2FwaSA9IGZ1bmN0aW9uIG9yZGVyc19hcGkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vcmRlcnM7XG4gICAgfTtcblxuICAgIEFwaXNJbnN0YW5jZS5wcm90b3R5cGUuc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrID0gZnVuY3Rpb24gc2V0UnBjQ29ubmVjdGlvblN0YXR1c0NhbGxiYWNrKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuc3RhdHVzQ2IgPSBjYWxsYmFjaztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFwaXNJbnN0YW5jZTtcbn0oKTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbnZhciBfdGhpcyA9IHZvaWQgMDtcblxudmFyIGVjY19jb25maWcgPSB7XG4gICAgYWRkcmVzc19wcmVmaXg6IHByb2Nlc3MuZW52Lm5wbV9jb25maWdfX2dyYXBoZW5lX2VjY19kZWZhdWx0X2FkZHJlc3NfcHJlZml4IHx8IFwiR1BIXCJcbn07XG5cbl90aGlzID0ge1xuICAgIGNvcmVfYXNzZXQ6IFwiQ09SRVwiLFxuICAgIGFkZHJlc3NfcHJlZml4OiBcIkdQSFwiLFxuICAgIGV4cGlyZV9pbl9zZWNzOiAxNSxcbiAgICBleHBpcmVfaW5fc2Vjc19wcm9wb3NhbDogMjQgKiA2MCAqIDYwLFxuICAgIHJldmlld19pbl9zZWNzX2NvbW1pdHRlZTogMjQgKiA2MCAqIDYwLFxuICAgIG5ldHdvcmtzOiB7XG4gICAgICAgIEJpdFNoYXJlczoge1xuICAgICAgICAgICAgY29yZV9hc3NldDogXCJCVFNcIixcbiAgICAgICAgICAgIGFkZHJlc3NfcHJlZml4OiBcIkJUU1wiLFxuICAgICAgICAgICAgY2hhaW5faWQ6IFwiNDAxOGQ3ODQ0Yzc4ZjZhNmM0MWM2YTU1MmI4OTgwMjIzMTBmYzVkZWMwNmRhNDY3ZWU3OTA1YThkYWQ1MTJjOFwiXG4gICAgICAgIH0sXG4gICAgICAgIE11c2U6IHtcbiAgICAgICAgICAgIGNvcmVfYXNzZXQ6IFwiTVVTRVwiLFxuICAgICAgICAgICAgYWRkcmVzc19wcmVmaXg6IFwiTVVTRVwiLFxuICAgICAgICAgICAgY2hhaW5faWQ6IFwiNDVhZDJkM2Y5ZWY5MmE0OWI1NWMyMjI3ZWIwNjEyM2Y2MTNiYjM1ZGQwOGJkODc2ZjJhZWEyMTkyNWE2N2E2N1wiXG4gICAgICAgIH0sXG4gICAgICAgIFRlc3Q6IHtcbiAgICAgICAgICAgIGNvcmVfYXNzZXQ6IFwiVEVTVFwiLFxuICAgICAgICAgICAgYWRkcmVzc19wcmVmaXg6IFwiVEVTVFwiLFxuICAgICAgICAgICAgY2hhaW5faWQ6IFwiMzlmNWUyZWRlMWY4YmMxYTNhNTRhNzkxNDQxNGUzNzc5ZTMzMTkzZjFmNTY5MzUxMGU3M2NiN2E4NzYxNzQ0N1wiXG4gICAgICAgIH0sXG4gICAgICAgIE9iZWxpc2s6IHtcbiAgICAgICAgICAgIGNvcmVfYXNzZXQ6IFwiR09WXCIsXG4gICAgICAgICAgICBhZGRyZXNzX3ByZWZpeDogXCJGRVdcIixcbiAgICAgICAgICAgIGNoYWluX2lkOiBcIjFjZmRlN2MzODhiOWU4YWMwNjQ2MmQ2OGFhZGJkOTY2YjU4Zjg4Nzk3NjM3ZDlhZjgwNWI0NTYwYjBlOTY2MWVcIlxuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKiBTZXQgYSBmZXcgcHJvcGVydGllcyBmb3Iga25vd24gY2hhaW4gSURzLiAqL1xuICAgIHNldENoYWluSWQ6IGZ1bmN0aW9uIHNldENoYWluSWQoY2hhaW5faWQpIHtcblxuICAgICAgICB2YXIgaSA9IHZvaWQgMCxcbiAgICAgICAgICAgIGxlbiA9IHZvaWQgMCxcbiAgICAgICAgICAgIG5ldHdvcmsgPSB2b2lkIDAsXG4gICAgICAgICAgICBuZXR3b3JrX25hbWUgPSB2b2lkIDAsXG4gICAgICAgICAgICByZWYgPSB2b2lkIDA7XG4gICAgICAgIHJlZiA9IE9iamVjdC5rZXlzKF90aGlzLm5ldHdvcmtzKTtcblxuICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSByZWYubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcblxuICAgICAgICAgICAgbmV0d29ya19uYW1lID0gcmVmW2ldO1xuICAgICAgICAgICAgbmV0d29yayA9IF90aGlzLm5ldHdvcmtzW25ldHdvcmtfbmFtZV07XG5cbiAgICAgICAgICAgIGlmIChuZXR3b3JrLmNoYWluX2lkID09PSBjaGFpbl9pZCkge1xuXG4gICAgICAgICAgICAgICAgX3RoaXMubmV0d29ya19uYW1lID0gbmV0d29ya19uYW1lO1xuXG4gICAgICAgICAgICAgICAgaWYgKG5ldHdvcmsuYWRkcmVzc19wcmVmaXgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuYWRkcmVzc19wcmVmaXggPSBuZXR3b3JrLmFkZHJlc3NfcHJlZml4O1xuICAgICAgICAgICAgICAgICAgICBlY2NfY29uZmlnLmFkZHJlc3NfcHJlZml4ID0gbmV0d29yay5hZGRyZXNzX3ByZWZpeDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIklORk8gICAgQ29uZmlndXJlZCBmb3JcIiwgbmV0d29ya19uYW1lLCBcIjpcIiwgbmV0d29yay5jb3JlX2Fzc2V0LCBcIlxcblwiKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIG5ldHdvcmtfbmFtZTogbmV0d29ya19uYW1lLFxuICAgICAgICAgICAgICAgICAgICBuZXR3b3JrOiBuZXR3b3JrXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghX3RoaXMubmV0d29ya19uYW1lKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIlVua25vd24gY2hhaW4gaWQgKHRoaXMgbWF5IGJlIGEgdGVzdG5ldClcIiwgY2hhaW5faWQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHJlc2V0OiBmdW5jdGlvbiByZXNldCgpIHtcbiAgICAgICAgX3RoaXMuY29yZV9hc3NldCA9IFwiQ09SRVwiO1xuICAgICAgICBfdGhpcy5hZGRyZXNzX3ByZWZpeCA9IFwiR1BIXCI7XG4gICAgICAgIGVjY19jb25maWcuYWRkcmVzc19wcmVmaXggPSBcIkdQSFwiO1xuICAgICAgICBfdGhpcy5leHBpcmVfaW5fc2VjcyA9IDE1O1xuICAgICAgICBfdGhpcy5leHBpcmVfaW5fc2Vjc19wcm9wb3NhbCA9IDI0ICogNjAgKiA2MDtcblxuICAgICAgICBjb25zb2xlLmxvZyhcIkNoYWluIGNvbmZpZyByZXNldFwiKTtcbiAgICB9LFxuXG4gICAgc2V0UHJlZml4OiBmdW5jdGlvbiBzZXRQcmVmaXgoKSB7XG4gICAgICAgIHZhciBwcmVmaXggPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFwiR1BIXCI7XG5cbiAgICAgICAgX3RoaXMuYWRkcmVzc19wcmVmaXggPSBwcmVmaXg7XG4gICAgICAgIGVjY19jb25maWcuYWRkcmVzc19wcmVmaXggPSBwcmVmaXg7XG4gICAgfVxufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gX3RoaXM7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgV2ViU29ja2V0Q2xpZW50ID0gdm9pZCAwO1xuaWYgKHR5cGVvZiBXZWJTb2NrZXQgPT09IFwidW5kZWZpbmVkXCIgJiYgIXByb2Nlc3MuZW52LmJyb3dzZXIpIHtcbiAgICBXZWJTb2NrZXRDbGllbnQgPSByZXF1aXJlKFwid3NcIik7XG59IGVsc2Uge1xuICAgIFdlYlNvY2tldENsaWVudCA9IFdlYlNvY2tldDtcbn1cblxudmFyIFNPQ0tFVF9ERUJVRyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBnZXRXZWJTb2NrZXRDbGllbnQoYXV0b1JlY29ubmVjdCkge1xuICAgIGlmICghYXV0b1JlY29ubmVjdCAmJiB0eXBlb2YgV2ViU29ja2V0ICE9PSBcInVuZGVmaW5lZFwiICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICByZXR1cm4gV2ViU29ja2V0O1xuICAgIH1cbiAgICByZXR1cm4gV2ViU29ja2V0Q2xpZW50O1xufVxuXG52YXIga2VlcF9hbGl2ZV9pbnRlcnZhbCA9IDUwMDA7XG52YXIgbWF4X3NlbmRfbGlmZSA9IDU7XG52YXIgbWF4X3JlY3ZfbGlmZSA9IG1heF9zZW5kX2xpZmUgKiAyO1xuXG52YXIgQ2hhaW5XZWJTb2NrZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ2hhaW5XZWJTb2NrZXQod3Nfc2VydmVyLCBzdGF0dXNDYikge1xuICAgICAgICB2YXIgY29ubmVjdFRpbWVvdXQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDUwMDA7XG5cbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgYXV0b1JlY29ubmVjdCA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogdHJ1ZTtcbiAgICAgICAgdmFyIGtlZXBBbGl2ZUNiID0gYXJndW1lbnRzLmxlbmd0aCA+IDQgJiYgYXJndW1lbnRzWzRdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbNF0gOiBudWxsO1xuXG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDaGFpbldlYlNvY2tldCk7XG5cbiAgICAgICAgdGhpcy51cmwgPSB3c19zZXJ2ZXI7XG4gICAgICAgIHRoaXMuc3RhdHVzQ2IgPSBzdGF0dXNDYjtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKF90aGlzLmN1cnJlbnRfcmVqZWN0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlamVjdCA9IF90aGlzLmN1cnJlbnRfcmVqZWN0O1xuICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRfcmVqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICBfdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJDb25uZWN0aW9uIGF0dGVtcHQgdGltZWQgb3V0IGFmdGVyIFwiICsgY29ubmVjdFRpbWVvdXQgLyAxMDAwICsgXCJzXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgY29ubmVjdFRpbWVvdXQpO1xuXG4gICAgICAgIHRoaXMuY3VycmVudF9yZWplY3QgPSBudWxsO1xuICAgICAgICB0aGlzLm9uX3JlY29ubmVjdCA9IG51bGw7XG4gICAgICAgIHRoaXMuY2xvc2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc2VuZF9saWZlID0gbWF4X3NlbmRfbGlmZTtcbiAgICAgICAgdGhpcy5yZWN2X2xpZmUgPSBtYXhfcmVjdl9saWZlO1xuICAgICAgICB0aGlzLmtlZXBBbGl2ZUNiID0ga2VlcEFsaXZlQ2I7XG4gICAgICAgIHRoaXMuY29ubmVjdF9wcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgX3RoaXMuY3VycmVudF9yZWplY3QgPSByZWplY3Q7XG4gICAgICAgICAgICB2YXIgV3NDbGllbnQgPSBnZXRXZWJTb2NrZXRDbGllbnQoYXV0b1JlY29ubmVjdCk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIF90aGlzLndzID0gbmV3IFdzQ2xpZW50KHdzX3NlcnZlcik7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIF90aGlzLndzID0geyByZWFkeVN0YXRlOiAzLCBjbG9zZTogZnVuY3Rpb24gY2xvc2UoKSB7fSB9OyAvLyBESVNDT05ORUNURURcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCB1cmxcIiwgd3Nfc2VydmVyLCBcIiBjbG9zZWRcIikpO1xuICAgICAgICAgICAgICAgIC8vIHJldHVybiB0aGlzLmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gICAgIGNvbnNvbGUubG9nKFwiSW52YWxpZCB1cmxcIiwgd3Nfc2VydmVyLCBcIiBjbG9zZWRcIik7XG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdXJsXCIsIHdzX3NlcnZlciwgXCIgY2xvc2VkXCIpXG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIHJldHVybiB0aGlzLmN1cnJlbnRfcmVqZWN0KEVycm9yKFwiSW52YWxpZCB3ZWJzb2NrZXQgdXJsOiBcIiArIHdzX3NlcnZlcikpO1xuICAgICAgICAgICAgICAgIC8vIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIF90aGlzLndzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMuY29ubmVjdGlvblRpbWVvdXQpO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5zdGF0dXNDYikgX3RoaXMuc3RhdHVzQ2IoXCJvcGVuXCIpO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5vbl9yZWNvbm5lY3QpIF90aGlzLm9uX3JlY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIF90aGlzLmtlZXBhbGl2ZV90aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5yZWN2X2xpZmUtLTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnJlY3ZfbGlmZSA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKF90aGlzLnVybCArICcgY29ubmVjdGlvbiBpcyBkZWFkLCB0ZXJtaW5hdGluZyB3cycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNsZWFySW50ZXJ2YWwodGhpcy5rZWVwYWxpdmVfdGltZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5rZWVwYWxpdmVfdGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2VuZF9saWZlLS07XG4gICAgICAgICAgICAgICAgICAgIGlmIChfdGhpcy5zZW5kX2xpZmUgPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy53cy5waW5nKCcnLCBmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMua2VlcEFsaXZlQ2IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5rZWVwQWxpdmVDYihfdGhpcy5jbG9zZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2VuZF9saWZlID0gbWF4X3NlbmRfbGlmZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIDUwMDApO1xuICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRfcmVqZWN0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgX3RoaXMud3Mub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5rZWVwYWxpdmVfdGltZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChfdGhpcy5rZWVwYWxpdmVfdGltZXIpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5rZWVwYWxpdmVfdGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfdGhpcy5jb25uZWN0aW9uVGltZW91dCk7XG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLnN0YXR1c0NiKSBfdGhpcy5zdGF0dXNDYihcImVycm9yXCIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLmN1cnJlbnRfcmVqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRfcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgX3RoaXMud3Mub25tZXNzYWdlID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5yZWN2X2xpZmUgPSBtYXhfcmVjdl9saWZlO1xuICAgICAgICAgICAgICAgIF90aGlzLmxpc3RlbmVyKEpTT04ucGFyc2UobWVzc2FnZS5kYXRhKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgX3RoaXMud3Mub25jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5jbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5rZWVwYWxpdmVfdGltZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChfdGhpcy5rZWVwYWxpdmVfdGltZXIpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5rZWVwYWxpdmVfdGltZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ2Nvbm5lY3Rpb24gY2xvc2VkJyk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgY2JJZCA9IF90aGlzLnJlc3BvbnNlQ2JJZCArIDE7IGNiSWQgPD0gX3RoaXMuY2JJZDsgY2JJZCArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmNic1tjYklkXS5yZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLnN0YXR1c0NiKSBfdGhpcy5zdGF0dXNDYihcImNsb3NlZFwiKTtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuX2Nsb3NlQ2IpIF90aGlzLl9jbG9zZUNiKCk7XG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLm9uX2Nsb3NlKSBfdGhpcy5vbl9jbG9zZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2JJZCA9IDA7XG4gICAgICAgIHRoaXMucmVzcG9uc2VDYklkID0gMDtcbiAgICAgICAgdGhpcy5jYnMgPSB7fTtcbiAgICAgICAgdGhpcy5zdWJzID0ge307XG4gICAgICAgIHRoaXMudW5zdWIgPSB7fTtcbiAgICB9XG5cbiAgICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uIGNhbGwocGFyYW1zKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLndzLnJlYWR5U3RhdGUgIT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ3dlYnNvY2tldCBzdGF0ZSBlcnJvcjonICsgdGhpcy53cy5yZWFkeVN0YXRlKSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG1ldGhvZCA9IHBhcmFtc1sxXTtcbiAgICAgICAgaWYgKFNPQ0tFVF9ERUJVRykgY29uc29sZS5sb2coXCJbQ2hhaW5XZWJTb2NrZXRdID4tLS0tIGNhbGwgLS0tLS0+ICBcXFwiaWRcXFwiOlwiICsgKHRoaXMuY2JJZCArIDEpLCBKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcblxuICAgICAgICB0aGlzLmNiSWQgKz0gMTtcblxuICAgICAgICBpZiAobWV0aG9kID09PSBcInNldF9zdWJzY3JpYmVfY2FsbGJhY2tcIiB8fCBtZXRob2QgPT09IFwic3Vic2NyaWJlX3RvX21hcmtldFwiIHx8IG1ldGhvZCA9PT0gXCJicm9hZGNhc3RfdHJhbnNhY3Rpb25fd2l0aF9jYWxsYmFja1wiIHx8IG1ldGhvZCA9PT0gXCJzZXRfcGVuZGluZ190cmFuc2FjdGlvbl9jYWxsYmFja1wiKSB7XG4gICAgICAgICAgICAvLyBTdG9yZSBjYWxsYmFjayBpbiBzdWJzIG1hcFxuICAgICAgICAgICAgdGhpcy5zdWJzW3RoaXMuY2JJZF0gPSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IHBhcmFtc1syXVswXVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gUmVwbGFjZSBjYWxsYmFjayB3aXRoIHRoZSBjYWxsYmFjayBpZFxuICAgICAgICAgICAgcGFyYW1zWzJdWzBdID0gdGhpcy5jYklkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gXCJ1bnN1YnNjcmliZV9mcm9tX21hcmtldFwiIHx8IG1ldGhvZCA9PT0gXCJ1bnN1YnNjcmliZV9mcm9tX2FjY291bnRzXCIpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGFyYW1zWzJdWzBdICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGaXJzdCBwYXJhbWV0ZXIgb2YgdW5zdWIgbXVzdCBiZSB0aGUgb3JpZ2luYWwgY2FsbGJhY2tcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB1blN1YkNiID0gcGFyYW1zWzJdLnNwbGljZSgwLCAxKVswXTtcblxuICAgICAgICAgICAgLy8gRmluZCB0aGUgY29ycmVzcG9uZGluZyBzdWJzY3JpcHRpb25cbiAgICAgICAgICAgIGZvciAodmFyIGlkIGluIHRoaXMuc3Vicykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN1YnNbaWRdLmNhbGxiYWNrID09PSB1blN1YkNiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudW5zdWJbdGhpcy5jYklkXSA9IGlkO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgIG1ldGhvZDogXCJjYWxsXCIsXG4gICAgICAgICAgICBwYXJhbXM6IHBhcmFtc1xuICAgICAgICB9O1xuICAgICAgICByZXF1ZXN0LmlkID0gdGhpcy5jYklkO1xuICAgICAgICB0aGlzLnNlbmRfbGlmZSA9IG1heF9zZW5kX2xpZmU7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIF90aGlzMi5jYnNbX3RoaXMyLmNiSWRdID0ge1xuICAgICAgICAgICAgICAgIHRpbWU6IG5ldyBEYXRlKCksXG4gICAgICAgICAgICAgICAgcmVzb2x2ZTogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgICByZWplY3Q6IHJlamVjdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIF90aGlzMi53cy5zZW5kKEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5saXN0ZW5lciA9IGZ1bmN0aW9uIGxpc3RlbmVyKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChTT0NLRVRfREVCVUcpIGNvbnNvbGUubG9nKFwiW0NoYWluV2ViU29ja2V0XSA8LS0tLSByZXBseSAtLS0tPFwiLCBKU09OLnN0cmluZ2lmeShyZXNwb25zZSkpO1xuXG4gICAgICAgIHZhciBzdWIgPSBmYWxzZSxcbiAgICAgICAgICAgIGNhbGxiYWNrID0gbnVsbDtcblxuICAgICAgICBpZiAocmVzcG9uc2UubWV0aG9kID09PSBcIm5vdGljZVwiKSB7XG4gICAgICAgICAgICBzdWIgPSB0cnVlO1xuICAgICAgICAgICAgcmVzcG9uc2UuaWQgPSByZXNwb25zZS5wYXJhbXNbMF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXN1Yikge1xuICAgICAgICAgICAgY2FsbGJhY2sgPSB0aGlzLmNic1tyZXNwb25zZS5pZF07XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNlQ2JJZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2sgPSB0aGlzLnN1YnNbcmVzcG9uc2UuaWRdLmNhbGxiYWNrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrICYmICFzdWIpIHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrLnJlamVjdChyZXNwb25zZS5lcnJvcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrLnJlc29sdmUocmVzcG9uc2UucmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNic1tyZXNwb25zZS5pZF07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnVuc3ViW3Jlc3BvbnNlLmlkXSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN1YnNbdGhpcy51bnN1YltyZXNwb25zZS5pZF1dO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnVuc3ViW3Jlc3BvbnNlLmlkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChjYWxsYmFjayAmJiBzdWIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHJlc3BvbnNlLnBhcmFtc1sxXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIldhcm5pbmc6IHVua25vd24gd2Vic29ja2V0IHJlc3BvbnNlOiBcIiwgcmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIENoYWluV2ViU29ja2V0LnByb3RvdHlwZS5sb2dpbiA9IGZ1bmN0aW9uIGxvZ2luKHVzZXIsIHBhc3N3b3JkKSB7XG4gICAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3RfcHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpczMuY2FsbChbMSwgXCJsb2dpblwiLCBbdXNlciwgcGFzc3dvcmRdXSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBDaGFpbldlYlNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoX3RoaXM0LmtlZXBhbGl2ZV90aW1lcik7XG4gICAgICAgICAgICBfdGhpczQua2VlcGFsaXZlX3RpbWVyID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgX3RoaXM0Ll9jbG9zZUNiID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlcygpO1xuICAgICAgICAgICAgICAgIF90aGlzNC5fY2xvc2VDYiA9IG51bGw7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKCFfdGhpczQud3MpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIldlYnNvY2tldCBhbHJlYWR5IGNsZWFyZWRcIiwgX3RoaXM0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoX3RoaXM0LndzLnRlcm1pbmF0ZSkge1xuICAgICAgICAgICAgICAgIF90aGlzNC53cy50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgX3RoaXM0LndzLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoX3RoaXM0LndzLnJlYWR5U3RhdGUgPT09IDMpIHJlcygpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIENoYWluV2ViU29ja2V0O1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBDaGFpbldlYlNvY2tldDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfQXBpSW5zdGFuY2VzID0gcmVxdWlyZShcIi4vQXBpSW5zdGFuY2VzXCIpO1xuXG52YXIgX0FwaUluc3RhbmNlczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BcGlJbnN0YW5jZXMpO1xuXG52YXIgX0NoYWluV2ViU29ja2V0ID0gcmVxdWlyZShcIi4vQ2hhaW5XZWJTb2NrZXRcIik7XG5cbnZhciBfQ2hhaW5XZWJTb2NrZXQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQ2hhaW5XZWJTb2NrZXQpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgTWFuYWdlciA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNYW5hZ2VyKF9yZWYpIHtcbiAgICAgICAgdmFyIHVybCA9IF9yZWYudXJsLFxuICAgICAgICAgICAgdXJscyA9IF9yZWYudXJscyxcbiAgICAgICAgICAgIGF1dG9GYWxsYmFjayA9IF9yZWYuYXV0b0ZhbGxiYWNrLFxuICAgICAgICAgICAgY2xvc2VDYiA9IF9yZWYuY2xvc2VDYixcbiAgICAgICAgICAgIG9wdGlvbmFsQXBpcyA9IF9yZWYub3B0aW9uYWxBcGlzLFxuICAgICAgICAgICAgdXJsQ2hhbmdlQ2FsbGJhY2sgPSBfcmVmLnVybENoYW5nZUNhbGxiYWNrO1xuXG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBNYW5hZ2VyKTtcblxuICAgICAgICB0aGlzLnVybCA9IHVybDtcbiAgICAgICAgdGhpcy51cmxzID0gdXJscy5maWx0ZXIoZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgIHJldHVybiBhICE9PSB1cmw7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF1dG9GYWxsYmFjayA9IGF1dG9GYWxsYmFjaztcbiAgICAgICAgdGhpcy5jbG9zZUNiID0gY2xvc2VDYjtcbiAgICAgICAgdGhpcy5vcHRpb25hbEFwaXMgPSBvcHRpb25hbEFwaXMgfHwge307XG4gICAgICAgIHRoaXMuaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy51cmxDaGFuZ2VDYWxsYmFjayA9IHVybENoYW5nZUNhbGxiYWNrO1xuICAgIH1cblxuICAgIE1hbmFnZXIucHJvdG90eXBlLnNldENsb3NlQ2IgPSBmdW5jdGlvbiBzZXRDbG9zZUNiKGNiKSB7XG4gICAgICAgIHRoaXMuY2xvc2VDYiA9IGNiO1xuICAgIH07XG5cbiAgICBNYW5hZ2VyLmNsb3NlID0gZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBfQXBpSW5zdGFuY2VzMi5kZWZhdWx0LmNsb3NlKCk7XG4gICAgfTtcblxuICAgIE1hbmFnZXIucHJvdG90eXBlLmxvZ0ZhaWx1cmUgPSBmdW5jdGlvbiBsb2dGYWlsdXJlKG1ldGhvZCwgdXJsLCBlcnIpIHtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBlcnIgJiYgZXJyLm1lc3NhZ2UgPyBlcnIubWVzc2FnZSA6IFwiXCI7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWV0aG9kLCBcIkZhaWxlZCB0byBjb25uZWN0IHRvIFwiICsgdXJsICsgKG1lc3NhZ2UgPyBcIiBFcnJvcjogXCIgKyBKU09OLnN0cmluZ2lmeShtZXNzYWdlKSA6IFwiXCIpKTtcbiAgICB9O1xuXG4gICAgTWFuYWdlci5wcm90b3R5cGUuX29uQ2xvc2UgPSBmdW5jdGlvbiBfb25DbG9zZSgpIHtcbiAgICAgICAgdGhpcy5pc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5jbG9zZUNiKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlQ2IoKTtcbiAgICAgICAgICAgIHRoaXMuc2V0Q2xvc2VDYihudWxsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hdXRvRmFsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdFdpdGhGYWxsYmFjaygpO1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBNYW5hZ2VyLnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24gY29ubmVjdCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgX2Nvbm5lY3QgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHRydWU7XG5cbiAgICAgICAgdmFyIHVybCA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogdGhpcy51cmw7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIF9BcGlJbnN0YW5jZXMyLmRlZmF1bHQuaW5zdGFuY2UodXJsLCBfY29ubmVjdCwgdW5kZWZpbmVkLCBfdGhpcy5vcHRpb25hbEFwaXMsIF90aGlzLl9vbkNsb3NlLmJpbmQoX3RoaXMpKS5pbml0X3Byb21pc2UudGhlbihmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMudXJsID0gdXJsO1xuICAgICAgICAgICAgICAgIF90aGlzLmlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgX0FwaUluc3RhbmNlczIuZGVmYXVsdC5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdFdpdGhGYWxsYmFjayA9IGZ1bmN0aW9uIGNvbm5lY3RXaXRoRmFsbGJhY2soKSB7XG4gICAgICAgIHZhciBjb25uZWN0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB0cnVlO1xuICAgICAgICB2YXIgdXJsID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB0aGlzLnVybDtcbiAgICAgICAgdmFyIGluZGV4ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAwO1xuXG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciByZXNvbHZlID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiBudWxsO1xuICAgICAgICB2YXIgcmVqZWN0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDQgJiYgYXJndW1lbnRzWzRdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbNF0gOiBudWxsO1xuXG4gICAgICAgIGlmIChyZWplY3QgJiYgaW5kZXggPiB0aGlzLnVybHMubGVuZ3RoKSByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcihcIlRyaWVkIFwiICsgaW5kZXggKyBcIiBjb25uZWN0aW9ucywgbm9uZSBvZiB3aGljaCB3b3JrZWQ6IFwiICsgSlNPTi5zdHJpbmdpZnkodGhpcy51cmxzLmNvbmNhdCh0aGlzLnVybCkpKSk7XG4gICAgICAgIHZhciBmYWxsYmFjayA9IGZ1bmN0aW9uIGZhbGxiYWNrKGVyciwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMyLnVybENoYW5nZUNhbGxiYWNrKSBfdGhpczIudXJsQ2hhbmdlQ2FsbGJhY2soX3RoaXMyLnVybHNbaW5kZXhdKTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpczIuY29ubmVjdFdpdGhGYWxsYmFjayhjb25uZWN0LCBfdGhpczIudXJsc1tpbmRleF0sIGluZGV4ICsgMSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHJlc29sdmUgJiYgcmVqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25uZWN0KGNvbm5lY3QsIHVybCkudGhlbihyZXNvbHZlKS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgZmFsbGJhY2soZXJyLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgICAgIF90aGlzMi5jb25uZWN0KGNvbm5lY3QsIHVuZGVmaW5lZCkudGhlbihyZXNvbHZlKS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGZhbGxiYWNrKGVyciwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIE1hbmFnZXIucHJvdG90eXBlLmNoZWNrQ29ubmVjdGlvbnMgPSBmdW5jdGlvbiBjaGVja0Nvbm5lY3Rpb25zKCkge1xuICAgICAgICB2YXIgcnBjX3VzZXIgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFwiXCI7XG4gICAgICAgIHZhciBycGNfcGFzc3dvcmQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFwiXCI7XG5cbiAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHJlc29sdmUgPSBhcmd1bWVudHNbMl07XG4gICAgICAgIHZhciByZWplY3QgPSBhcmd1bWVudHNbM107XG5cbiAgICAgICAgdmFyIGNvbm5lY3Rpb25TdGFydFRpbWVzID0ge307XG4gICAgICAgIHZhciBjaGVja0Z1bmN0aW9uID0gZnVuY3Rpb24gY2hlY2tGdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIHZhciBmdWxsTGlzdCA9IF90aGlzMy51cmxzLmNvbmNhdChfdGhpczMudXJsKTtcbiAgICAgICAgICAgIHZhciBjb25uZWN0aW9uUHJvbWlzZXMgPSBbXTtcblxuICAgICAgICAgICAgZnVsbExpc3QuZm9yRWFjaChmdW5jdGlvbiAodXJsKSB7XG4gICAgICAgICAgICAgICAgLyogVXNlIGRlZmF1bHQgdGltZW91dCBhbmQgbm8gcmVjb25uZWN0aW5nLXdlYnNvY2tldCAqL1xuICAgICAgICAgICAgICAgIHZhciBjb25uID0gbmV3IF9DaGFpbldlYlNvY2tldDIuZGVmYXVsdCh1cmwsIGZ1bmN0aW9uICgpIHt9LCB1bmRlZmluZWQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uU3RhcnRUaW1lc1t1cmxdID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvblByb21pc2VzLnB1c2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29ubi5sb2dpbihycGNfdXNlciwgcnBjX3Bhc3N3b3JkKS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgX3Jlc3VsdDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IChfcmVzdWx0ID0ge30sIF9yZXN1bHRbdXJsXSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gY29ubmVjdGlvblN0YXJ0VGltZXNbdXJsXSwgX3Jlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29ubi5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMzLmxvZ0ZhaWx1cmUoXCJjaGVja0Nvbm5lY3Rpb25zXCIsIHVybCwgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmwgPT09IF90aGlzMy51cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczMudXJsID0gX3RoaXMzLnVybHNbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMy51cmxzID0gX3RoaXMzLnVybHMuZmlsdGVyKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhICE9PSB1cmw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29ubi5jbG9zZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIFByb21pc2UuYWxsKGNvbm5lY3Rpb25Qcm9taXNlcy5tYXAoZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYSgpO1xuICAgICAgICAgICAgfSkpLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgICAgICAgICAgICAgIHZhciBmaW5hbCA9IHJlcy5maWx0ZXIoZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhYTtcbiAgICAgICAgICAgICAgICB9KS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKGEpWzBdIC0gT2JqZWN0LnZhbHVlcyhiKVswXTtcbiAgICAgICAgICAgICAgICB9KS5yZWR1Y2UoZnVuY3Rpb24gKGYsIGEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleSA9IE9iamVjdC5rZXlzKGEpWzBdO1xuICAgICAgICAgICAgICAgICAgICBmW2tleV0gPSBhW2tleV07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmO1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ2hlY2tlZCBcIiArIHJlcy5sZW5ndGggKyBcIiBjb25uZWN0aW9ucywgXCIgKyAocmVzLmxlbmd0aCAtIE9iamVjdC5rZXlzKGZpbmFsKS5sZW5ndGgpICsgXCIgZmFpbGVkXCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGZpbmFsKTtcbiAgICAgICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLmNoZWNrQ29ubmVjdGlvbnMocnBjX3VzZXIsIHJwY19wYXNzd29yZCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChyZXNvbHZlICYmIHJlamVjdCkge1xuICAgICAgICAgICAgY2hlY2tGdW5jdGlvbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGNoZWNrRnVuY3Rpb24pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBNYW5hZ2VyO1xufSgpO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBNYW5hZ2VyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxudmFyIEdyYXBoZW5lQXBpID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdyYXBoZW5lQXBpKHdzX3JwYywgYXBpX25hbWUpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEdyYXBoZW5lQXBpKTtcblxuICAgICAgICB0aGlzLndzX3JwYyA9IHdzX3JwYztcbiAgICAgICAgdGhpcy5hcGlfbmFtZSA9IGFwaV9uYW1lO1xuICAgIH1cblxuICAgIEdyYXBoZW5lQXBpLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gaW5pdCgpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICByZXR1cm4gdGhpcy53c19ycGMuY2FsbChbMSwgdGhpcy5hcGlfbmFtZSwgW11dKS50aGVuKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhcIltHcmFwaGVuZUFwaS5qczoxMV0gLS0tLS0gR3JhcGhlbmVBcGkuaW5pdCAtLS0tLT5cIiwgdGhpcy5hcGlfbmFtZSwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgc2VsZi5hcGlfaWQgPSByZXNwb25zZTtcbiAgICAgICAgICAgIHJldHVybiBzZWxmO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgR3JhcGhlbmVBcGkucHJvdG90eXBlLmV4ZWMgPSBmdW5jdGlvbiBleGVjKG1ldGhvZCwgcGFyYW1zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLndzX3JwYy5jYWxsKFt0aGlzLmFwaV9pZCwgbWV0aG9kLCBwYXJhbXNdKS5jYXRjaChmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiISEhIEdyYXBoZW5lQXBpIGVycm9yOiBcIiwgbWV0aG9kLCBwYXJhbXMsIGVycm9yLCBKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gR3JhcGhlbmVBcGk7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEdyYXBoZW5lQXBpO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTsiLCIiLCIvKiBlc2xpbnQtZGlzYWJsZSBub2RlL25vLWRlcHJlY2F0ZWQtYXBpICovXG52YXIgYnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJylcbnZhciBCdWZmZXIgPSBidWZmZXIuQnVmZmVyXG5cbi8vIGFsdGVybmF0aXZlIHRvIHVzaW5nIE9iamVjdC5rZXlzIGZvciBvbGQgYnJvd3NlcnNcbmZ1bmN0aW9uIGNvcHlQcm9wcyAoc3JjLCBkc3QpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykge1xuICAgIGRzdFtrZXldID0gc3JjW2tleV1cbiAgfVxufVxuaWYgKEJ1ZmZlci5mcm9tICYmIEJ1ZmZlci5hbGxvYyAmJiBCdWZmZXIuYWxsb2NVbnNhZmUgJiYgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdykge1xuICBtb2R1bGUuZXhwb3J0cyA9IGJ1ZmZlclxufSBlbHNlIHtcbiAgLy8gQ29weSBwcm9wZXJ0aWVzIGZyb20gcmVxdWlyZSgnYnVmZmVyJylcbiAgY29weVByb3BzKGJ1ZmZlciwgZXhwb3J0cylcbiAgZXhwb3J0cy5CdWZmZXIgPSBTYWZlQnVmZmVyXG59XG5cbmZ1bmN0aW9uIFNhZmVCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIENvcHkgc3RhdGljIG1ldGhvZHMgZnJvbSBCdWZmZXJcbmNvcHlQcm9wcyhCdWZmZXIsIFNhZmVCdWZmZXIpXG5cblNhZmVCdWZmZXIuZnJvbSA9IGZ1bmN0aW9uIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuU2FmZUJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgdmFyIGJ1ZiA9IEJ1ZmZlcihzaXplKVxuICBpZiAoZmlsbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwsIGVuY29kaW5nKVxuICAgIH0gZWxzZSB7XG4gICAgICBidWYuZmlsbChmaWxsKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBidWYuZmlsbCgwKVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKHNpemUpXG59XG5cblNhZmVCdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBidWZmZXIuU2xvd0J1ZmZlcihzaXplKVxufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbid1c2Ugc3RyaWN0JztcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBpc0VuY29kaW5nID0gQnVmZmVyLmlzRW5jb2RpbmcgfHwgZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIGVuY29kaW5nID0gJycgKyBlbmNvZGluZztcbiAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpjYXNlICd1dGY4JzpjYXNlICd1dGYtOCc6Y2FzZSAnYXNjaWknOmNhc2UgJ2JpbmFyeSc6Y2FzZSAnYmFzZTY0JzpjYXNlICd1Y3MyJzpjYXNlICd1Y3MtMic6Y2FzZSAndXRmMTZsZSc6Y2FzZSAndXRmLTE2bGUnOmNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIGlmICghZW5jKSByZXR1cm4gJ3V0ZjgnO1xuICB2YXIgcmV0cmllZDtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuYykge1xuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiAndXRmOCc7XG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gJ3V0ZjE2bGUnO1xuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiAnbGF0aW4xJztcbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gZW5jO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKHJldHJpZWQpIHJldHVybjsgLy8gdW5kZWZpbmVkXG4gICAgICAgIGVuYyA9ICgnJyArIGVuYykudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0cmllZCA9IHRydWU7XG4gICAgfVxuICB9XG59O1xuXG4vLyBEbyBub3QgY2FjaGUgYEJ1ZmZlci5pc0VuY29kaW5nYCB3aGVuIGNoZWNraW5nIGVuY29kaW5nIG5hbWVzIGFzIHNvbWVcbi8vIG1vZHVsZXMgbW9ua2V5LXBhdGNoIGl0IHRvIHN1cHBvcnQgYWRkaXRpb25hbCBlbmNvZGluZ3NcbmZ1bmN0aW9uIG5vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICB2YXIgbmVuYyA9IF9ub3JtYWxpemVFbmNvZGluZyhlbmMpO1xuICBpZiAodHlwZW9mIG5lbmMgIT09ICdzdHJpbmcnICYmIChCdWZmZXIuaXNFbmNvZGluZyA9PT0gaXNFbmNvZGluZyB8fCAhaXNFbmNvZGluZyhlbmMpKSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jKTtcbiAgcmV0dXJuIG5lbmMgfHwgZW5jO1xufVxuXG4vLyBTdHJpbmdEZWNvZGVyIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgZWZmaWNpZW50bHkgc3BsaXR0aW5nIGEgc2VyaWVzIG9mXG4vLyBidWZmZXJzIGludG8gYSBzZXJpZXMgb2YgSlMgc3RyaW5ncyB3aXRob3V0IGJyZWFraW5nIGFwYXJ0IG11bHRpLWJ5dGVcbi8vIGNoYXJhY3RlcnMuXG5leHBvcnRzLlN0cmluZ0RlY29kZXIgPSBTdHJpbmdEZWNvZGVyO1xuZnVuY3Rpb24gU3RyaW5nRGVjb2RlcihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gbm9ybWFsaXplRW5jb2RpbmcoZW5jb2RpbmcpO1xuICB2YXIgbmI7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgdGhpcy50ZXh0ID0gdXRmMTZUZXh0O1xuICAgICAgdGhpcy5lbmQgPSB1dGYxNkVuZDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgdGhpcy5maWxsTGFzdCA9IHV0ZjhGaWxsTGFzdDtcbiAgICAgIG5iID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICB0aGlzLnRleHQgPSBiYXNlNjRUZXh0O1xuICAgICAgdGhpcy5lbmQgPSBiYXNlNjRFbmQ7XG4gICAgICBuYiA9IDM7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhpcy53cml0ZSA9IHNpbXBsZVdyaXRlO1xuICAgICAgdGhpcy5lbmQgPSBzaW1wbGVFbmQ7XG4gICAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIHRoaXMubGFzdFRvdGFsID0gMDtcbiAgdGhpcy5sYXN0Q2hhciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShuYik7XG59XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcnO1xuICB2YXIgcjtcbiAgdmFyIGk7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgciA9IHRoaXMuZmlsbExhc3QoYnVmKTtcbiAgICBpZiAociA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XG4gICAgaSA9IHRoaXMubGFzdE5lZWQ7XG4gICAgdGhpcy5sYXN0TmVlZCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgaSA9IDA7XG4gIH1cbiAgaWYgKGkgPCBidWYubGVuZ3RoKSByZXR1cm4gciA/IHIgKyB0aGlzLnRleHQoYnVmLCBpKSA6IHRoaXMudGV4dChidWYsIGkpO1xuICByZXR1cm4gciB8fCAnJztcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IHV0ZjhFbmQ7XG5cbi8vIFJldHVybnMgb25seSBjb21wbGV0ZSBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS50ZXh0ID0gdXRmOFRleHQ7XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgcGFydGlhbCBub24tVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmZpbGxMYXN0ID0gZnVuY3Rpb24gKGJ1Zikge1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufTtcblxuLy8gQ2hlY2tzIHRoZSB0eXBlIG9mIGEgVVRGLTggYnl0ZSwgd2hldGhlciBpdCdzIEFTQ0lJLCBhIGxlYWRpbmcgYnl0ZSwgb3IgYVxuLy8gY29udGludWF0aW9uIGJ5dGUuIElmIGFuIGludmFsaWQgYnl0ZSBpcyBkZXRlY3RlZCwgLTIgaXMgcmV0dXJuZWQuXG5mdW5jdGlvbiB1dGY4Q2hlY2tCeXRlKGJ5dGUpIHtcbiAgaWYgKGJ5dGUgPD0gMHg3RikgcmV0dXJuIDA7ZWxzZSBpZiAoYnl0ZSA+PiA1ID09PSAweDA2KSByZXR1cm4gMjtlbHNlIGlmIChieXRlID4+IDQgPT09IDB4MEUpIHJldHVybiAzO2Vsc2UgaWYgKGJ5dGUgPj4gMyA9PT0gMHgxRSkgcmV0dXJuIDQ7XG4gIHJldHVybiBieXRlID4+IDYgPT09IDB4MDIgPyAtMSA6IC0yO1xufVxuXG4vLyBDaGVja3MgYXQgbW9zdCAzIGJ5dGVzIGF0IHRoZSBlbmQgb2YgYSBCdWZmZXIgaW4gb3JkZXIgdG8gZGV0ZWN0IGFuXG4vLyBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyLiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzICgyLCAzLCBvciA0KVxuLy8gbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBVVEYtOCBjaGFyYWN0ZXIgKGlmIGFwcGxpY2FibGUpIGFyZSByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0luY29tcGxldGUoc2VsZiwgYnVmLCBpKSB7XG4gIHZhciBqID0gYnVmLmxlbmd0aCAtIDE7XG4gIGlmIChqIDwgaSkgcmV0dXJuIDA7XG4gIHZhciBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAxO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAyO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSB8fCBuYiA9PT0gLTIpIHJldHVybiAwO1xuICBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSB7XG4gICAgICBpZiAobmIgPT09IDIpIG5iID0gMDtlbHNlIHNlbGYubGFzdE5lZWQgPSBuYiAtIDM7XG4gICAgfVxuICAgIHJldHVybiBuYjtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuLy8gVmFsaWRhdGVzIGFzIG1hbnkgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIGFzXG4vLyBuZWVkZWQgb3IgYXJlIGF2YWlsYWJsZS4gSWYgd2Ugc2VlIGEgbm9uLWNvbnRpbnVhdGlvbiBieXRlIHdoZXJlIHdlIGV4cGVjdFxuLy8gb25lLCB3ZSBcInJlcGxhY2VcIiB0aGUgdmFsaWRhdGVkIGNvbnRpbnVhdGlvbiBieXRlcyB3ZSd2ZSBzZWVuIHNvIGZhciB3aXRoXG4vLyBhIHNpbmdsZSBVVEYtOCByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKCdcXHVmZmZkJyksIHRvIG1hdGNoIHY4J3MgVVRGLTggZGVjb2Rpbmdcbi8vIGJlaGF2aW9yLiBUaGUgY29udGludWF0aW9uIGJ5dGUgY2hlY2sgaXMgaW5jbHVkZWQgdGhyZWUgdGltZXMgaW4gdGhlIGNhc2Vcbi8vIHdoZXJlIGFsbCBvZiB0aGUgY29udGludWF0aW9uIGJ5dGVzIGZvciBhIGNoYXJhY3RlciBleGlzdCBpbiB0aGUgc2FtZSBidWZmZXIuXG4vLyBJdCBpcyBhbHNvIGRvbmUgdGhpcyB3YXkgYXMgYSBzbGlnaHQgcGVyZm9ybWFuY2UgaW5jcmVhc2UgaW5zdGVhZCBvZiB1c2luZyBhXG4vLyBsb29wLlxuZnVuY3Rpb24gdXRmOENoZWNrRXh0cmFCeXRlcyhzZWxmLCBidWYsIHApIHtcbiAgaWYgKChidWZbMF0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgIHNlbGYubGFzdE5lZWQgPSAwO1xuICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gIH1cbiAgaWYgKHNlbGYubGFzdE5lZWQgPiAxICYmIGJ1Zi5sZW5ndGggPiAxKSB7XG4gICAgaWYgKChidWZbMV0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgc2VsZi5sYXN0TmVlZCA9IDE7XG4gICAgICByZXR1cm4gJ1xcdWZmZmQnO1xuICAgIH1cbiAgICBpZiAoc2VsZi5sYXN0TmVlZCA+IDIgJiYgYnVmLmxlbmd0aCA+IDIpIHtcbiAgICAgIGlmICgoYnVmWzJdICYgMHhDMCkgIT09IDB4ODApIHtcbiAgICAgICAgc2VsZi5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIEF0dGVtcHRzIHRvIGNvbXBsZXRlIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlci5cbmZ1bmN0aW9uIHV0ZjhGaWxsTGFzdChidWYpIHtcbiAgdmFyIHAgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gIHZhciByID0gdXRmOENoZWNrRXh0cmFCeXRlcyh0aGlzLCBidWYsIHApO1xuICBpZiAociAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcjtcbiAgaWYgKHRoaXMubGFzdE5lZWQgPD0gYnVmLmxlbmd0aCkge1xuICAgIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCBidWYubGVuZ3RoKTtcbiAgdGhpcy5sYXN0TmVlZCAtPSBidWYubGVuZ3RoO1xufVxuXG4vLyBSZXR1cm5zIGFsbCBjb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXJzIGluIGEgQnVmZmVyLiBJZiB0aGUgQnVmZmVyIGVuZGVkIG9uIGFcbi8vIHBhcnRpYWwgY2hhcmFjdGVyLCB0aGUgY2hhcmFjdGVyJ3MgYnl0ZXMgYXJlIGJ1ZmZlcmVkIHVudGlsIHRoZSByZXF1aXJlZFxuLy8gbnVtYmVyIG9mIGJ5dGVzIGFyZSBhdmFpbGFibGUuXG5mdW5jdGlvbiB1dGY4VGV4dChidWYsIGkpIHtcbiAgdmFyIHRvdGFsID0gdXRmOENoZWNrSW5jb21wbGV0ZSh0aGlzLCBidWYsIGkpO1xuICBpZiAoIXRoaXMubGFzdE5lZWQpIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpKTtcbiAgdGhpcy5sYXN0VG90YWwgPSB0b3RhbDtcbiAgdmFyIGVuZCA9IGJ1Zi5sZW5ndGggLSAodG90YWwgLSB0aGlzLmxhc3ROZWVkKTtcbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgMCwgZW5kKTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGksIGVuZCk7XG59XG5cbi8vIEZvciBVVEYtOCwgYSByZXBsYWNlbWVudCBjaGFyYWN0ZXIgaXMgYWRkZWQgd2hlbiBlbmRpbmcgb24gYSBwYXJ0aWFsXG4vLyBjaGFyYWN0ZXIuXG5mdW5jdGlvbiB1dGY4RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArICdcXHVmZmZkJztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFVURi0xNkxFIHR5cGljYWxseSBuZWVkcyB0d28gYnl0ZXMgcGVyIGNoYXJhY3RlciwgYnV0IGV2ZW4gaWYgd2UgaGF2ZSBhbiBldmVuXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXZhaWxhYmxlLCB3ZSBuZWVkIHRvIGNoZWNrIGlmIHdlIGVuZCBvbiBhIGxlYWRpbmcvaGlnaFxuLy8gc3Vycm9nYXRlLiBJbiB0aGF0IGNhc2UsIHdlIG5lZWQgdG8gd2FpdCBmb3IgdGhlIG5leHQgdHdvIGJ5dGVzIGluIG9yZGVyIHRvXG4vLyBkZWNvZGUgdGhlIGxhc3QgY2hhcmFjdGVyIHByb3Blcmx5LlxuZnVuY3Rpb24gdXRmMTZUZXh0KGJ1ZiwgaSkge1xuICBpZiAoKGJ1Zi5sZW5ndGggLSBpKSAlIDIgPT09IDApIHtcbiAgICB2YXIgciA9IGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGkpO1xuICAgIGlmIChyKSB7XG4gICAgICB2YXIgYyA9IHIuY2hhckNvZGVBdChyLmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKGMgPj0gMHhEODAwICYmIGMgPD0gMHhEQkZGKSB7XG4gICAgICAgIHRoaXMubGFzdE5lZWQgPSAyO1xuICAgICAgICB0aGlzLmxhc3RUb3RhbCA9IDQ7XG4gICAgICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIHIuc2xpY2UoMCwgLTEpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMTtcbiAgdGhpcy5sYXN0VG90YWwgPSAyO1xuICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmMTZsZScsIGksIGJ1Zi5sZW5ndGggLSAxKTtcbn1cblxuLy8gRm9yIFVURi0xNkxFIHdlIGRvIG5vdCBleHBsaWNpdGx5IGFwcGVuZCBzcGVjaWFsIHJlcGxhY2VtZW50IGNoYXJhY3RlcnMgaWYgd2Vcbi8vIGVuZCBvbiBhIHBhcnRpYWwgY2hhcmFjdGVyLCB3ZSBzaW1wbHkgbGV0IHY4IGhhbmRsZSB0aGF0LlxuZnVuY3Rpb24gdXRmMTZFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICB2YXIgZW5kID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICAgIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygndXRmMTZsZScsIDAsIGVuZCk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRleHQoYnVmLCBpKSB7XG4gIHZhciBuID0gKGJ1Zi5sZW5ndGggLSBpKSAlIDM7XG4gIGlmIChuID09PSAwKSByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpKTtcbiAgdGhpcy5sYXN0TmVlZCA9IDMgLSBuO1xuICB0aGlzLmxhc3RUb3RhbCA9IDM7XG4gIGlmIChuID09PSAxKSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIH1cbiAgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSwgYnVmLmxlbmd0aCAtIG4pO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgdGhpcy5sYXN0Q2hhci50b1N0cmluZygnYmFzZTY0JywgMCwgMyAtIHRoaXMubGFzdE5lZWQpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gUGFzcyBieXRlcyBvbiB0aHJvdWdoIGZvciBzaW5nbGUtYnl0ZSBlbmNvZGluZ3MgKGUuZy4gYXNjaWksIGxhdGluMSwgaGV4KVxuZnVuY3Rpb24gc2ltcGxlV3JpdGUoYnVmKSB7XG4gIHJldHVybiBidWYudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHNpbXBsZUVuZChidWYpIHtcbiAgcmV0dXJuIGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG59IiwidmFyIGJhc2V4ID0gcmVxdWlyZSgnYmFzZS14JylcbnZhciBBTFBIQUJFVCA9ICcxMjM0NTY3ODlBQkNERUZHSEpLTE1OUFFSU1RVVldYWVphYmNkZWZnaGlqa21ub3BxcnN0dXZ3eHl6J1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2V4KEFMUEhBQkVUKVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJyk7XG52YXIgQnVmZmVyID0gYnVmZmVyLkJ1ZmZlcjtcbnZhciBTbG93QnVmZmVyID0gYnVmZmVyLlNsb3dCdWZmZXI7XG52YXIgTUFYX0xFTiA9IGJ1ZmZlci5rTWF4TGVuZ3RoIHx8IDIxNDc0ODM2NDc7XG5leHBvcnRzLmFsbG9jID0gZnVuY3Rpb24gYWxsb2Moc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBCdWZmZXIuYWxsb2MgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKHNpemUsIGZpbGwsIGVuY29kaW5nKTtcbiAgfVxuICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2VuY29kaW5nIG11c3Qgbm90IGJlIG51bWJlcicpO1xuICB9XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdzaXplIG11c3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBpZiAoc2l6ZSA+IE1BWF9MRU4pIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc2l6ZSBpcyB0b28gbGFyZ2UnKTtcbiAgfVxuICB2YXIgZW5jID0gZW5jb2Rpbmc7XG4gIHZhciBfZmlsbCA9IGZpbGw7XG4gIGlmIChfZmlsbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jID0gdW5kZWZpbmVkO1xuICAgIF9maWxsID0gMDtcbiAgfVxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzaXplKTtcbiAgaWYgKHR5cGVvZiBfZmlsbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YXIgZmlsbEJ1ZiA9IG5ldyBCdWZmZXIoX2ZpbGwsIGVuYyk7XG4gICAgdmFyIGZsZW4gPSBmaWxsQnVmLmxlbmd0aDtcbiAgICB2YXIgaSA9IC0xO1xuICAgIHdoaWxlICgrK2kgPCBzaXplKSB7XG4gICAgICBidWZbaV0gPSBmaWxsQnVmW2kgJSBmbGVuXTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgYnVmLmZpbGwoX2ZpbGwpO1xuICB9XG4gIHJldHVybiBidWY7XG59XG5leHBvcnRzLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gYWxsb2NVbnNhZmUoc2l6ZSkge1xuICBpZiAodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2NVbnNhZmUoc2l6ZSk7XG4gIH1cbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3NpemUgbXVzdCBiZSBhIG51bWJlcicpO1xuICB9XG4gIGlmIChzaXplID4gTUFYX0xFTikge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdzaXplIGlzIHRvbyBsYXJnZScpO1xuICB9XG4gIHJldHVybiBuZXcgQnVmZmVyKHNpemUpO1xufVxuZXhwb3J0cy5mcm9tID0gZnVuY3Rpb24gZnJvbSh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgQnVmZmVyLmZyb20gPT09ICdmdW5jdGlvbicgJiYgKCFnbG9iYWwuVWludDhBcnJheSB8fCBVaW50OEFycmF5LmZyb20gIT09IEJ1ZmZlci5mcm9tKSkge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbSh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBhIG51bWJlcicpO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpO1xuICB9XG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICB2YXIgb2Zmc2V0ID0gZW5jb2RpbmdPck9mZnNldDtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuICAgIHZhciBsZW4gPSBsZW5ndGg7XG4gICAgaWYgKHR5cGVvZiBsZW4gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsZW4gPSB2YWx1ZS5ieXRlTGVuZ3RoIC0gb2Zmc2V0O1xuICAgIH1cbiAgICBpZiAob2Zmc2V0ID49IHZhbHVlLmJ5dGVMZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcXCdvZmZzZXRcXCcgaXMgb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAobGVuID4gdmFsdWUuYnl0ZUxlbmd0aCAtIG9mZnNldCkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ2xlbmd0aFxcJyBpcyBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQnVmZmVyKHZhbHVlLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgbGVuKSk7XG4gIH1cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcih2YWx1ZS5sZW5ndGgpO1xuICAgIHZhbHVlLmNvcHkob3V0LCAwLCAwLCB2YWx1ZS5sZW5ndGgpO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cbiAgaWYgKHZhbHVlKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpIHx8ICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fCAnbGVuZ3RoJyBpbiB2YWx1ZSkge1xuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUpO1xuICAgIH1cbiAgICBpZiAodmFsdWUudHlwZSA9PT0gJ0J1ZmZlcicgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZS5kYXRhKSkge1xuICAgICAgcmV0dXJuIG5ldyBCdWZmZXIodmFsdWUuZGF0YSk7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCAnICsgJ0FycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJyk7XG59XG5leHBvcnRzLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIGFsbG9jVW5zYWZlU2xvdyhzaXplKSB7XG4gIGlmICh0eXBlb2YgQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KHNpemUpO1xuICB9XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdzaXplIG11c3QgYmUgYSBudW1iZXInKTtcbiAgfVxuICBpZiAoc2l6ZSA+PSBNQVhfTEVOKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NpemUgaXMgdG9vIGxhcmdlJyk7XG4gIH1cbiAgcmV0dXJuIG5ldyBTbG93QnVmZmVyKHNpemUpO1xufVxuIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wcm90byAqL1xuXG4ndXNlIHN0cmljdCdcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG52YXIgaWVlZTc1NCA9IHJlcXVpcmUoJ2llZWU3NTQnKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbnZhciBLX01BWF9MRU5HVEggPSAweDdmZmZmZmZmXG5leHBvcnRzLmtNYXhMZW5ndGggPSBLX01BWF9MRU5HVEhcblxuLyoqXG4gKiBJZiBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgOlxuICogICA9PT0gdHJ1ZSAgICBVc2UgVWludDhBcnJheSBpbXBsZW1lbnRhdGlvbiAoZmFzdGVzdClcbiAqICAgPT09IGZhbHNlICAgUHJpbnQgd2FybmluZyBhbmQgcmVjb21tZW5kIHVzaW5nIGBidWZmZXJgIHY0Lnggd2hpY2ggaGFzIGFuIE9iamVjdFxuICogICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiAobW9zdCBjb21wYXRpYmxlLCBldmVuIElFNilcbiAqXG4gKiBCcm93c2VycyB0aGF0IHN1cHBvcnQgdHlwZWQgYXJyYXlzIGFyZSBJRSAxMCssIEZpcmVmb3ggNCssIENocm9tZSA3KywgU2FmYXJpIDUuMSssXG4gKiBPcGVyYSAxMS42KywgaU9TIDQuMisuXG4gKlxuICogV2UgcmVwb3J0IHRoYXQgdGhlIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB0eXBlZCBhcnJheXMgaWYgdGhlIGFyZSBub3Qgc3ViY2xhc3NhYmxlXG4gKiB1c2luZyBfX3Byb3RvX18uIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgXG4gKiAoU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzgpLiBJRSAxMCBsYWNrcyBzdXBwb3J0XG4gKiBmb3IgX19wcm90b19fIGFuZCBoYXMgYSBidWdneSB0eXBlZCBhcnJheSBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgPSB0eXBlZEFycmF5U3VwcG9ydCgpXG5cbmlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmXG4gICAgdHlwZW9mIGNvbnNvbGUuZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgY29uc29sZS5lcnJvcihcbiAgICAnVGhpcyBicm93c2VyIGxhY2tzIHR5cGVkIGFycmF5IChVaW50OEFycmF5KSBzdXBwb3J0IHdoaWNoIGlzIHJlcXVpcmVkIGJ5ICcgK1xuICAgICdgYnVmZmVyYCB2NS54LiBVc2UgYGJ1ZmZlcmAgdjQueCBpZiB5b3UgcmVxdWlyZSBvbGQgYnJvd3NlciBzdXBwb3J0LidcbiAgKVxufVxuXG5mdW5jdGlvbiB0eXBlZEFycmF5U3VwcG9ydCAoKSB7XG4gIC8vIENhbiB0eXBlZCBhcnJheSBpbnN0YW5jZXMgY2FuIGJlIGF1Z21lbnRlZD9cbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMSlcbiAgICBhcnIuX19wcm90b19fID0ge19fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfX1cbiAgICByZXR1cm4gYXJyLmZvbygpID09PSA0MlxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlci5wcm90b3R5cGUsICdwYXJlbnQnLCB7XG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJ1ZmZlclxuICB9XG59KVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLnByb3RvdHlwZSwgJ29mZnNldCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYnl0ZU9mZnNldFxuICB9XG59KVxuXG5mdW5jdGlvbiBjcmVhdGVCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAobGVuZ3RoID4gS19NQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgdHlwZWQgYXJyYXkgbGVuZ3RoJylcbiAgfVxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKVxuICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYnVmXG59XG5cbi8qKlxuICogVGhlIEJ1ZmZlciBjb25zdHJ1Y3RvciByZXR1cm5zIGluc3RhbmNlcyBvZiBgVWludDhBcnJheWAgdGhhdCBoYXZlIHRoZWlyXG4gKiBwcm90b3R5cGUgY2hhbmdlZCB0byBgQnVmZmVyLnByb3RvdHlwZWAuIEZ1cnRoZXJtb3JlLCBgQnVmZmVyYCBpcyBhIHN1YmNsYXNzIG9mXG4gKiBgVWludDhBcnJheWAsIHNvIHRoZSByZXR1cm5lZCBpbnN0YW5jZXMgd2lsbCBoYXZlIGFsbCB0aGUgbm9kZSBgQnVmZmVyYCBtZXRob2RzXG4gKiBhbmQgdGhlIGBVaW50OEFycmF5YCBtZXRob2RzLiBTcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdFxuICogcmV0dXJucyBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBUaGUgYFVpbnQ4QXJyYXlgIHByb3RvdHlwZSByZW1haW5zIHVubW9kaWZpZWQuXG4gKi9cblxuZnVuY3Rpb24gQnVmZmVyIChhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZShhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20oYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG5pZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgJiZcbiAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlciwgU3ltYm9sLnNwZWNpZXMsIHtcbiAgICB2YWx1ZTogbnVsbCxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgd3JpdGFibGU6IGZhbHNlXG4gIH0pXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG5mdW5jdGlvbiBmcm9tICh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmIChpc0FycmF5QnVmZmVyKHZhbHVlKSB8fCAodmFsdWUgJiYgaXNBcnJheUJ1ZmZlcih2YWx1ZS5idWZmZXIpKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQpXG4gIH1cblxuICByZXR1cm4gZnJvbU9iamVjdCh2YWx1ZSlcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbSh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG4vLyBOb3RlOiBDaGFuZ2UgcHJvdG90eXBlICphZnRlciogQnVmZmVyLmZyb20gaXMgZGVmaW5lZCB0byB3b3JrYXJvdW5kIENocm9tZSBidWc6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzE0OFxuQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIoc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxufVxuXG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gQnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG4vKipcbiAqIEVxdWl2YWxlbnQgdG8gU2xvd0J1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICovXG5CdWZmZXIuYWxsb2NVbnNhZmVTbG93ID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgcmV0dXJuIGFsbG9jVW5zYWZlKHNpemUpXG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgfVxuXG4gIGlmICghQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICB9XG5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuXG4gIHZhciBhY3R1YWwgPSBidWYud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIGJ1ZiA9IGJ1Zi5zbGljZSgwLCBhY3R1YWwpXG4gIH1cblxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdmFyIGJ1ZiA9IGNyZWF0ZUJ1ZmZlcihsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICBidWZbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5QnVmZmVyIChhcnJheSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmIChieXRlT2Zmc2V0IDwgMCB8fCBhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcIm9mZnNldFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICBpZiAoYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQgKyAobGVuZ3RoIHx8IDApKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1wibGVuZ3RoXCIgaXMgb3V0c2lkZSBvZiBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIHZhciBidWZcbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5KVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQpXG4gIH0gZWxzZSB7XG4gICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIGJ1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gZnJvbU9iamVjdCAob2JqKSB7XG4gIGlmIChCdWZmZXIuaXNCdWZmZXIob2JqKSkge1xuICAgIHZhciBsZW4gPSBjaGVja2VkKG9iai5sZW5ndGgpIHwgMFxuICAgIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuKVxuXG4gICAgaWYgKGJ1Zi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBidWZcbiAgICB9XG5cbiAgICBvYmouY29weShidWYsIDAsIDAsIGxlbilcbiAgICByZXR1cm4gYnVmXG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhvYmopIHx8ICdsZW5ndGgnIGluIG9iaikge1xuICAgICAgaWYgKHR5cGVvZiBvYmoubGVuZ3RoICE9PSAnbnVtYmVyJyB8fCBudW1iZXJJc05hTihvYmoubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlQnVmZmVyKDApXG4gICAgICB9XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZShvYmopXG4gICAgfVxuXG4gICAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBBcnJheS5pc0FycmF5KG9iai5kYXRhKSkge1xuICAgICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqLmRhdGEpXG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgQXJyYXktbGlrZSBPYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IEtfTUFYX0xFTkdUSGAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBLX01BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsgS19NQVhfTEVOR1RILnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyID09PSB0cnVlXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAoYSwgYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnRzIG11c3QgYmUgQnVmZmVycycpXG4gIH1cblxuICBpZiAoYSA9PT0gYikgcmV0dXJuIDBcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gTWF0aC5taW4oeCwgeSk7IGkgPCBsZW47ICsraSkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICB4ID0gYVtpXVxuICAgICAgeSA9IGJbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uIGlzRW5jb2RpbmcgKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gY29uY2F0IChsaXN0LCBsZW5ndGgpIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMClcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGxlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgICAgbGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV1cbiAgICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KGJ1ZikpIHtcbiAgICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGJ1ZilcbiAgICB9XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgaXNBcnJheUJ1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhpcyBwcm9wZXJ0eSBpcyB1c2VkIGJ5IGBCdWZmZXIuaXNCdWZmZXJgIChhbmQgdGhlIGBpcy1idWZmZXJgIG5wbSBwYWNrYWdlKVxuLy8gdG8gZGV0ZWN0IGEgQnVmZmVyIGluc3RhbmNlLiBJdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgYGluc3RhbmNlb2YgQnVmZmVyYFxuLy8gcmVsaWFibHkgaW4gYSBicm93c2VyaWZ5IGNvbnRleHQgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBtdWx0aXBsZSBkaWZmZXJlbnRcbi8vIGNvcGllcyBvZiB0aGUgJ2J1ZmZlcicgcGFja2FnZSBpbiB1c2UuIFRoaXMgbWV0aG9kIHdvcmtzIGV2ZW4gZm9yIEJ1ZmZlclxuLy8gaW5zdGFuY2VzIHRoYXQgd2VyZSBjcmVhdGVkIGZyb20gYW5vdGhlciBjb3B5IG9mIHRoZSBgYnVmZmVyYCBwYWNrYWdlLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9pc3N1ZXMvMTU0XG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW5ndGggPT09IDApIHJldHVybiAnJ1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCAwLCBsZW5ndGgpXG4gIHJldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcywgYXJndW1lbnRzKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nID0gQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZ1xuXG5CdWZmZXIucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIGlmICh0aGlzID09PSBiKSByZXR1cm4gdHJ1ZVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gIHZhciBzdHIgPSAnJ1xuICB2YXIgbWF4ID0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFU1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB7XG4gICAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKCcgJylcbiAgICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBzdHIgKyAnPidcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5jb21wYXJlID0gZnVuY3Rpb24gY29tcGFyZSAodGFyZ2V0LCBzdGFydCwgZW5kLCB0aGlzU3RhcnQsIHRoaXNFbmQpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGFyZ2V0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICB9XG5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICBpZiAoZW5kID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmQgPSB0YXJnZXQgPyB0YXJnZXQubGVuZ3RoIDogMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNTdGFydCA9IDBcbiAgfVxuICBpZiAodGhpc0VuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpc0VuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IGVuZCA+IHRhcmdldC5sZW5ndGggfHwgdGhpc1N0YXJ0IDwgMCB8fCB0aGlzRW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCAmJiBzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGlmICh0aGlzU3RhcnQgPj0gdGhpc0VuZCkge1xuICAgIHJldHVybiAtMVxuICB9XG4gIGlmIChzdGFydCA+PSBlbmQpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgc3RhcnQgPj4+PSAwXG4gIGVuZCA+Pj49IDBcbiAgdGhpc1N0YXJ0ID4+Pj0gMFxuICB0aGlzRW5kID4+Pj0gMFxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQpIHJldHVybiAwXG5cbiAgdmFyIHggPSB0aGlzRW5kIC0gdGhpc1N0YXJ0XG4gIHZhciB5ID0gZW5kIC0gc3RhcnRcbiAgdmFyIGxlbiA9IE1hdGgubWluKHgsIHkpXG5cbiAgdmFyIHRoaXNDb3B5ID0gdGhpcy5zbGljZSh0aGlzU3RhcnQsIHRoaXNFbmQpXG4gIHZhciB0YXJnZXRDb3B5ID0gdGFyZ2V0LnNsaWNlKHN0YXJ0LCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIGlmICh0aGlzQ29weVtpXSAhPT0gdGFyZ2V0Q29weVtpXSkge1xuICAgICAgeCA9IHRoaXNDb3B5W2ldXG4gICAgICB5ID0gdGFyZ2V0Q29weVtpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbi8vIEZpbmRzIGVpdGhlciB0aGUgZmlyc3QgaW5kZXggb2YgYHZhbGAgaW4gYGJ1ZmZlcmAgYXQgb2Zmc2V0ID49IGBieXRlT2Zmc2V0YCxcbi8vIE9SIHRoZSBsYXN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA8PSBgYnl0ZU9mZnNldGAuXG4vL1xuLy8gQXJndW1lbnRzOlxuLy8gLSBidWZmZXIgLSBhIEJ1ZmZlciB0byBzZWFyY2hcbi8vIC0gdmFsIC0gYSBzdHJpbmcsIEJ1ZmZlciwgb3IgbnVtYmVyXG4vLyAtIGJ5dGVPZmZzZXQgLSBhbiBpbmRleCBpbnRvIGBidWZmZXJgOyB3aWxsIGJlIGNsYW1wZWQgdG8gYW4gaW50MzJcbi8vIC0gZW5jb2RpbmcgLSBhbiBvcHRpb25hbCBlbmNvZGluZywgcmVsZXZhbnQgaXMgdmFsIGlzIGEgc3RyaW5nXG4vLyAtIGRpciAtIHRydWUgZm9yIGluZGV4T2YsIGZhbHNlIGZvciBsYXN0SW5kZXhPZlxuZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YgKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIC8vIEVtcHR5IGJ1ZmZlciBtZWFucyBubyBtYXRjaFxuICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xXG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXRcbiAgaWYgKHR5cGVvZiBieXRlT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gYnl0ZU9mZnNldFxuICAgIGJ5dGVPZmZzZXQgPSAwXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA+IDB4N2ZmZmZmZmYpIHtcbiAgICBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPCAtMHg4MDAwMDAwMCkge1xuICAgIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICB9XG4gIGJ5dGVPZmZzZXQgPSArYnl0ZU9mZnNldCAgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKG51bWJlcklzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKG51bWJlcklzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoID4+PiAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgKGJ5dGVzW2kgKyAxXSAqIDI1NikpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCAoOCAqIGJ5dGVMZW5ndGgpIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgKDggKiBieXRlTGVuZ3RoKSAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IHNob3VsZCBiZSBhIEJ1ZmZlcicpXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gVXNlIGJ1aWx0LWluIHdoZW4gYXZhaWxhYmxlLCBtaXNzaW5nIGZyb20gSUUxMVxuICAgIHRoaXMuY29weVdpdGhpbih0YXJnZXRTdGFydCwgc3RhcnQsIGVuZClcbiAgfSBlbHNlIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAodmFyIGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKChlbmNvZGluZyA9PT0gJ3V0ZjgnICYmIGNvZGUgPCAxMjgpIHx8XG4gICAgICAgICAgZW5jb2RpbmcgPT09ICdsYXRpbjEnKSB7XG4gICAgICAgIC8vIEZhc3QgcGF0aDogSWYgYHZhbGAgZml0cyBpbnRvIGEgc2luZ2xlIGJ5dGUsIHVzZSB0aGF0IG51bWVyaWMgdmFsdWUuXG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiBuZXcgQnVmZmVyKHZhbCwgZW5jb2RpbmcpXG4gICAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aFxuICAgIGlmIChsZW4gPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSB2YWx1ZSBcIicgKyB2YWwgK1xuICAgICAgICAnXCIgaXMgaW52YWxpZCBmb3IgYXJndW1lbnQgXCJ2YWx1ZVwiJylcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSB0YWtlcyBlcXVhbCBzaWducyBhcyBlbmQgb2YgdGhlIEJhc2U2NCBlbmNvZGluZ1xuICBzdHIgPSBzdHIuc3BsaXQoJz0nKVswXVxuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyLnRyaW0oKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gKGxlYWRTdXJyb2dhdGUgLSAweEQ4MDAgPDwgMTAgfCBjb2RlUG9pbnQgLSAweERDMDApICsgMHgxMDAwMFxuICAgIH0gZWxzZSBpZiAobGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgLy8gdmFsaWQgYm1wIGNoYXIsIGJ1dCBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgfVxuXG4gICAgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcblxuICAgIC8vIGVuY29kZSB1dGY4XG4gICAgaWYgKGNvZGVQb2ludCA8IDB4ODApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMSkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChjb2RlUG9pbnQpXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2IHwgMHhDMCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyB8IDB4RTAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDQpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDEyIHwgMHhGMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4QyAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBjb2RlIHBvaW50JylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnl0ZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGKVxuICB9XG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMgKHN0ciwgdW5pdHMpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKChpICsgb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKSBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbi8vIEFycmF5QnVmZmVycyBmcm9tIGFub3RoZXIgY29udGV4dCAoaS5lLiBhbiBpZnJhbWUpIGRvIG5vdCBwYXNzIHRoZSBgaW5zdGFuY2VvZmAgY2hlY2tcbi8vIGJ1dCB0aGV5IHNob3VsZCBiZSB0cmVhdGVkIGFzIHZhbGlkLiBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2lzc3Vlcy8xNjZcbmZ1bmN0aW9uIGlzQXJyYXlCdWZmZXIgKG9iaikge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHxcbiAgICAob2JqICE9IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yICE9IG51bGwgJiYgb2JqLmNvbnN0cnVjdG9yLm5hbWUgPT09ICdBcnJheUJ1ZmZlcicgJiZcbiAgICAgIHR5cGVvZiBvYmouYnl0ZUxlbmd0aCA9PT0gJ251bWJlcicpXG59XG5cbmZ1bmN0aW9uIG51bWJlcklzTmFOIChvYmopIHtcbiAgcmV0dXJuIG9iaiAhPT0gb2JqIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlXG59XG4iLCIvKlxyXG4gQ29weXJpZ2h0IDIwMTMtMjAxNCBEYW5pZWwgV2lydHogPGRjb2RlQGRjb2RlLmlvPlxyXG5cclxuIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XHJcbiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXHJcbiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuXHJcbiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcclxuXHJcbiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXHJcbiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXHJcbiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cclxuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcclxuIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBAbGljZW5zZSBieXRlYnVmZmVyLmpzIChjKSAyMDE1IERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiAqIEJhY2tpbmcgYnVmZmVyOiBBcnJheUJ1ZmZlciwgQWNjZXNzb3I6IFVpbnQ4QXJyYXlcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMFxyXG4gKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL2J5dGVidWZmZXIuanMgZm9yIGRldGFpbHNcclxuICovXHJcbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcclxuXHJcbiAgICAvKiBBTUQgKi8gaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lW1wiYW1kXCJdKVxyXG4gICAgICAgIGRlZmluZShbXCJsb25nXCJdLCBmYWN0b3J5KTtcclxuICAgIC8qIENvbW1vbkpTICovIGVsc2UgaWYgKHR5cGVvZiByZXF1aXJlID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgbW9kdWxlICYmIG1vZHVsZVtcImV4cG9ydHNcIl0pXHJcbiAgICAgICAgbW9kdWxlWydleHBvcnRzJ10gPSAoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHZhciBMb25nOyB0cnkgeyBMb25nID0gcmVxdWlyZShcImxvbmdcIik7IH0gY2F0Y2ggKGUpIHt9XHJcbiAgICAgICAgICAgIHJldHVybiBmYWN0b3J5KExvbmcpO1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAvKiBHbG9iYWwgKi8gZWxzZVxyXG4gICAgICAgIChnbG9iYWxbXCJkY29kZUlPXCJdID0gZ2xvYmFsW1wiZGNvZGVJT1wiXSB8fCB7fSlbXCJCeXRlQnVmZmVyXCJdID0gZmFjdG9yeShnbG9iYWxbXCJkY29kZUlPXCJdW1wiTG9uZ1wiXSk7XHJcblxyXG59KSh0aGlzLCBmdW5jdGlvbihMb25nKSB7XHJcbiAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBjbGFzcyBUaGUgc3dpc3MgYXJteSBrbmlmZSBmb3IgYmluYXJ5IGRhdGEgaW4gSmF2YVNjcmlwdC5cclxuICAgICAqIEBleHBvcnRzIEJ5dGVCdWZmZXJcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBjYXBhY2l0eSBJbml0aWFsIGNhcGFjaXR5LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0NBUEFDSVRZfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG5vQXNzZXJ0IFdoZXRoZXIgdG8gc2tpcCBhc3NlcnRpb25zIG9mIG9mZnNldHMgYW5kIHZhbHVlcy4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgdmFyIEJ5dGVCdWZmZXIgPSBmdW5jdGlvbihjYXBhY2l0eSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgY2FwYWNpdHkgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBjYXBhY2l0eSA9IEJ5dGVCdWZmZXIuREVGQVVMVF9DQVBBQ0lUWTtcclxuICAgICAgICBpZiAodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU47XHJcbiAgICAgICAgaWYgKHR5cGVvZiBub0Fzc2VydCA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIG5vQXNzZXJ0ID0gQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUO1xyXG4gICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgY2FwYWNpdHkgPSBjYXBhY2l0eSB8IDA7XHJcbiAgICAgICAgICAgIGlmIChjYXBhY2l0eSA8IDApXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBjYXBhY2l0eVwiKTtcclxuICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gISFsaXR0bGVFbmRpYW47XHJcbiAgICAgICAgICAgIG5vQXNzZXJ0ID0gISFub0Fzc2VydDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEJhY2tpbmcgQXJyYXlCdWZmZXIuXHJcbiAgICAgICAgICogQHR5cGUgeyFBcnJheUJ1ZmZlcn1cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5idWZmZXIgPSBjYXBhY2l0eSA9PT0gMCA/IEVNUFRZX0JVRkZFUiA6IG5ldyBBcnJheUJ1ZmZlcihjYXBhY2l0eSk7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVpbnQ4QXJyYXkgdXRpbGl6ZWQgdG8gbWFuaXB1bGF0ZSB0aGUgYmFja2luZyBidWZmZXIuIEJlY29tZXMgYG51bGxgIGlmIHRoZSBiYWNraW5nIGJ1ZmZlciBoYXMgYSBjYXBhY2l0eSBvZiBgMGAuXHJcbiAgICAgICAgICogQHR5cGUgez9VaW50OEFycmF5fVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLnZpZXcgPSBjYXBhY2l0eSA9PT0gMCA/IG51bGwgOiBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlcik7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEFic29sdXRlIHJlYWQvd3JpdGUgb2Zmc2V0LlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNmbGlwXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI2NsZWFyXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNYXJrZWQgb2Zmc2V0LlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNtYXJrXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI3Jlc2V0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5tYXJrZWRPZmZzZXQgPSAtMTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQWJzb2x1dGUgbGltaXQgb2YgdGhlIGNvbnRhaW5lZCBkYXRhLiBTZXQgdG8gdGhlIGJhY2tpbmcgYnVmZmVyJ3MgY2FwYWNpdHkgdXBvbiBhbGxvY2F0aW9uLlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNmbGlwXHJcbiAgICAgICAgICogQHNlZSBCeXRlQnVmZmVyI2NsZWFyXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5saW1pdCA9IGNhcGFjaXR5O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIGJpZyBlbmRpYW4uXHJcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubGl0dGxlRW5kaWFuID0gbGl0dGxlRW5kaWFuO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMsIGRlZmF1bHRzIHRvIGBmYWxzZWAuXHJcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubm9Bc3NlcnQgPSBub0Fzc2VydDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCeXRlQnVmZmVyIHZlcnNpb24uXHJcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuVkVSU0lPTiA9IFwiNS4wLjFcIjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIExpdHRsZSBlbmRpYW4gY29uc3RhbnQgdGhhdCBjYW4gYmUgdXNlZCBpbnN0ZWFkIG9mIGl0cyBib29sZWFuIHZhbHVlLiBFdmFsdWF0ZXMgdG8gYHRydWVgLlxyXG4gICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5MSVRUTEVfRU5ESUFOID0gdHJ1ZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJpZyBlbmRpYW4gY29uc3RhbnQgdGhhdCBjYW4gYmUgdXNlZCBpbnN0ZWFkIG9mIGl0cyBib29sZWFuIHZhbHVlLiBFdmFsdWF0ZXMgdG8gYGZhbHNlYC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuQklHX0VORElBTiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVmYXVsdCBpbml0aWFsIGNhcGFjaXR5IG9mIGAxNmAuXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFkgPSAxNjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmF1bHQgZW5kaWFuZXNzIG9mIGBmYWxzZWAgZm9yIGJpZyBlbmRpYW4uXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTiA9IEJ5dGVCdWZmZXIuQklHX0VORElBTjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlZmF1bHQgbm8gYXNzZXJ0aW9ucyBmbGFnIG9mIGBmYWxzZWAuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUID0gZmFsc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGBMb25nYCBjbGFzcyBmb3IgcmVwcmVzZW50aW5nIGEgNjQtYml0IHR3bydzLWNvbXBsZW1lbnQgaW50ZWdlciB2YWx1ZS4gTWF5IGJlIGBudWxsYCBpZiBMb25nLmpzIGhhcyBub3QgYmVlbiBsb2FkZWRcclxuICAgICAqICBhbmQgaW50NjQgc3VwcG9ydCBpcyBub3QgYXZhaWxhYmxlLlxyXG4gICAgICogQHR5cGUgez9Mb25nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL2xvbmcuanNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5Mb25nID0gTG9uZyB8fCBudWxsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGFsaWFzIEJ5dGVCdWZmZXIucHJvdG90eXBlXHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIEJ5dGVCdWZmZXJQcm90b3R5cGUgPSBCeXRlQnVmZmVyLnByb3RvdHlwZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBCeXRlQnVmZmVyIG9yIG5vdC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLl9faXNCeXRlQnVmZmVyX187XHJcblxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEJ5dGVCdWZmZXJQcm90b3R5cGUsIFwiX19pc0J5dGVCdWZmZXJfX1wiLCB7XHJcbiAgICAgICAgdmFsdWU6IHRydWUsXHJcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gaGVscGVyc1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFBcnJheUJ1ZmZlcn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgRU1QVFlfQlVGRkVSID0gbmV3IEFycmF5QnVmZmVyKDApO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3RyaW5nLmZyb21DaGFyQ29kZSByZWZlcmVuY2UgZm9yIGNvbXBpbGUtdGltZSByZW5hbWluZy5cclxuICAgICAqIEB0eXBlIHtmdW5jdGlvbiguLi5udW1iZXIpOnN0cmluZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgc3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBzb3VyY2UgZnVuY3Rpb24gZm9yIGEgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHMgU3RyaW5nIHRvIHJlYWQgZnJvbVxyXG4gICAgICogQHJldHVybnMge2Z1bmN0aW9uKCk6bnVtYmVyfG51bGx9IFNvdXJjZSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseSBgbnVsbGAgaWYgdGhlcmUgYXJlXHJcbiAgICAgKiAgbm8gbW9yZSBjaGFyYWN0ZXJzIGxlZnQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIHRoZSBhcmd1bWVudCBpcyBpbnZhbGlkXHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gc3RyaW5nU291cmNlKHMpIHtcclxuICAgICAgICB2YXIgaT0wOyByZXR1cm4gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBpIDwgcy5sZW5ndGggPyBzLmNoYXJDb2RlQXQoaSsrKSA6IG51bGw7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBkZXN0aW5hdGlvbiBmdW5jdGlvbiBmb3IgYSBzdHJpbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7ZnVuY3Rpb24obnVtYmVyPSk6dW5kZWZpbmVkfHN0cmluZ30gRGVzdGluYXRpb24gZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIHRoZSBuZXh0IGNoYXIgY29kZS5cclxuICAgICAqICBSZXR1cm5zIHRoZSBmaW5hbCBzdHJpbmcgd2hlbiBjYWxsZWQgd2l0aG91dCBhcmd1bWVudHMuXHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gc3RyaW5nRGVzdGluYXRpb24oKSB7XHJcbiAgICAgICAgdmFyIGNzID0gW10sIHBzID0gW107IHJldHVybiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHMuam9pbignJykrc3RyaW5nRnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY3MpO1xyXG4gICAgICAgICAgICBpZiAoY3MubGVuZ3RoICsgYXJndW1lbnRzLmxlbmd0aCA+IDEwMjQpXHJcbiAgICAgICAgICAgICAgICBwcy5wdXNoKHN0cmluZ0Zyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNzKSksXHJcbiAgICAgICAgICAgICAgICAgICAgY3MubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoY3MsIGFyZ3VtZW50cyk7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGFjY2Vzc29yIHR5cGUuXHJcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IGBCdWZmZXJgIHVuZGVyIG5vZGUuanMsIGBVaW50OEFycmF5YCByZXNwZWN0aXZlbHkgYERhdGFWaWV3YCBpbiB0aGUgYnJvd3NlciAoY2xhc3NlcylcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5hY2Nlc3NvciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBVaW50OEFycmF5O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQWxsb2NhdGVzIGEgbmV3IEJ5dGVCdWZmZXIgYmFja2VkIGJ5IGEgYnVmZmVyIG9mIHRoZSBzcGVjaWZpZWQgY2FwYWNpdHkuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGNhcGFjaXR5IEluaXRpYWwgY2FwYWNpdHkuIERlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfQ0FQQUNJVFl9LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmFsbG9jYXRlID0gZnVuY3Rpb24oY2FwYWNpdHksIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEJ5dGVCdWZmZXIoY2FwYWNpdHksIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbmNhdGVuYXRlcyBtdWx0aXBsZSBCeXRlQnVmZmVycyBpbnRvIG9uZS5cclxuICAgICAqIEBwYXJhbSB7IUFycmF5LjwhQnl0ZUJ1ZmZlcnwhQXJyYXlCdWZmZXJ8IVVpbnQ4QXJyYXl8c3RyaW5nPn0gYnVmZmVycyBCdWZmZXJzIHRvIGNvbmNhdGVuYXRlXHJcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8Ym9vbGVhbik9fSBlbmNvZGluZyBTdHJpbmcgZW5jb2RpbmcgaWYgYGJ1ZmZlcnNgIGNvbnRhaW5zIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLFxyXG4gICAgICogIGRlZmF1bHRzIHRvIFwidXRmOFwiKVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIgZm9yIHRoZSByZXN1bHRpbmcgQnl0ZUJ1ZmZlci4gRGVmYXVsdHNcclxuICAgICAqICB0byB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMgZm9yIHRoZSByZXN1bHRpbmcgQnl0ZUJ1ZmZlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX05PQVNTRVJUfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQ29uY2F0ZW5hdGVkIEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbihidWZmZXJzLCBlbmNvZGluZywgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdib29sZWFuJyB8fCB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIG5vQXNzZXJ0ID0gbGl0dGxlRW5kaWFuO1xyXG4gICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBlbmNvZGluZztcclxuICAgICAgICAgICAgZW5jb2RpbmcgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjYXBhY2l0eSA9IDA7XHJcbiAgICAgICAgZm9yICh2YXIgaT0wLCBrPWJ1ZmZlcnMubGVuZ3RoLCBsZW5ndGg7IGk8azsgKytpKSB7XHJcbiAgICAgICAgICAgIGlmICghQnl0ZUJ1ZmZlci5pc0J5dGVCdWZmZXIoYnVmZmVyc1tpXSkpXHJcbiAgICAgICAgICAgICAgICBidWZmZXJzW2ldID0gQnl0ZUJ1ZmZlci53cmFwKGJ1ZmZlcnNbaV0sIGVuY29kaW5nKTtcclxuICAgICAgICAgICAgbGVuZ3RoID0gYnVmZmVyc1tpXS5saW1pdCAtIGJ1ZmZlcnNbaV0ub2Zmc2V0O1xyXG4gICAgICAgICAgICBpZiAobGVuZ3RoID4gMCkgY2FwYWNpdHkgKz0gbGVuZ3RoO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY2FwYWNpdHkgPT09IDApXHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnl0ZUJ1ZmZlcigwLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICB2YXIgYmIgPSBuZXcgQnl0ZUJ1ZmZlcihjYXBhY2l0eSwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCksXHJcbiAgICAgICAgICAgIGJpO1xyXG4gICAgICAgIGk9MDsgd2hpbGUgKGk8aykge1xyXG4gICAgICAgICAgICBiaSA9IGJ1ZmZlcnNbaSsrXTtcclxuICAgICAgICAgICAgbGVuZ3RoID0gYmkubGltaXQgLSBiaS5vZmZzZXQ7XHJcbiAgICAgICAgICAgIGlmIChsZW5ndGggPD0gMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGJiLnZpZXcuc2V0KGJpLnZpZXcuc3ViYXJyYXkoYmkub2Zmc2V0LCBiaS5saW1pdCksIGJiLm9mZnNldCk7XHJcbiAgICAgICAgICAgIGJiLm9mZnNldCArPSBsZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJiLmxpbWl0ID0gYmIub2Zmc2V0O1xyXG4gICAgICAgIGJiLm9mZnNldCA9IDA7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdHlwZSBpcyBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0geyp9IGJiIEJ5dGVCdWZmZXIgdG8gdGVzdFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBpdCBpcyBhIEJ5dGVCdWZmZXIsIG90aGVyd2lzZSBgZmFsc2VgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuaXNCeXRlQnVmZmVyID0gZnVuY3Rpb24oYmIpIHtcclxuICAgICAgICByZXR1cm4gKGJiICYmIGJiW1wiX19pc0J5dGVCdWZmZXJfX1wiXSkgPT09IHRydWU7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBiYWNraW5nIGJ1ZmZlciB0eXBlLlxyXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBgQnVmZmVyYCB1bmRlciBub2RlLmpzLCBgQXJyYXlCdWZmZXJgIGluIHRoZSBicm93c2VyIChjbGFzc2VzKVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLnR5cGUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICByZXR1cm4gQXJyYXlCdWZmZXI7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBXcmFwcyBhIGJ1ZmZlciBvciBhIHN0cmluZy4gU2V0cyB0aGUgYWxsb2NhdGVkIEJ5dGVCdWZmZXIncyB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IHRvIGAwYCBhbmQgaXRzXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9IHRvIHRoZSBsZW5ndGggb2YgdGhlIHdyYXBwZWQgZGF0YS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ8IUFycmF5QnVmZmVyfCFVaW50OEFycmF5fHN0cmluZ3whQXJyYXkuPG51bWJlcj59IGJ1ZmZlciBBbnl0aGluZyB0aGF0IGNhbiBiZSB3cmFwcGVkXHJcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8Ym9vbGVhbik9fSBlbmNvZGluZyBTdHJpbmcgZW5jb2RpbmcgaWYgYGJ1ZmZlcmAgaXMgYSBzdHJpbmcgKFwiYmFzZTY0XCIsIFwiaGV4XCIsIFwiYmluYXJ5XCIsIGRlZmF1bHRzIHRvXHJcbiAgICAgKiAgXCJ1dGY4XCIpXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEEgQnl0ZUJ1ZmZlciB3cmFwcGluZyBgYnVmZmVyYFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLndyYXAgPSBmdW5jdGlvbihidWZmZXIsIGVuY29kaW5nLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgbm9Bc3NlcnQgPSBsaXR0bGVFbmRpYW47XHJcbiAgICAgICAgICAgIGxpdHRsZUVuZGlhbiA9IGVuY29kaW5nO1xyXG4gICAgICAgICAgICBlbmNvZGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHR5cGVvZiBidWZmZXIgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBcInV0ZjhcIjtcclxuICAgICAgICAgICAgc3dpdGNoIChlbmNvZGluZykge1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcImJhc2U2NFwiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21CYXNlNjQoYnVmZmVyLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcImhleFwiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21IZXgoYnVmZmVyLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcImJpbmFyeVwiOlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBCeXRlQnVmZmVyLmZyb21CaW5hcnkoYnVmZmVyLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcInV0ZjhcIjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tVVRGOChidWZmZXIsIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiZGVidWdcIjpcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tRGVidWcoYnVmZmVyLCBsaXR0bGVFbmRpYW4pO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcIlVuc3VwcG9ydGVkIGVuY29kaW5nOiBcIitlbmNvZGluZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJ1ZmZlciA9PT0gbnVsbCB8fCB0eXBlb2YgYnVmZmVyICE9PSAnb2JqZWN0JylcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBidWZmZXJcIik7XHJcbiAgICAgICAgdmFyIGJiO1xyXG4gICAgICAgIGlmIChCeXRlQnVmZmVyLmlzQnl0ZUJ1ZmZlcihidWZmZXIpKSB7XHJcbiAgICAgICAgICAgIGJiID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5jbG9uZS5jYWxsKGJ1ZmZlcik7XHJcbiAgICAgICAgICAgIGJiLm1hcmtlZE9mZnNldCA9IC0xO1xyXG4gICAgICAgICAgICByZXR1cm4gYmI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7IC8vIEV4dHJhY3QgQXJyYXlCdWZmZXIgZnJvbSBVaW50OEFycmF5XHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoMCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICAgICAgICAgIGlmIChidWZmZXIubGVuZ3RoID4gMCkgeyAvLyBBdm9pZCByZWZlcmVuY2VzIHRvIG1vcmUgdGhhbiBvbmUgRU1QVFlfQlVGRkVSXHJcbiAgICAgICAgICAgICAgICBiYi5idWZmZXIgPSBidWZmZXIuYnVmZmVyO1xyXG4gICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gYnVmZmVyLmJ5dGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICBiYi5saW1pdCA9IGJ1ZmZlci5ieXRlT2Zmc2V0ICsgYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBiYi52aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyLmJ1ZmZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7IC8vIFJldXNlIEFycmF5QnVmZmVyXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoMCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCk7XHJcbiAgICAgICAgICAgIGlmIChidWZmZXIuYnl0ZUxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGJiLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgICAgICAgICAgICAgIGJiLm9mZnNldCA9IDA7XHJcbiAgICAgICAgICAgICAgICBiYi5saW1pdCA9IGJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgYmIudmlldyA9IGJ1ZmZlci5ieXRlTGVuZ3RoID4gMCA/IG5ldyBVaW50OEFycmF5KGJ1ZmZlcikgOiBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYnVmZmVyKSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiKSB7IC8vIENyZWF0ZSBmcm9tIG9jdGV0c1xyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKGJ1ZmZlci5sZW5ndGgsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpO1xyXG4gICAgICAgICAgICBiYi5saW1pdCA9IGJ1ZmZlci5sZW5ndGg7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGk9MDsgaTxidWZmZXIubGVuZ3RoOyArK2kpXHJcbiAgICAgICAgICAgICAgICBiYi52aWV3W2ldID0gYnVmZmVyW2ldO1xyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJ1ZmZlclwiKTsgLy8gT3RoZXJ3aXNlIGZhaWxcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIHRoZSBhcnJheSBhcyBhIGJpdHNldC5cclxuICAgICAqIEBwYXJhbSB7QXJyYXk8Ym9vbGVhbj59IHZhbHVlIEFycmF5IG9mIGJvb2xlYW5zIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgbGVuZ3RoYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlQml0U2V0ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSlcclxuICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgQml0U2V0OiBOb3QgYW4gYXJyYXlcIik7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgYml0cyA9IHZhbHVlLmxlbmd0aCxcclxuICAgICAgICAgIGJ5dGVzID0gKGJpdHMgPj4gMyksXHJcbiAgICAgICAgICBiaXQgPSAwLFxyXG4gICAgICAgICAgaztcclxuXHJcbiAgICAgIG9mZnNldCArPSB0aGlzLndyaXRlVmFyaW50MzIoYml0cyxvZmZzZXQpO1xyXG5cclxuICAgICAgd2hpbGUoYnl0ZXMtLSkge1xyXG4gICAgICAgIGsgPSAoISF2YWx1ZVtiaXQrK10gJiAxKSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCAxKSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCAyKSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCAzKSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCA0KSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCA1KSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCA2KSB8XHJcbiAgICAgICAgICAgICgoISF2YWx1ZVtiaXQrK10gJiAxKSA8PCA3KTtcclxuICAgICAgICB0aGlzLndyaXRlQnl0ZShrLG9mZnNldCsrKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYoYml0IDwgYml0cykge1xyXG4gICAgICAgIHZhciBtID0gMDsgayA9IDA7XHJcbiAgICAgICAgd2hpbGUoYml0IDwgYml0cykgayA9IGsgfCAoKCEhdmFsdWVbYml0KytdICYgMSkgPDwgKG0rKykpO1xyXG4gICAgICAgIHRoaXMud3JpdGVCeXRlKGssb2Zmc2V0KyspO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gb2Zmc2V0IC0gc3RhcnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIEJpdFNldCBhcyBhbiBhcnJheSBvZiBib29sZWFucy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGBsZW5ndGhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXk8Ym9vbGVhbj5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkQml0U2V0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcblxyXG4gICAgICB2YXIgcmV0ID0gdGhpcy5yZWFkVmFyaW50MzIob2Zmc2V0KSxcclxuICAgICAgICAgIGJpdHMgPSByZXQudmFsdWUsXHJcbiAgICAgICAgICBieXRlcyA9IChiaXRzID4+IDMpLFxyXG4gICAgICAgICAgYml0ID0gMCxcclxuICAgICAgICAgIHZhbHVlID0gW10sXHJcbiAgICAgICAgICBrO1xyXG5cclxuICAgICAgb2Zmc2V0ICs9IHJldC5sZW5ndGg7XHJcblxyXG4gICAgICB3aGlsZShieXRlcy0tKSB7XHJcbiAgICAgICAgayA9IHRoaXMucmVhZEJ5dGUob2Zmc2V0KyspO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDAxKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgwMik7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MDQpO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDA4KTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHgxMCk7XHJcbiAgICAgICAgdmFsdWVbYml0KytdID0gISEoayAmIDB4MjApO1xyXG4gICAgICAgIHZhbHVlW2JpdCsrXSA9ICEhKGsgJiAweDQwKTtcclxuICAgICAgICB2YWx1ZVtiaXQrK10gPSAhIShrICYgMHg4MCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmKGJpdCA8IGJpdHMpIHtcclxuICAgICAgICB2YXIgbSA9IDA7XHJcbiAgICAgICAgayA9IHRoaXMucmVhZEJ5dGUob2Zmc2V0KyspO1xyXG4gICAgICAgIHdoaWxlKGJpdCA8IGJpdHMpIHZhbHVlW2JpdCsrXSA9ICEhKChrID4+IChtKyspKSAmIDEpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJ5dGVzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgYnl0ZXMgdG8gcmVhZFxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYGxlbmd0aGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn1cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkQnl0ZXMgPSBmdW5jdGlvbihsZW5ndGgsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIGxlbmd0aCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiK2xlbmd0aCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc2xpY2UgPSB0aGlzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgbGVuZ3RoKTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IGxlbmd0aDtcbiAgICAgICAgcmV0dXJuIHNsaWNlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIHBheWxvYWQgb2YgYnl0ZXMuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjYXBwZW5kfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcnwhQXJyYXlCdWZmZXJ8IVVpbnQ4QXJyYXl8c3RyaW5nfSBzb3VyY2UgRGF0YSB0byB3cml0ZS4gSWYgYHNvdXJjZWAgaXMgYSBCeXRlQnVmZmVyLCBpdHMgb2Zmc2V0c1xyXG4gICAgICogIHdpbGwgYmUgbW9kaWZpZWQgYWNjb3JkaW5nIHRvIHRoZSBwZXJmb3JtZWQgcmVhZCBvcGVyYXRpb24uXHJcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKT19IGVuY29kaW5nIEVuY29kaW5nIGlmIGBkYXRhYCBpcyBhIHN0cmluZyAoXCJiYXNlNjRcIiwgXCJoZXhcIiwgXCJiaW5hcnlcIiwgZGVmYXVsdHMgdG8gXCJ1dGY4XCIpXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUJ5dGVzID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5hcHBlbmQ7XHJcblxyXG4gICAgLy8gdHlwZXMvaW50cy9pbnQ4XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gOGJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICB2YXIgY2FwYWNpdHkwID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTAgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTAgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gMTtcbiAgICAgICAgdGhpcy52aWV3W29mZnNldF0gPSB2YWx1ZTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDE7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiA4Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlSW50OH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVCeXRlID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludDg7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiA4Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmlld1tvZmZzZXRdO1xyXG4gICAgICAgIGlmICgodmFsdWUgJiAweDgwKSA9PT0gMHg4MCkgdmFsdWUgPSAtKDB4RkYgLSB2YWx1ZSArIDEpOyAvLyBDYXN0IHRvIHNpZ25lZFxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIDhiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEludDh9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRCeXRlID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50ODtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiA4Yml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDggPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgdmFyIGNhcGFjaXR5MSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTEpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDE7XG4gICAgICAgIHRoaXMudmlld1tvZmZzZXRdID0gdmFsdWU7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAxO1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gOGJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVWludDh9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGFkdmFuY2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgMWAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVUludDggPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDg7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhbiA4Yml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDEgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIisxK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmlld1tvZmZzZXRdO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIDhiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkVWludDh9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAxYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVSW50OCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQ4O1xyXG5cclxuICAgIC8vIHR5cGVzL2ludHMvaW50MTZcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDE2Yml0IHNpZ25lZCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIG9yIGB2YWx1ZWAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQxNiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgdmFyIGNhcGFjaXR5MiA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTIpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkyICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkyIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDI7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlICYgMHhGRjAwKSA+Pj4gODtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICB2YWx1ZSAmIDB4MDBGRjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0XSAgID0gKHZhbHVlICYgMHhGRjAwKSA+Pj4gODtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICB2YWx1ZSAmIDB4MDBGRjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSAyO1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAxNmJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUludDE2fS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIG9yIGB2YWx1ZWAgaXMgbm90IGEgdmFsaWQgbnVtYmVyXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBvdXQgb2YgYm91bmRzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVTaG9ydCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQxNjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMTZiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBpcyBub3QgYSB2YWxpZCBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG91dCBvZiBib3VuZHNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50MTYgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAyID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMitcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSAwO1xyXG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xyXG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDg7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCAgXSA8PCA4O1xyXG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKHZhbHVlICYgMHg4MDAwKSA9PT0gMHg4MDAwKSB2YWx1ZSA9IC0oMHhGRkZGIC0gdmFsdWUgKyAxKTsgLy8gQ2FzdCB0byBzaWduZWRcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDI7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDE2Yml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRJbnQxNn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRTaG9ydCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEludDE2O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMTZiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBvciBgdmFsdWVgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDE2ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICAgIHZhciBjYXBhY2l0eTMgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkzKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MyAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MyA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSAyO1xuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9ICh2YWx1ZSAmIDB4RkYwMCkgPj4+IDg7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgdmFsdWUgJiAweDAwRkY7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldF0gICA9ICh2YWx1ZSAmIDB4RkYwMCkgPj4+IDg7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAgdmFsdWUgJiAweDAwRkY7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMTZiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZVVpbnQxNn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGAyYCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgb2Zmc2V0YCBvciBgdmFsdWVgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVUludDE2ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQxNjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMTZiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50MTYgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAyID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMitcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSAwO1xyXG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICB2YWx1ZSAgPSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xyXG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDg7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCAgXSA8PCA4O1xyXG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDI7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDE2Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZFVpbnQxNn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBhZHZhbmNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDJgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVSW50MTYgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50MTY7XHJcblxyXG4gICAgLy8gdHlwZXMvaW50cy9pbnQzMlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgMzJiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQzMiA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gNDtcbiAgICAgICAgdmFyIGNhcGFjaXR5NCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTQpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk0ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk0IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDQ7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICB2YWx1ZSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAodmFsdWUgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9ICh2YWx1ZSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgdmFsdWUgICAgICAgICAmIDB4RkY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCBzaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUludDMyfS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUludCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJbnQzMjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSW50MzIgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrNCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSAwO1xyXG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgIHZhbHVlICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWUgfD0gMDsgLy8gQ2FzdCB0byBzaWduZWRcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IHNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRJbnQzMn0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgYWR2YW5jZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQzMjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVaW50MzIgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyB8fCB2YWx1ZSAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIHZhbHVlID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICBvZmZzZXQgKz0gNDtcbiAgICAgICAgdmFyIGNhcGFjaXR5NSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTUpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHk1ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHk1IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IDQ7XG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICh2YWx1ZSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAodmFsdWUgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICB2YWx1ZSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAodmFsdWUgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKHZhbHVlID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9ICh2YWx1ZSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgdmFsdWUgICAgICAgICAmIDB4RkY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlVWludDMyfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVUludDMyID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVpbnQzMjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50MzIgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrNCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdmFsdWUgPSAwO1xyXG4gICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xuICAgICAgICAgICAgdmFsdWUgID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgIHZhbHVlIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgdmFsdWUgKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICB2YWx1ZSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgdmFsdWUgfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgIHZhbHVlICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSAzMmJpdCB1bnNpZ25lZCBpbnRlZ2VyLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3JlYWRVaW50MzJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVUludDMyID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVWludDMyO1xyXG5cclxuICAgIC8vIHR5cGVzL2ludHMvaW50NjRcclxuXHJcbiAgICBpZiAoTG9uZykge1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBXcml0ZXMgYSA2NGJpdCBzaWduZWQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50NjQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoISh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIExvbmcpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIgb3IgTG9uZylcIik7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDg7XG4gICAgICAgICAgICB2YXIgY2FwYWNpdHk2ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTYpXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5NiAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5NiA6IG9mZnNldCk7XG4gICAgICAgICAgICBvZmZzZXQgLT0gODtcbiAgICAgICAgICAgIHZhciBsbyA9IHZhbHVlLmxvdyxcclxuICAgICAgICAgICAgICAgIGhpID0gdmFsdWUuaGlnaDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gKGxvID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAobG8gPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChsbyA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gIGxvICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChoaSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGhpID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoaGkgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBoaSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0ICBdID0gKGhpID4+PiAyNCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoaGkgPj4+IDE2KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChoaSA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzNdID0gIGhpICAgICAgICAgJiAweEZGO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChsbyA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGxvID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAobG8gPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBsbyAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVJbnQ2NH0uXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUxvbmcgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlSW50NjQ7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyA4ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgbG8gPSAwLFxyXG4gICAgICAgICAgICAgICAgaGkgPSAwO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcclxuICAgICAgICAgICAgICAgIGxvICA9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgMTY7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAgODtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0ICBdO1xuICAgICAgICAgICAgICAgIGxvICs9IHRoaXMudmlld1tvZmZzZXQrM10gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICBoaSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgICAgICBoaSArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGhpICA9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgMTY7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAgODtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzNdO1xuICAgICAgICAgICAgICAgIGhpICs9IHRoaXMudmlld1tvZmZzZXQgIF0gPDwgMjQgPj4+IDA7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ICs9IDQ7XHJcbiAgICAgICAgICAgICAgICBsbyAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgICAgICBsbyArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBuZXcgTG9uZyhsbywgaGksIGZhbHNlKTtcclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEludDY0fS5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZExvbmcgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRJbnQ2NDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV3JpdGVzIGEgNjRiaXQgdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA4YCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDY0ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCEodmFsdWUgJiYgdmFsdWUgaW5zdGFuY2VvZiBMb25nKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyIG9yIExvbmcpXCIpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIG9mZnNldCArPSA4O1xuICAgICAgICAgICAgdmFyIGNhcGFjaXR5NyA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk3KVxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTcgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTcgOiBvZmZzZXQpO1xuICAgICAgICAgICAgb2Zmc2V0IC09IDg7XG4gICAgICAgICAgICB2YXIgbG8gPSB2YWx1ZS5sb3csXHJcbiAgICAgICAgICAgICAgICBoaSA9IHZhbHVlLmhpZ2g7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9IChsbyA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGxvID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAobG8gPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9ICBsbyAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAoaGkgPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsyXSA9IChoaSA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGhpID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgaGkgICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCAgXSA9IChoaSA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzFdID0gKGhpID4+PiAxNikgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoaGkgPj4+ICA4KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCszXSA9ICBoaSAgICAgICAgICYgMHhGRjtcbiAgICAgICAgICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAobG8gPj4+IDI0KSAmIDB4RkY7XG4gICAgICAgICAgICAgICAgdGhpcy52aWV3W29mZnNldCsxXSA9IChsbyA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gKGxvID4+PiAgOCkgJiAweEZGO1xuICAgICAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgbG8gICAgICAgICAmIDB4RkY7XG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIDY0Yml0IHVuc2lnbmVkIGludGVnZXIuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjd3JpdGVVaW50NjR9LlxyXG4gICAgICAgICAqIEBmdW5jdGlvblxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVVSW50NjQgPSBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlVWludDY0O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWFkcyBhIDY0Yml0IHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVaW50NjQgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgOCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis4K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGxvID0gMCxcclxuICAgICAgICAgICAgICAgIGhpID0gMDtcclxuICAgICAgICAgICAgaWYgKHRoaXMubGl0dGxlRW5kaWFuKSB7XHJcbiAgICAgICAgICAgICAgICBsbyAgPSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrMV0gPDwgIDg7XG4gICAgICAgICAgICAgICAgbG8gfD0gdGhpcy52aWV3W29mZnNldCAgXTtcbiAgICAgICAgICAgICAgICBsbyArPSB0aGlzLnZpZXdbb2Zmc2V0KzNdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgaGkgID0gdGhpcy52aWV3W29mZnNldCsyXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBoaSB8PSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQgIF07XG4gICAgICAgICAgICAgICAgaGkgKz0gdGhpcy52aWV3W29mZnNldCszXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBoaSAgPSB0aGlzLnZpZXdbb2Zmc2V0KzFdIDw8IDE2O1xuICAgICAgICAgICAgICAgIGhpIHw9IHRoaXMudmlld1tvZmZzZXQrMl0gPDwgIDg7XG4gICAgICAgICAgICAgICAgaGkgfD0gdGhpcy52aWV3W29mZnNldCszXTtcbiAgICAgICAgICAgICAgICBoaSArPSB0aGlzLnZpZXdbb2Zmc2V0ICBdIDw8IDI0ID4+PiAwO1xuICAgICAgICAgICAgICAgIG9mZnNldCArPSA0O1xyXG4gICAgICAgICAgICAgICAgbG8gID0gdGhpcy52aWV3W29mZnNldCsxXSA8PCAxNjtcbiAgICAgICAgICAgICAgICBsbyB8PSB0aGlzLnZpZXdbb2Zmc2V0KzJdIDw8ICA4O1xuICAgICAgICAgICAgICAgIGxvIHw9IHRoaXMudmlld1tvZmZzZXQrM107XG4gICAgICAgICAgICAgICAgbG8gKz0gdGhpcy52aWV3W29mZnNldCAgXSA8PCAyNCA+Pj4gMDtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gbmV3IExvbmcobG8sIGhpLCB0cnVlKTtcclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA4O1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgNjRiaXQgdW5zaWduZWQgaW50ZWdlci4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkVWludDY0fS5cclxuICAgICAgICAgKiBAZnVuY3Rpb25cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVJbnQ2NCA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFVpbnQ2NDtcclxuXHJcbiAgICB9IC8vIExvbmdcclxuXHJcblxyXG4gICAgLy8gdHlwZXMvZmxvYXRzL2Zsb2F0MzJcclxuXHJcbiAgICAvKlxyXG4gICAgIGllZWU3NTQgLSBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2llZWU3NTRcclxuXHJcbiAgICAgVGhlIE1JVCBMaWNlbnNlIChNSVQpXHJcblxyXG4gICAgIENvcHlyaWdodCAoYykgRmVyb3NzIEFib3VraGFkaWplaFxyXG5cclxuICAgICBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XHJcbiAgICAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxyXG4gICAgIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcclxuICAgICB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXHJcbiAgICAgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXHJcbiAgICAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcclxuXHJcbiAgICAgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cclxuICAgICBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cclxuXHJcbiAgICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxyXG4gICAgIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxyXG4gICAgIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxyXG4gICAgIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcclxuICAgICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxyXG4gICAgIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cclxuICAgICBUSEUgU09GVFdBUkUuXHJcbiAgICAqL1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gSUVFRTc1NCBmbG9hdCBmcm9tIGEgYnl0ZSBhcnJheS5cclxuICAgICAqIEBwYXJhbSB7IUFycmF5fSBidWZmZXJcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNMRVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1MZW5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuQnl0ZXNcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gaWVlZTc1NF9yZWFkKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcclxuICAgICAgICB2YXIgZSwgbSxcclxuICAgICAgICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcclxuICAgICAgICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcclxuICAgICAgICAgICAgZUJpYXMgPSBlTWF4ID4+IDEsXHJcbiAgICAgICAgICAgIG5CaXRzID0gLTcsXHJcbiAgICAgICAgICAgIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMCxcclxuICAgICAgICAgICAgZCA9IGlzTEUgPyAtMSA6IDEsXHJcbiAgICAgICAgICAgIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV07XHJcblxyXG4gICAgICAgIGkgKz0gZDtcclxuXHJcbiAgICAgICAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XHJcbiAgICAgICAgcyA+Pj0gKC1uQml0cyk7XHJcbiAgICAgICAgbkJpdHMgKz0gZUxlbjtcclxuICAgICAgICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxyXG5cclxuICAgICAgICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcclxuICAgICAgICBlID4+PSAoLW5CaXRzKTtcclxuICAgICAgICBuQml0cyArPSBtTGVuO1xyXG4gICAgICAgIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XHJcblxyXG4gICAgICAgIGlmIChlID09PSAwKSB7XHJcbiAgICAgICAgICAgIGUgPSAxIC0gZUJpYXM7XHJcbiAgICAgICAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xyXG4gICAgICAgICAgICBlID0gZSAtIGVCaWFzO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiBJRUVFNzU0IGZsb2F0IHRvIGEgYnl0ZSBhcnJheS5cclxuICAgICAqIEBwYXJhbSB7IUFycmF5fSBidWZmZXJcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBpc0xFXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbUxlblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG5CeXRlc1xyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGllZWU3NTRfd3JpdGUoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcclxuICAgICAgICB2YXIgZSwgbSwgYyxcclxuICAgICAgICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcclxuICAgICAgICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcclxuICAgICAgICAgICAgZUJpYXMgPSBlTWF4ID4+IDEsXHJcbiAgICAgICAgICAgIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKSxcclxuICAgICAgICAgICAgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpLFxyXG4gICAgICAgICAgICBkID0gaXNMRSA/IDEgOiAtMSxcclxuICAgICAgICAgICAgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMDtcclxuXHJcbiAgICAgICAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSk7XHJcblxyXG4gICAgICAgIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XHJcbiAgICAgICAgICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcclxuICAgICAgICAgICAgZSA9IGVNYXg7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpO1xyXG4gICAgICAgICAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICBlLS07XHJcbiAgICAgICAgICAgICAgICBjICo9IDI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSArPSBydCAvIGM7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XHJcbiAgICAgICAgICAgICAgICBlKys7XHJcbiAgICAgICAgICAgICAgICBjIC89IDI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xyXG4gICAgICAgICAgICAgICAgbSA9IDA7XHJcbiAgICAgICAgICAgICAgICBlID0gZU1heDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xyXG4gICAgICAgICAgICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xyXG4gICAgICAgICAgICAgICAgZSA9IGUgKyBlQmlhcztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKTtcclxuICAgICAgICAgICAgICAgIGUgPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxyXG5cclxuICAgICAgICBlID0gKGUgPDwgbUxlbikgfCBtO1xyXG4gICAgICAgIGVMZW4gKz0gbUxlbjtcclxuICAgICAgICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XHJcblxyXG4gICAgICAgIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyODtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDMyYml0IGZsb2F0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gd3JpdGUgdG8uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IGA0YCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVGbG9hdDMyID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGEgbnVtYmVyKVwiKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIG9mZnNldCArPSA0O1xuICAgICAgICB2YXIgY2FwYWNpdHk4ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5OClcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTggKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTggOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gNDtcbiAgICAgICAgaWVlZTc1NF93cml0ZSh0aGlzLnZpZXcsIHZhbHVlLCBvZmZzZXQsIHRoaXMubGl0dGxlRW5kaWFuLCAyMywgNCk7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCArPSA0O1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCBmbG9hdC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZUZsb2F0MzJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUZsb2F0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUZsb2F0MzI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDMyYml0IGZsb2F0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDRgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRGbG9hdDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgNCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzQrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gaWVlZTc1NF9yZWFkKHRoaXMudmlldywgb2Zmc2V0LCB0aGlzLmxpdHRsZUVuZGlhbiwgMjMsIDQpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgZmxvYXQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEZsb2F0MzJ9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgNGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0ID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkRmxvYXQzMjtcclxuXHJcbiAgICAvLyB0eXBlcy9mbG9hdHMvZmxvYXQ2NFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgNjRiaXQgZmxvYXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUZsb2F0NjQgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYSBudW1iZXIpXCIpO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgb2Zmc2V0ICs9IDg7XG4gICAgICAgIHZhciBjYXBhY2l0eTkgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHk5KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5OSAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5OSA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSA4O1xuICAgICAgICBpZWVlNzU0X3dyaXRlKHRoaXMudmlldywgdmFsdWUsIG9mZnNldCwgdGhpcy5saXR0bGVFbmRpYW4sIDUyLCA4KTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IDg7XG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhIDY0Yml0IGZsb2F0LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3dyaXRlRmxvYXQ2NH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlRG91YmxlID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZUZsb2F0NjQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIDY0Yml0IGZsb2F0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgYDhgIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRGbG9hdDY0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgOCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzgrXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZhbHVlID0gaWVlZTc1NF9yZWFkKHRoaXMudmlldywgb2Zmc2V0LCB0aGlzLmxpdHRsZUVuZGlhbiwgNTIsIDgpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gODtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgNjRiaXQgZmxvYXQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIEJ5dGVCdWZmZXIjcmVhZEZsb2F0NjR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSBgOGAgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZERvdWJsZSA9IEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZEZsb2F0NjQ7XHJcblxyXG5cclxuICAgIC8vIHR5cGVzL3ZhcmludHMvdmFyaW50MzJcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIGEgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuTUFYX1ZBUklOVDMyX0JZVEVTID0gNTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgdG8gc3RvcmUgYSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byBlbmNvZGVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBieXRlcyByZXF1aXJlZC4gQ2FwcGVkIHRvIHtAbGluayBCeXRlQnVmZmVyLk1BWF9WQVJJTlQzMl9CWVRFU31cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQzMiA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL2lvL2NvZGVkX3N0cmVhbS5jY1xyXG4gICAgICAgIHZhbHVlID0gdmFsdWUgPj4+IDA7XHJcbiAgICAgICAgICAgICBpZiAodmFsdWUgPCAxIDw8IDcgKSByZXR1cm4gMTtcclxuICAgICAgICBlbHNlIGlmICh2YWx1ZSA8IDEgPDwgMTQpIHJldHVybiAyO1xyXG4gICAgICAgIGVsc2UgaWYgKHZhbHVlIDwgMSA8PCAyMSkgcmV0dXJuIDM7XHJcbiAgICAgICAgZWxzZSBpZiAodmFsdWUgPCAxIDw8IDI4KSByZXR1cm4gNDtcclxuICAgICAgICBlbHNlICAgICAgICAgICAgICAgICAgICAgIHJldHVybiA1O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFppZ3phZyBlbmNvZGVzIGEgc2lnbmVkIDMyYml0IGludGVnZXIgc28gdGhhdCBpdCBjYW4gYmUgZWZmZWN0aXZlbHkgdXNlZCB3aXRoIHZhcmludCBlbmNvZGluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFNpZ25lZCAzMmJpdCBpbnRlZ2VyXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCB6aWd6YWcgZW5jb2RlZCAzMmJpdCBpbnRlZ2VyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuemlnWmFnRW5jb2RlMzIgPSBmdW5jdGlvbihuKSB7XHJcbiAgICAgICAgcmV0dXJuICgoKG4gfD0gMCkgPDwgMSkgXiAobiA+PiAzMSkpID4+PiAwOyAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvd2lyZV9mb3JtYXRfbGl0ZS5oXHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIHppZ3phZyBlbmNvZGVkIHNpZ25lZCAzMmJpdCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVW5zaWduZWQgemlnemFnIGVuY29kZWQgMzJiaXQgaW50ZWdlclxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIDMyYml0IGludGVnZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci56aWdaYWdEZWNvZGUzMiA9IGZ1bmN0aW9uKG4pIHtcclxuICAgICAgICByZXR1cm4gKChuID4+PiAxKSBeIC0obiAmIDEpKSB8IDA7IC8vIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmhcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSAzMmJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBgb2Zmc2V0YCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZhcmludDMyID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicgfHwgdmFsdWUgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdmFsdWU6IFwiK3ZhbHVlK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICB2YWx1ZSB8PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzaXplID0gQnl0ZUJ1ZmZlci5jYWxjdWxhdGVWYXJpbnQzMih2YWx1ZSksXHJcbiAgICAgICAgICAgIGI7XHJcbiAgICAgICAgb2Zmc2V0ICs9IHNpemU7XG4gICAgICAgIHZhciBjYXBhY2l0eTEwID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTApXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxMCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTAgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gc2l6ZTtcbiAgICAgICAgdmFsdWUgPj4+PSAwO1xyXG4gICAgICAgIHdoaWxlICh2YWx1ZSA+PSAweDgwKSB7XHJcbiAgICAgICAgICAgIGIgPSAodmFsdWUgJiAweDdmKSB8IDB4ODA7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSB2YWx1ZTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2l6ZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYSB6aWctemFnIGVuY29kZWQgKHNpZ25lZCkgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IHRoaXMgaWYgYG9mZnNldGAgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVWYXJpbnQzMlppZ1phZyA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53cml0ZVZhcmludDMyKEJ5dGVCdWZmZXIuemlnWmFnRW5jb2RlMzIodmFsdWUpLCBvZmZzZXQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgMzJiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge251bWJlcnwhe3ZhbHVlOiBudW1iZXIsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHZhbHVlIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHZhbHVlIHJlYWRcclxuICAgICAqICBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCdzIG5vdCBhIHZhbGlkIHZhcmludC4gSGFzIGEgcHJvcGVydHkgYHRydW5jYXRlZCA9IHRydWVgIGlmIHRoZXJlIGlzIG5vdCBlbm91Z2ggZGF0YSBhdmFpbGFibGVcclxuICAgICAqICB0byBmdWxseSBkZWNvZGUgdGhlIHZhcmludC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVmFyaW50MzIgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgYyA9IDAsXHJcbiAgICAgICAgICAgIHZhbHVlID0gMCA+Pj4gMCxcclxuICAgICAgICAgICAgYjtcclxuICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCAmJiBvZmZzZXQgPiB0aGlzLmxpbWl0KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXJyID0gRXJyb3IoXCJUcnVuY2F0ZWRcIik7XHJcbiAgICAgICAgICAgICAgICBlcnJbJ3RydW5jYXRlZCddID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBiID0gdGhpcy52aWV3W29mZnNldCsrXTtcclxuICAgICAgICAgICAgaWYgKGMgPCA1KVxyXG4gICAgICAgICAgICAgICAgdmFsdWUgfD0gKGIgJiAweDdmKSA8PCAoNypjKTtcclxuICAgICAgICAgICAgKytjO1xyXG4gICAgICAgIH0gd2hpbGUgKChiICYgMHg4MCkgIT09IDApO1xyXG4gICAgICAgIHZhbHVlIHw9IDA7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIFwidmFsdWVcIjogdmFsdWUsXHJcbiAgICAgICAgICAgIFwibGVuZ3RoXCI6IGNcclxuICAgICAgICB9O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgemlnLXphZyBlbmNvZGVkIChzaWduZWQpIDMyYml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ8IXt2YWx1ZTogbnVtYmVyLCBsZW5ndGg6IG51bWJlcn19IFRoZSB2YWx1ZSByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSB2YWx1ZSByZWFkXHJcbiAgICAgKiAgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQncyBub3QgYSB2YWxpZCB2YXJpbnRcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVmFyaW50MzJaaWdaYWcgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgdmFsID0gdGhpcy5yZWFkVmFyaW50MzIob2Zmc2V0KTtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ29iamVjdCcpXHJcbiAgICAgICAgICAgIHZhbFtcInZhbHVlXCJdID0gQnl0ZUJ1ZmZlci56aWdaYWdEZWNvZGUzMih2YWxbXCJ2YWx1ZVwiXSk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB2YWwgPSBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTMyKHZhbCk7XHJcbiAgICAgICAgcmV0dXJuIHZhbDtcclxuICAgIH07XHJcblxyXG4gICAgLy8gdHlwZXMvdmFyaW50cy92YXJpbnQ2NFxyXG5cclxuICAgIGlmIChMb25nKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIGEgNjRiaXQgYmFzZSAxMjggdmFyaWFibGUtbGVuZ3RoIGludGVnZXIuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKiBAY29uc3RcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlci5NQVhfVkFSSU5UNjRfQllURVMgPSAxMDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsY3VsYXRlcyB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCB0byBzdG9yZSBhIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBWYWx1ZSB0byBlbmNvZGVcclxuICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQuIENhcHBlZCB0byB7QGxpbmsgQnl0ZUJ1ZmZlci5NQVhfVkFSSU5UNjRfQllURVN9XHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXIuY2FsY3VsYXRlVmFyaW50NjQgPSBmdW5jdGlvbih2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgICAgIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi9pby9jb2RlZF9zdHJlYW0uY2NcclxuICAgICAgICAgICAgdmFyIHBhcnQwID0gdmFsdWUudG9JbnQoKSA+Pj4gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQxID0gdmFsdWUuc2hpZnRSaWdodFVuc2lnbmVkKDI4KS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDIgPSB2YWx1ZS5zaGlmdFJpZ2h0VW5zaWduZWQoNTYpLnRvSW50KCkgPj4+IDA7XHJcbiAgICAgICAgICAgIGlmIChwYXJ0MiA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocGFydDEgPT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0MCA8IDEgPDwgMTQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MCA8IDEgPDwgNyA/IDEgOiAyO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnQwIDwgMSA8PCAyMSA/IDMgOiA0O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocGFydDEgPCAxIDw8IDE0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFydDEgPCAxIDw8IDcgPyA1IDogNjtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJ0MSA8IDEgPDwgMjEgPyA3IDogODtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFydDIgPCAxIDw8IDcgPyA5IDogMTA7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogWmlnemFnIGVuY29kZXMgYSBzaWduZWQgNjRiaXQgaW50ZWdlciBzbyB0aGF0IGl0IGNhbiBiZSBlZmZlY3RpdmVseSB1c2VkIHdpdGggdmFyaW50IGVuY29kaW5nLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSB2YWx1ZSBTaWduZWQgbG9uZ1xyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgemlnemFnIGVuY29kZWQgbG9uZ1xyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyLnppZ1phZ0VuY29kZTY0ID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21OdW1iZXIodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnVuc2lnbmVkICE9PSBmYWxzZSkgdmFsdWUgPSB2YWx1ZS50b1NpZ25lZCgpO1xuICAgICAgICAgICAgLy8gcmVmOiBzcmMvZ29vZ2xlL3Byb3RvYnVmL3dpcmVfZm9ybWF0X2xpdGUuaFxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuc2hpZnRMZWZ0KDEpLnhvcih2YWx1ZS5zaGlmdFJpZ2h0KDYzKSkudG9VbnNpZ25lZCgpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlY29kZXMgYSB6aWd6YWcgZW5jb2RlZCBzaWduZWQgNjRiaXQgaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcn0gdmFsdWUgVW5zaWduZWQgemlnemFnIGVuY29kZWQgbG9uZyBvciBKYXZhU2NyaXB0IG51bWJlclxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2lnbmVkIGxvbmdcclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlci56aWdaYWdEZWNvZGU2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tTnVtYmVyKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKVxuICAgICAgICAgICAgICAgIHZhbHVlID0gTG9uZy5mcm9tU3RyaW5nKHZhbHVlLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlIGlmICh2YWx1ZS51bnNpZ25lZCAhPT0gZmFsc2UpIHZhbHVlID0gdmFsdWUudG9TaWduZWQoKTtcbiAgICAgICAgICAgIC8vIHJlZjogc3JjL2dvb2dsZS9wcm90b2J1Zi93aXJlX2Zvcm1hdF9saXRlLmhcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCgxKS54b3IodmFsdWUuYW5kKExvbmcuT05FKS50b1NpZ25lZCgpLm5lZ2F0ZSgpKS50b1NpZ25lZCgpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfExvbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ8bnVtYmVyfSBgdGhpc2AgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi5cclxuICAgICAgICAgKiBAZXhwb3NlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZhcmludDY0ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBMb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCEodmFsdWUgJiYgdmFsdWUgaW5zdGFuY2VvZiBMb25nKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCB2YWx1ZTogXCIrdmFsdWUrXCIgKG5vdCBhbiBpbnRlZ2VyIG9yIExvbmcpXCIpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbU51bWJlcih2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IExvbmcuZnJvbVN0cmluZyh2YWx1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUudW5zaWduZWQgIT09IGZhbHNlKSB2YWx1ZSA9IHZhbHVlLnRvU2lnbmVkKCk7XG4gICAgICAgICAgICB2YXIgc2l6ZSA9IEJ5dGVCdWZmZXIuY2FsY3VsYXRlVmFyaW50NjQodmFsdWUpLFxyXG4gICAgICAgICAgICAgICAgcGFydDAgPSB2YWx1ZS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICAgICAgcGFydDEgPSB2YWx1ZS5zaGlmdFJpZ2h0VW5zaWduZWQoMjgpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBwYXJ0MiA9IHZhbHVlLnNoaWZ0UmlnaHRVbnNpZ25lZCg1NikudG9JbnQoKSA+Pj4gMDtcclxuICAgICAgICAgICAgb2Zmc2V0ICs9IHNpemU7XG4gICAgICAgICAgICB2YXIgY2FwYWNpdHkxMSA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxMSlcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxMSAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTEgOiBvZmZzZXQpO1xuICAgICAgICAgICAgb2Zmc2V0IC09IHNpemU7XG4gICAgICAgICAgICBzd2l0Y2ggKHNpemUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMTA6IHRoaXMudmlld1tvZmZzZXQrOV0gPSAocGFydDIgPj4+ICA3KSAmIDB4MDE7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDkgOiB0aGlzLnZpZXdbb2Zmc2V0KzhdID0gc2l6ZSAhPT0gOSA/IChwYXJ0MiAgICAgICApIHwgMHg4MCA6IChwYXJ0MiAgICAgICApICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgOCA6IHRoaXMudmlld1tvZmZzZXQrN10gPSBzaXplICE9PSA4ID8gKHBhcnQxID4+PiAyMSkgfCAweDgwIDogKHBhcnQxID4+PiAyMSkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3IDogdGhpcy52aWV3W29mZnNldCs2XSA9IHNpemUgIT09IDcgPyAocGFydDEgPj4+IDE0KSB8IDB4ODAgOiAocGFydDEgPj4+IDE0KSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDYgOiB0aGlzLnZpZXdbb2Zmc2V0KzVdID0gc2l6ZSAhPT0gNiA/IChwYXJ0MSA+Pj4gIDcpIHwgMHg4MCA6IChwYXJ0MSA+Pj4gIDcpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgNSA6IHRoaXMudmlld1tvZmZzZXQrNF0gPSBzaXplICE9PSA1ID8gKHBhcnQxICAgICAgICkgfCAweDgwIDogKHBhcnQxICAgICAgICkgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0IDogdGhpcy52aWV3W29mZnNldCszXSA9IHNpemUgIT09IDQgPyAocGFydDAgPj4+IDIxKSB8IDB4ODAgOiAocGFydDAgPj4+IDIxKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDMgOiB0aGlzLnZpZXdbb2Zmc2V0KzJdID0gc2l6ZSAhPT0gMyA/IChwYXJ0MCA+Pj4gMTQpIHwgMHg4MCA6IChwYXJ0MCA+Pj4gMTQpICYgMHg3RjtcclxuICAgICAgICAgICAgICAgIGNhc2UgMiA6IHRoaXMudmlld1tvZmZzZXQrMV0gPSBzaXplICE9PSAyID8gKHBhcnQwID4+PiAgNykgfCAweDgwIDogKHBhcnQwID4+PiAgNykgJiAweDdGO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAxIDogdGhpcy52aWV3W29mZnNldCAgXSA9IHNpemUgIT09IDEgPyAocGFydDAgICAgICAgKSB8IDB4ODAgOiAocGFydDAgICAgICAgKSAmIDB4N0Y7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldCArPSBzaXplO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2l6ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdyaXRlcyBhIHppZy16YWcgZW5jb2RlZCA2NGJpdCBiYXNlIDEyOCB2YXJpYWJsZS1sZW5ndGggaW50ZWdlci5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcnxMb25nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gYHRoaXNgIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4uXHJcbiAgICAgICAgICogQGV4cG9zZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVWYXJpbnQ2NFppZ1phZyA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JpdGVWYXJpbnQ2NChCeXRlQnVmZmVyLnppZ1phZ0VuY29kZTY0KHZhbHVlKSwgb2Zmc2V0KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWFkcyBhIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLiBSZXF1aXJlcyBMb25nLmpzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ3whe3ZhbHVlOiBMb25nLCBsZW5ndGg6IG51bWJlcn19IFRoZSB2YWx1ZSByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSB2YWx1ZSByZWFkIGFuZFxyXG4gICAgICAgICAqICB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCdzIG5vdCBhIHZhbGlkIHZhcmludFxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWYXJpbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyByZWY6IHNyYy9nb29nbGUvcHJvdG9idWYvaW8vY29kZWRfc3RyZWFtLmNjXHJcbiAgICAgICAgICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgICAgICAgIHBhcnQwID0gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQxID0gMCxcclxuICAgICAgICAgICAgICAgIHBhcnQyID0gMCxcclxuICAgICAgICAgICAgICAgIGIgID0gMDtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQwICA9IChiICYgMHg3RikgICAgICA7IGlmICggYiAmIDB4ODAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQwIHw9IChiICYgMHg3RikgPDwgIDc7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQwIHw9IChiICYgMHg3RikgPDwgMTQ7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQwIHw9IChiICYgMHg3RikgPDwgMjE7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQxICA9IChiICYgMHg3RikgICAgICA7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQxIHw9IChiICYgMHg3RikgPDwgIDc7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQxIHw9IChiICYgMHg3RikgPDwgMTQ7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQxIHw9IChiICYgMHg3RikgPDwgMjE7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQyICA9IChiICYgMHg3RikgICAgICA7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgYiA9IHRoaXMudmlld1tvZmZzZXQrK107IHBhcnQyIHw9IChiICYgMHg3RikgPDwgIDc7IGlmICgoYiAmIDB4ODApIHx8ICh0aGlzLm5vQXNzZXJ0ICYmIHR5cGVvZiBiID09PSAndW5kZWZpbmVkJykpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJCdWZmZXIgb3ZlcnJ1blwiKTsgfX19fX19fX19fVxyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBMb25nLmZyb21CaXRzKHBhcnQwIHwgKHBhcnQxIDw8IDI4KSwgKHBhcnQxID4+PiA0KSB8IChwYXJ0MikgPDwgMjQsIGZhbHNlKTtcclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgJ3ZhbHVlJzogdmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2xlbmd0aCc6IG9mZnNldC1zdGFydFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlYWRzIGEgemlnLXphZyBlbmNvZGVkIDY0Yml0IGJhc2UgMTI4IHZhcmlhYmxlLWxlbmd0aCBpbnRlZ2VyLiBSZXF1aXJlcyBMb25nLmpzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshTG9uZ3whe3ZhbHVlOiBMb25nLCBsZW5ndGg6IG51bWJlcn19IFRoZSB2YWx1ZSByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSB2YWx1ZSByZWFkIGFuZFxyXG4gICAgICAgICAqICB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBpdCdzIG5vdCBhIHZhbGlkIHZhcmludFxyXG4gICAgICAgICAqIEBleHBvc2VcclxuICAgICAgICAgKi9cclxuICAgICAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRWYXJpbnQ2NFppZ1phZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgICAgICB2YXIgdmFsID0gdGhpcy5yZWFkVmFyaW50NjQob2Zmc2V0KTtcclxuICAgICAgICAgICAgaWYgKHZhbCAmJiB2YWxbJ3ZhbHVlJ10gaW5zdGFuY2VvZiBMb25nKVxyXG4gICAgICAgICAgICAgICAgdmFsW1widmFsdWVcIl0gPSBCeXRlQnVmZmVyLnppZ1phZ0RlY29kZTY0KHZhbFtcInZhbHVlXCJdKTtcclxuICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgdmFsID0gQnl0ZUJ1ZmZlci56aWdaYWdEZWNvZGU2NCh2YWwpO1xyXG4gICAgICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgfSAvLyBMb25nXHJcblxyXG5cclxuICAgIC8vIHR5cGVzL3N0cmluZ3MvY3N0cmluZ1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgTlVMTC10ZXJtaW5hdGVkIFVURjggZW5jb2RlZCBzdHJpbmcuIEZvciB0aGlzIHRvIHdvcmsgdGhlIHNwZWNpZmllZCBzdHJpbmcgbXVzdCBub3QgY29udGFpbiBhbnkgTlVMTFxyXG4gICAgICogIGNoYXJhY3RlcnMgaXRzZWxmLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIGNvbnRhaW5lZCBpbiBgc3RyYCArIDEgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IHRoaXMgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlQ1N0cmluZyA9IGZ1bmN0aW9uKHN0ciwgb2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIHZhciBpLFxyXG4gICAgICAgICAgICBrID0gc3RyLmxlbmd0aDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIHN0cmluZ1wiKTtcclxuICAgICAgICAgICAgZm9yIChpPTA7IGk8azsgKytpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RyLmNoYXJDb2RlQXQoaSkgPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgc3RyOiBDb250YWlucyBOVUxMLWNoYXJhY3RlcnNcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFVURjggc3RyaW5ncyBkbyBub3QgY29udGFpbiB6ZXJvIGJ5dGVzIGluIGJldHdlZW4gZXhjZXB0IGZvciB0aGUgemVybyBjaGFyYWN0ZXIsIHNvOlxyXG4gICAgICAgIGsgPSB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4KHN0cmluZ1NvdXJjZShzdHIpKVsxXTtcclxuICAgICAgICBvZmZzZXQgKz0gaysxO1xuICAgICAgICB2YXIgY2FwYWNpdHkxMiA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTEyKVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTIgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTEyIDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IGsrMTtcbiAgICAgICAgdXRmeC5lbmNvZGVVVEYxNnRvVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gYjtcclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSAwO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBrO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGEgTlVMTC10ZXJtaW5hdGVkIFVURjggZW5jb2RlZCBzdHJpbmcuIEZvciB0aGlzIHRvIHdvcmsgdGhlIHN0cmluZyByZWFkIG11c3Qgbm90IGNvbnRhaW4gYW55IE5VTEwgY2hhcmFjdGVyc1xyXG4gICAgICogIGl0c2VsZi5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRDU3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0KSB7XHJcbiAgICAgICAgdmFyIHJlbGF0aXZlID0gdHlwZW9mIG9mZnNldCA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgICAgIGlmIChyZWxhdGl2ZSkgb2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMSA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzErXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0YXJ0ID0gb2Zmc2V0LFxyXG4gICAgICAgICAgICB0ZW1wO1xyXG4gICAgICAgIC8vIFVURjggc3RyaW5ncyBkbyBub3QgY29udGFpbiB6ZXJvIGJ5dGVzIGluIGJldHdlZW4gZXhjZXB0IGZvciB0aGUgemVybyBjaGFyYWN0ZXIgaXRzZWxmLCBzbzpcclxuICAgICAgICB2YXIgc2QsIGIgPSAtMTtcclxuICAgICAgICB1dGZ4LmRlY29kZVVURjh0b1VURjE2KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBpZiAoYiA9PT0gMCkgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPj0gdGhpcy5saW1pdClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrb2Zmc2V0K1wiIDwgXCIrdGhpcy5saW1pdCk7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbb2Zmc2V0KytdO1xyXG4gICAgICAgICAgICByZXR1cm4gYiA9PT0gMCA/IG51bGwgOiBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSwgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpLCB0cnVlKTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiBzZCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBcInN0cmluZ1wiOiBzZCgpLFxyXG4gICAgICAgICAgICAgICAgXCJsZW5ndGhcIjogb2Zmc2V0IC0gc3RhcnRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIHR5cGVzL3N0cmluZ3MvaXN0cmluZ1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgbGVuZ3RoIGFzIHVpbnQzMiBwcmVmaXhlZCBVVEY4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHdyaXR0ZW4gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IGB0aGlzYCBpZiBgb2Zmc2V0YCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciN3cml0ZVZhcmludDMyXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUud3JpdGVJU3RyaW5nID0gZnVuY3Rpb24oc3RyLCBvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBzdHJpbmdcIik7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQsXHJcbiAgICAgICAgICAgIGs7XHJcbiAgICAgICAgayA9IHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0ciksIHRoaXMubm9Bc3NlcnQpWzFdO1xyXG4gICAgICAgIG9mZnNldCArPSA0K2s7XG4gICAgICAgIHZhciBjYXBhY2l0eTEzID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTMpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxMyAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTMgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gNCtrO1xuICAgICAgICBpZiAodGhpcy5saXR0bGVFbmRpYW4pIHtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAoayA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoayA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoayA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAgayAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQgIF0gPSAoayA+Pj4gMjQpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMV0gPSAoayA+Pj4gMTYpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrMl0gPSAoayA+Pj4gIDgpICYgMHhGRjtcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrM10gPSAgayAgICAgICAgICYgMHhGRjtcbiAgICAgICAgfVxuICAgICAgICBvZmZzZXQgKz0gNDtcclxuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCAhPT0gc3RhcnQgKyA0ICsgaylcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IFRydW5jYXRlZCBkYXRhLCBcIitvZmZzZXQrXCIgPT0gXCIrKG9mZnNldCs0K2spKTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2Zmc2V0IC0gc3RhcnQ7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYSBsZW5ndGggYXMgdWludDMyIHByZWZpeGVkIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whe3N0cmluZzogc3RyaW5nLCBsZW5ndGg6IG51bWJlcn19IFRoZSBzdHJpbmcgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgc3RyaW5nXHJcbiAgICAgKiAgcmVhZCBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNyZWFkVmFyaW50MzJcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkSVN0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIis0K1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldDtcclxuICAgICAgICB2YXIgbGVuID0gdGhpcy5yZWFkVWludDMyKG9mZnNldCk7XHJcbiAgICAgICAgdmFyIHN0ciA9IHRoaXMucmVhZFVURjhTdHJpbmcobGVuLCBCeXRlQnVmZmVyLk1FVFJJQ1NfQllURVMsIG9mZnNldCArPSA0KTtcclxuICAgICAgICBvZmZzZXQgKz0gc3RyWydsZW5ndGgnXTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiBzdHJbJ3N0cmluZyddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAnc3RyaW5nJzogc3RyWydzdHJpbmcnXSxcclxuICAgICAgICAgICAgICAgICdsZW5ndGgnOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gdHlwZXMvc3RyaW5ncy91dGY4c3RyaW5nXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRyaWNzIHJlcHJlc2VudGluZyBudW1iZXIgb2YgVVRGOCBjaGFyYWN0ZXJzLiBFdmFsdWF0ZXMgdG8gYGNgLlxyXG4gICAgICogQHR5cGUge3N0cmluZ31cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLk1FVFJJQ1NfQ0hBUlMgPSAnYyc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXRyaWNzIHJlcHJlc2VudGluZyBudW1iZXIgb2YgYnl0ZXMuIEV2YWx1YXRlcyB0byBgYmAuXHJcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuTUVUUklDU19CWVRFUyA9ICdiJztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFdyaXRlcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gd3JpdGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byB3cml0ZSB0by4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcnxudW1iZXJ9IHRoaXMgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbi5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVURjhTdHJpbmcgPSBmdW5jdGlvbihzdHIsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBrO1xyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldDtcclxuICAgICAgICBrID0gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSlbMV07XHJcbiAgICAgICAgb2Zmc2V0ICs9IGs7XG4gICAgICAgIHZhciBjYXBhY2l0eTE0ID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgICAgICAgaWYgKG9mZnNldCA+IGNhcGFjaXR5MTQpXG4gICAgICAgICAgICB0aGlzLnJlc2l6ZSgoY2FwYWNpdHkxNCAqPSAyKSA+IG9mZnNldCA/IGNhcGFjaXR5MTQgOiBvZmZzZXQpO1xuICAgICAgICBvZmZzZXQgLT0gaztcbiAgICAgICAgdXRmeC5lbmNvZGVVVEYxNnRvVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICB0aGlzLnZpZXdbb2Zmc2V0KytdID0gYjtcclxuICAgICAgICB9LmJpbmQodGhpcykpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBXcml0ZXMgYW4gVVRGOCBlbmNvZGVkIHN0cmluZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciN3cml0ZVVURjhTdHJpbmd9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gdGhpcyBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyB3cml0dGVuLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLndyaXRlU3RyaW5nID0gQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVVURjhTdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgVVRGOCBjaGFyYWN0ZXJzIG9mIGEgc3RyaW5nLiBKYXZhU2NyaXB0IGl0c2VsZiB1c2VzIFVURi0xNiwgc28gdGhhdCBhIHN0cmluZydzXHJcbiAgICAgKiAgYGxlbmd0aGAgcHJvcGVydHkgZG9lcyBub3QgcmVmbGVjdCBpdHMgYWN0dWFsIFVURjggc2l6ZSBpZiBpdCBjb250YWlucyBjb2RlIHBvaW50cyBsYXJnZXIgdGhhbiAweEZGRkYuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBjYWxjdWxhdGVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBVVEY4IGNoYXJhY3RlcnNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVVVEY4Q2hhcnMgPSBmdW5jdGlvbihzdHIpIHtcclxuICAgICAgICByZXR1cm4gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSlbMF07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgb2YgYSBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBjYWxjdWxhdGVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBVVEY4IGJ5dGVzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuY2FsY3VsYXRlVVRGOEJ5dGVzID0gZnVuY3Rpb24oc3RyKSB7XHJcbiAgICAgICAgcmV0dXJuIHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0cikpWzFdO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVVEY4IGJ5dGVzIG9mIGEgc3RyaW5nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyLmNhbGN1bGF0ZVVURjhCeXRlc30uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNhbGN1bGF0ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIFVURjggYnl0ZXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5jYWxjdWxhdGVTdHJpbmcgPSBCeXRlQnVmZmVyLmNhbGN1bGF0ZVVURjhCeXRlcztcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlYWRzIGFuIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBjaGFyYWN0ZXJzIG9yIGJ5dGVzIHRvIHJlYWQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZz19IG1ldHJpY3MgTWV0cmljcyBzcGVjaWZ5aW5nIHdoYXQgYGxlbmd0aGAgaXMgbWVhbnQgdG8gY291bnQuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuTUVUUklDU19DSEFSU30uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcmVhZCBmcm9tLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3whe3N0cmluZzogc3RyaW5nLCBsZW5ndGg6IG51bWJlcn19IFRoZSBzdHJpbmcgcmVhZCBpZiBvZmZzZXQgaXMgb21pdHRlZCwgZWxzZSB0aGUgc3RyaW5nXHJcbiAgICAgKiAgcmVhZCBhbmQgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgcmVhZC5cclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5yZWFkVVRGOFN0cmluZyA9IGZ1bmN0aW9uKGxlbmd0aCwgbWV0cmljcywgb2Zmc2V0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRyaWNzID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICBvZmZzZXQgPSBtZXRyaWNzO1xyXG4gICAgICAgICAgICBtZXRyaWNzID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRyaWNzID09PSAndW5kZWZpbmVkJykgbWV0cmljcyA9IEJ5dGVCdWZmZXIuTUVUUklDU19DSEFSUztcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBsZW5ndGggIT09ICdudW1iZXInIHx8IGxlbmd0aCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBsZW5ndGg6IFwiK2xlbmd0aCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgbGVuZ3RoIHw9IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ICsgMCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiAwIDw9IFwiK29mZnNldCtcIiAoK1wiKzArXCIpIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGkgPSAwLFxyXG4gICAgICAgICAgICBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgICAgc2Q7XHJcbiAgICAgICAgaWYgKG1ldHJpY3MgPT09IEJ5dGVCdWZmZXIuTUVUUklDU19DSEFSUykgeyAvLyBUaGUgc2FtZSBmb3Igbm9kZSBhbmQgdGhlIGJyb3dzZXJcclxuICAgICAgICAgICAgc2QgPSBzdHJpbmdEZXN0aW5hdGlvbigpO1xyXG4gICAgICAgICAgICB1dGZ4LmRlY29kZVVURjgoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaSA8IGxlbmd0aCAmJiBvZmZzZXQgPCB0aGlzLmxpbWl0ID8gdGhpcy52aWV3W29mZnNldCsrXSA6IG51bGw7XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSwgZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgICAgICsraTsgdXRmeC5VVEY4dG9VVEYxNihjcCwgc2QpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYgKGkgIT09IGxlbmd0aClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIraStcIiA9PSBcIitsZW5ndGgpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgIFwic3RyaW5nXCI6IHNkKCksXHJcbiAgICAgICAgICAgICAgICAgICAgXCJsZW5ndGhcIjogb2Zmc2V0IC0gc3RhcnRcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKG1ldHJpY3MgPT09IEJ5dGVCdWZmZXIuTUVUUklDU19CWVRFUykge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogXCIrb2Zmc2V0K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyBsZW5ndGggPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrbGVuZ3RoK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGsgPSBvZmZzZXQgKyBsZW5ndGg7XHJcbiAgICAgICAgICAgIHV0ZnguZGVjb2RlVVRGOHRvVVRGMTYoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2Zmc2V0IDwgayA/IHRoaXMudmlld1tvZmZzZXQrK10gOiBudWxsO1xyXG4gICAgICAgICAgICB9LmJpbmQodGhpcyksIHNkID0gc3RyaW5nRGVzdGluYXRpb24oKSwgdGhpcy5ub0Fzc2VydCk7XHJcbiAgICAgICAgICAgIGlmIChvZmZzZXQgIT09IGspXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK29mZnNldCtcIiA9PSBcIitrKTtcclxuICAgICAgICAgICAgaWYgKHJlbGF0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzZCgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAnc3RyaW5nJzogc2QoKSxcclxuICAgICAgICAgICAgICAgICAgICAnbGVuZ3RoJzogb2Zmc2V0IC0gc3RhcnRcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiVW5zdXBwb3J0ZWQgbWV0cmljczogXCIrbWV0cmljcyk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVhZHMgYW4gVVRGOCBlbmNvZGVkIHN0cmluZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgQnl0ZUJ1ZmZlciNyZWFkVVRGOFN0cmluZ30uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGNoYXJhY3RlcnMgb3IgYnl0ZXMgdG8gcmVhZFxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBtZXRyaWNzIE1ldHJpY3Mgc3BlY2lmeWluZyB3aGF0IGBuYCBpcyBtZWFudCB0byBjb3VudC4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5NRVRSSUNTX0NIQVJTfS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byByZWFkIGZyb20uIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICByZWFkIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCF7c3RyaW5nOiBzdHJpbmcsIGxlbmd0aDogbnVtYmVyfX0gVGhlIHN0cmluZyByZWFkIGlmIG9mZnNldCBpcyBvbWl0dGVkLCBlbHNlIHRoZSBzdHJpbmdcclxuICAgICAqICByZWFkIGFuZCB0aGUgYWN0dWFsIG51bWJlciBvZiBieXRlcyByZWFkLlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRTdHJpbmcgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnJlYWRVVEY4U3RyaW5nO1xyXG5cclxuICAgIC8vIHR5cGVzL3N0cmluZ3MvdnN0cmluZ1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGVzIGEgbGVuZ3RoIGFzIHZhcmludDMyIHByZWZpeGVkIFVURjggZW5jb2RlZCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byB3cml0ZVxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHdyaXRlIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgd3JpdHRlbiBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfG51bWJlcn0gYHRoaXNgIGlmIGBvZmZzZXRgIGlzIG9taXR0ZWQsIGVsc2UgdGhlIGFjdHVhbCBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3dyaXRlVmFyaW50MzJcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS53cml0ZVZTdHJpbmcgPSBmdW5jdGlvbihzdHIsIG9mZnNldCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIHN0cmluZ1wiKTtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICAgICAgaywgbDtcclxuICAgICAgICBrID0gdXRmeC5jYWxjdWxhdGVVVEYxNmFzVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgdGhpcy5ub0Fzc2VydClbMV07XHJcbiAgICAgICAgbCA9IEJ5dGVCdWZmZXIuY2FsY3VsYXRlVmFyaW50MzIoayk7XHJcbiAgICAgICAgb2Zmc2V0ICs9IGwraztcbiAgICAgICAgdmFyIGNhcGFjaXR5MTUgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICBpZiAob2Zmc2V0ID4gY2FwYWNpdHkxNSlcbiAgICAgICAgICAgIHRoaXMucmVzaXplKChjYXBhY2l0eTE1ICo9IDIpID4gb2Zmc2V0ID8gY2FwYWNpdHkxNSA6IG9mZnNldCk7XG4gICAgICAgIG9mZnNldCAtPSBsK2s7XG4gICAgICAgIG9mZnNldCArPSB0aGlzLndyaXRlVmFyaW50MzIoaywgb2Zmc2V0KTtcclxuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4KHN0cmluZ1NvdXJjZShzdHIpLCBmdW5jdGlvbihiKSB7XHJcbiAgICAgICAgICAgIHRoaXMudmlld1tvZmZzZXQrK10gPSBiO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCAhPT0gc3RhcnQraytsKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogVHJ1bmNhdGVkIGRhdGEsIFwiK29mZnNldCtcIiA9PSBcIisob2Zmc2V0K2srbCkpO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvZmZzZXQgLSBzdGFydDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWFkcyBhIGxlbmd0aCBhcyB2YXJpbnQzMiBwcmVmaXhlZCBVVEY4IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHJlYWQgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHJlYWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8IXtzdHJpbmc6IHN0cmluZywgbGVuZ3RoOiBudW1iZXJ9fSBUaGUgc3RyaW5nIHJlYWQgaWYgb2Zmc2V0IGlzIG9taXR0ZWQsIGVsc2UgdGhlIHN0cmluZ1xyXG4gICAgICogIHJlYWQgYW5kIHRoZSBhY3R1YWwgbnVtYmVyIG9mIGJ5dGVzIHJlYWQuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjcmVhZFZhcmludDMyXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVhZFZTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2Ygb2Zmc2V0ID09PSAndW5kZWZpbmVkJztcbiAgICAgICAgaWYgKHJlbGF0aXZlKSBvZmZzZXQgPSB0aGlzLm9mZnNldDtcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAxID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMStcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICAgICAgdmFyIGxlbiA9IHRoaXMucmVhZFZhcmludDMyKG9mZnNldCk7XHJcbiAgICAgICAgdmFyIHN0ciA9IHRoaXMucmVhZFVURjhTdHJpbmcobGVuWyd2YWx1ZSddLCBCeXRlQnVmZmVyLk1FVFJJQ1NfQllURVMsIG9mZnNldCArPSBsZW5bJ2xlbmd0aCddKTtcclxuICAgICAgICBvZmZzZXQgKz0gc3RyWydsZW5ndGgnXTtcclxuICAgICAgICBpZiAocmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgICAgIHJldHVybiBzdHJbJ3N0cmluZyddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAnc3RyaW5nJzogc3RyWydzdHJpbmcnXSxcclxuICAgICAgICAgICAgICAgICdsZW5ndGgnOiBvZmZzZXQgLSBzdGFydFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kcyBzb21lIGRhdGEgdG8gdGhpcyBCeXRlQnVmZmVyLiBUaGlzIHdpbGwgb3ZlcndyaXRlIGFueSBjb250ZW50cyBiZWhpbmQgdGhlIHNwZWNpZmllZCBvZmZzZXQgdXAgdG8gdGhlIGFwcGVuZGVkXHJcbiAgICAgKiAgZGF0YSdzIGxlbmd0aC5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ8IUFycmF5QnVmZmVyfCFVaW50OEFycmF5fHN0cmluZ30gc291cmNlIERhdGEgdG8gYXBwZW5kLiBJZiBgc291cmNlYCBpcyBhIEJ5dGVCdWZmZXIsIGl0cyBvZmZzZXRzXHJcbiAgICAgKiAgd2lsbCBiZSBtb2RpZmllZCBhY2NvcmRpbmcgdG8gdGhlIHBlcmZvcm1lZCByZWFkIG9wZXJhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7KHN0cmluZ3xudW1iZXIpPX0gZW5jb2RpbmcgRW5jb2RpbmcgaWYgYGRhdGFgIGlzIGEgc3RyaW5nIChcImJhc2U2NFwiLCBcImhleFwiLCBcImJpbmFyeVwiLCBkZWZhdWx0cyB0byBcInV0ZjhcIilcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBhcHBlbmQgYXQuIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBleGFtcGxlIEEgcmVsYXRpdmUgYDwwMSAwMj4wMy5hcHBlbmQoPDA0IDA1PilgIHdpbGwgcmVzdWx0IGluIGA8MDEgMDIgMDQgMDU+LCAwNCAwNXxgXHJcbiAgICAgKiBAZXhhbXBsZSBBbiBhYnNvbHV0ZSBgPDAxIDAyPjAzLmFwcGVuZCgwNCAwNT4sIDEpYCB3aWxsIHJlc3VsdCBpbiBgPDAxIDA0PjA1LCAwNCAwNXxgXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24oc291cmNlLCBlbmNvZGluZywgb2Zmc2V0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ251bWJlcicgfHwgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBvZmZzZXQgPSBlbmNvZGluZztcclxuICAgICAgICAgICAgZW5jb2RpbmcgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghKHNvdXJjZSBpbnN0YW5jZW9mIEJ5dGVCdWZmZXIpKVxyXG4gICAgICAgICAgICBzb3VyY2UgPSBCeXRlQnVmZmVyLndyYXAoc291cmNlLCBlbmNvZGluZyk7XHJcbiAgICAgICAgdmFyIGxlbmd0aCA9IHNvdXJjZS5saW1pdCAtIHNvdXJjZS5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKGxlbmd0aCA8PSAwKSByZXR1cm4gdGhpczsgLy8gTm90aGluZyB0byBhcHBlbmRcclxuICAgICAgICBvZmZzZXQgKz0gbGVuZ3RoO1xuICAgICAgICB2YXIgY2FwYWNpdHkxNiA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XG4gICAgICAgIGlmIChvZmZzZXQgPiBjYXBhY2l0eTE2KVxuICAgICAgICAgICAgdGhpcy5yZXNpemUoKGNhcGFjaXR5MTYgKj0gMikgPiBvZmZzZXQgPyBjYXBhY2l0eTE2IDogb2Zmc2V0KTtcbiAgICAgICAgb2Zmc2V0IC09IGxlbmd0aDtcbiAgICAgICAgdGhpcy52aWV3LnNldChzb3VyY2Uudmlldy5zdWJhcnJheShzb3VyY2Uub2Zmc2V0LCBzb3VyY2UubGltaXQpLCBvZmZzZXQpO1xyXG4gICAgICAgIHNvdXJjZS5vZmZzZXQgKz0gbGVuZ3RoO1xyXG4gICAgICAgIGlmIChyZWxhdGl2ZSkgdGhpcy5vZmZzZXQgKz0gbGVuZ3RoO1xuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBlbmRzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGFub3RoZXIgQnl0ZUJ1ZmZlci4gVGhpcyB3aWxsIG92ZXJ3cml0ZSBhbnkgY29udGVudHMgYXQgYW5kIGFmdGVyIHRoZVxyXG4gICAgICAgIHNwZWNpZmllZCBvZmZzZXQgdXAgdG8gdGhlIGxlbmd0aCBvZiB0aGlzIEJ5dGVCdWZmZXIncyBkYXRhLlxyXG4gICAgICogQHBhcmFtIHshQnl0ZUJ1ZmZlcn0gdGFyZ2V0IFRhcmdldCBCeXRlQnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gYXBwZW5kIHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2Uge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzXHJcbiAgICAgKiAgcmVhZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAc2VlIEJ5dGVCdWZmZXIjYXBwZW5kXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuYXBwZW5kVG8gPSBmdW5jdGlvbih0YXJnZXQsIG9mZnNldCkge1xyXG4gICAgICAgIHRhcmdldC5hcHBlbmQodGhpcywgb2Zmc2V0KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmFibGVzIG9yIGRpc2FibGVzIGFzc2VydGlvbnMgb2YgYXJndW1lbnQgdHlwZXMgYW5kIG9mZnNldHMuIEFzc2VydGlvbnMgYXJlIGVuYWJsZWQgYnkgZGVmYXVsdCBidXQgeW91IGNhbiBvcHQgdG9cclxuICAgICAqICBkaXNhYmxlIHRoZW0gaWYgeW91ciBjb2RlIGFscmVhZHkgbWFrZXMgc3VyZSB0aGF0IGV2ZXJ5dGhpbmcgaXMgdmFsaWQuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGFzc2VydCBgdHJ1ZWAgdG8gZW5hYmxlIGFzc2VydGlvbnMsIG90aGVyd2lzZSBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5hc3NlcnQgPSBmdW5jdGlvbihhc3NlcnQpIHtcclxuICAgICAgICB0aGlzLm5vQXNzZXJ0ID0gIWFzc2VydDtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBjYXBhY2l0eSBvZiB0aGlzIEJ5dGVCdWZmZXIncyBiYWNraW5nIGJ1ZmZlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IENhcGFjaXR5IG9mIHRoZSBiYWNraW5nIGJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNhcGFjaXR5ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDbGVhcnMgdGhpcyBCeXRlQnVmZmVyJ3Mgb2Zmc2V0cyBieSBzZXR0aW5nIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gdG8gYDBgIGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0gdG8gdGhlXHJcbiAgICAgKiAgYmFja2luZyBidWZmZXIncyBjYXBhY2l0eS4gRGlzY2FyZHMge0BsaW5rIEJ5dGVCdWZmZXIjbWFya2VkT2Zmc2V0fS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgIHRoaXMubGltaXQgPSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoO1xyXG4gICAgICAgIHRoaXMubWFya2VkT2Zmc2V0ID0gLTE7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGNsb25lZCBpbnN0YW5jZSBvZiB0aGlzIEJ5dGVCdWZmZXIsIHByZXNldCB3aXRoIHRoaXMgQnl0ZUJ1ZmZlcidzIHZhbHVlcyBmb3Ige0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSxcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrZWRPZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBjb3B5IFdoZXRoZXIgdG8gY29weSB0aGUgYmFja2luZyBidWZmZXIgb3IgdG8gcmV0dXJuIGFub3RoZXIgdmlldyBvbiB0aGUgc2FtZSwgZGVmYXVsdHMgdG8gYGZhbHNlYFxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBDbG9uZWQgaW5zdGFuY2VcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uKGNvcHkpIHtcclxuICAgICAgICB2YXIgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigwLCB0aGlzLmxpdHRsZUVuZGlhbiwgdGhpcy5ub0Fzc2VydCk7XHJcbiAgICAgICAgaWYgKGNvcHkpIHtcclxuICAgICAgICAgICAgYmIuYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG4gICAgICAgICAgICBiYi52aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYmIuYnVmZmVyKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBiYi5idWZmZXIgPSB0aGlzLmJ1ZmZlcjtcclxuICAgICAgICAgICAgYmIudmlldyA9IHRoaXMudmlldztcclxuICAgICAgICB9XHJcbiAgICAgICAgYmIub2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgYmIubWFya2VkT2Zmc2V0ID0gdGhpcy5tYXJrZWRPZmZzZXQ7XHJcbiAgICAgICAgYmIubGltaXQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb21wYWN0cyB0aGlzIEJ5dGVCdWZmZXIgdG8gYmUgYmFja2VkIGJ5IGEge0BsaW5rIEJ5dGVCdWZmZXIjYnVmZmVyfSBvZiBpdHMgY29udGVudHMnIGxlbmd0aC4gQ29udGVudHMgYXJlIHRoZSBieXRlc1xyXG4gICAgICogIGJldHdlZW4ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LiBXaWxsIHNldCBgb2Zmc2V0ID0gMGAgYW5kIGBsaW1pdCA9IGNhcGFjaXR5YCBhbmRcclxuICAgICAqICBhZGFwdCB7QGxpbmsgQnl0ZUJ1ZmZlciNtYXJrZWRPZmZzZXR9IHRvIHRoZSBzYW1lIHJlbGF0aXZlIHBvc2l0aW9uIGlmIHNldC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gT2Zmc2V0IHRvIHN0YXJ0IGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH1cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmNvbXBhY3QgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChiZWdpbiA9PT0gMCAmJiBlbmQgPT09IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzOyAvLyBBbHJlYWR5IGNvbXBhY3RlZFxyXG4gICAgICAgIHZhciBsZW4gPSBlbmQgLSBiZWdpbjtcclxuICAgICAgICBpZiAobGVuID09PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgICAgICB0aGlzLnZpZXcgPSBudWxsO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5tYXJrZWRPZmZzZXQgPj0gMCkgdGhpcy5tYXJrZWRPZmZzZXQgLT0gYmVnaW47XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgdGhpcy5saW1pdCA9IDA7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGxlbik7XHJcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xyXG4gICAgICAgIHZpZXcuc2V0KHRoaXMudmlldy5zdWJhcnJheShiZWdpbiwgZW5kKSk7XHJcbiAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7XHJcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcclxuICAgICAgICBpZiAodGhpcy5tYXJrZWRPZmZzZXQgPj0gMCkgdGhpcy5tYXJrZWRPZmZzZXQgLT0gYmVnaW47XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xyXG4gICAgICAgIHRoaXMubGltaXQgPSBsZW47XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZFxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gQmVnaW4gb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgRW5kIG9mZnNldCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBDb3B5XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJlZ2luID09PSBlbmQpXHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQnl0ZUJ1ZmZlcigwLCB0aGlzLmxpdHRsZUVuZGlhbiwgdGhpcy5ub0Fzc2VydCk7XHJcbiAgICAgICAgdmFyIGNhcGFjaXR5ID0gZW5kIC0gYmVnaW4sXHJcbiAgICAgICAgICAgIGJiID0gbmV3IEJ5dGVCdWZmZXIoY2FwYWNpdHksIHRoaXMubGl0dGxlRW5kaWFuLCB0aGlzLm5vQXNzZXJ0KTtcclxuICAgICAgICBiYi5vZmZzZXQgPSAwO1xyXG4gICAgICAgIGJiLmxpbWl0ID0gY2FwYWNpdHk7XHJcbiAgICAgICAgaWYgKGJiLm1hcmtlZE9mZnNldCA+PSAwKSBiYi5tYXJrZWRPZmZzZXQgLT0gYmVnaW47XHJcbiAgICAgICAgdGhpcy5jb3B5VG8oYmIsIDAsIGJlZ2luLCBlbmQpO1xyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb3BpZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgdG8gYW5vdGhlciBCeXRlQnVmZmVyLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW4ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmRcclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfSB0YXJnZXQgVGFyZ2V0IEJ5dGVCdWZmZXJcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gdGFyZ2V0T2Zmc2V0IE9mZnNldCB0byBjb3B5IHRvLiBXaWxsIHVzZSBhbmQgaW5jcmVhc2UgdGhlIHRhcmdldCdzIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH1cclxuICAgICAqICBieSB0aGUgbnVtYmVyIG9mIGJ5dGVzIGNvcGllZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBzb3VyY2VPZmZzZXQgT2Zmc2V0IHRvIHN0YXJ0IGNvcHlpbmcgZnJvbS4gV2lsbCB1c2UgYW5kIGluY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlXHJcbiAgICAgKiAgbnVtYmVyIG9mIGJ5dGVzIGNvcGllZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBzb3VyY2VMaW1pdCBPZmZzZXQgdG8gZW5kIGNvcHlpbmcgZnJvbSwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9XHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5jb3B5VG8gPSBmdW5jdGlvbih0YXJnZXQsIHRhcmdldE9mZnNldCwgc291cmNlT2Zmc2V0LCBzb3VyY2VMaW1pdCkge1xyXG4gICAgICAgIHZhciByZWxhdGl2ZSxcclxuICAgICAgICAgICAgdGFyZ2V0UmVsYXRpdmU7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICghQnl0ZUJ1ZmZlci5pc0J5dGVCdWZmZXIodGFyZ2V0KSlcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgdGFyZ2V0OiBOb3QgYSBCeXRlQnVmZmVyXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0YXJnZXRPZmZzZXQgPSAodGFyZ2V0UmVsYXRpdmUgPSB0eXBlb2YgdGFyZ2V0T2Zmc2V0ID09PSAndW5kZWZpbmVkJykgPyB0YXJnZXQub2Zmc2V0IDogdGFyZ2V0T2Zmc2V0IHwgMDtcclxuICAgICAgICBzb3VyY2VPZmZzZXQgPSAocmVsYXRpdmUgPSB0eXBlb2Ygc291cmNlT2Zmc2V0ID09PSAndW5kZWZpbmVkJykgPyB0aGlzLm9mZnNldCA6IHNvdXJjZU9mZnNldCB8IDA7XHJcbiAgICAgICAgc291cmNlTGltaXQgPSB0eXBlb2Ygc291cmNlTGltaXQgPT09ICd1bmRlZmluZWQnID8gdGhpcy5saW1pdCA6IHNvdXJjZUxpbWl0IHwgMDtcclxuXHJcbiAgICAgICAgaWYgKHRhcmdldE9mZnNldCA8IDAgfHwgdGFyZ2V0T2Zmc2V0ID4gdGFyZ2V0LmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCB0YXJnZXQgcmFuZ2U6IDAgPD0gXCIrdGFyZ2V0T2Zmc2V0K1wiIDw9IFwiK3RhcmdldC5idWZmZXIuYnl0ZUxlbmd0aCk7XHJcbiAgICAgICAgaWYgKHNvdXJjZU9mZnNldCA8IDAgfHwgc291cmNlTGltaXQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBzb3VyY2UgcmFuZ2U6IDAgPD0gXCIrc291cmNlT2Zmc2V0K1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xyXG5cclxuICAgICAgICB2YXIgbGVuID0gc291cmNlTGltaXQgLSBzb3VyY2VPZmZzZXQ7XHJcbiAgICAgICAgaWYgKGxlbiA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRhcmdldDsgLy8gTm90aGluZyB0byBjb3B5XHJcblxyXG4gICAgICAgIHRhcmdldC5lbnN1cmVDYXBhY2l0eSh0YXJnZXRPZmZzZXQgKyBsZW4pO1xyXG5cclxuICAgICAgICB0YXJnZXQudmlldy5zZXQodGhpcy52aWV3LnN1YmFycmF5KHNvdXJjZU9mZnNldCwgc291cmNlTGltaXQpLCB0YXJnZXRPZmZzZXQpO1xyXG5cclxuICAgICAgICBpZiAocmVsYXRpdmUpIHRoaXMub2Zmc2V0ICs9IGxlbjtcclxuICAgICAgICBpZiAodGFyZ2V0UmVsYXRpdmUpIHRhcmdldC5vZmZzZXQgKz0gbGVuO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYWtlcyBzdXJlIHRoYXQgdGhpcyBCeXRlQnVmZmVyIGlzIGJhY2tlZCBieSBhIHtAbGluayBCeXRlQnVmZmVyI2J1ZmZlcn0gb2YgYXQgbGVhc3QgdGhlIHNwZWNpZmllZCBjYXBhY2l0eS4gSWYgdGhlXHJcbiAgICAgKiAgY3VycmVudCBjYXBhY2l0eSBpcyBleGNlZWRlZCwgaXQgd2lsbCBiZSBkb3VibGVkLiBJZiBkb3VibGUgdGhlIGN1cnJlbnQgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIHRoZSByZXF1aXJlZCBjYXBhY2l0eSxcclxuICAgICAqICB0aGUgcmVxdWlyZWQgY2FwYWNpdHkgd2lsbCBiZSB1c2VkIGluc3RlYWQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2FwYWNpdHkgUmVxdWlyZWQgY2FwYWNpdHlcclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLmVuc3VyZUNhcGFjaXR5ID0gZnVuY3Rpb24oY2FwYWNpdHkpIHtcclxuICAgICAgICB2YXIgY3VycmVudCA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7XHJcbiAgICAgICAgaWYgKGN1cnJlbnQgPCBjYXBhY2l0eSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVzaXplKChjdXJyZW50ICo9IDIpID4gY2FwYWNpdHkgPyBjdXJyZW50IDogY2FwYWNpdHkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE92ZXJ3cml0ZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLiBDb250ZW50cyBhcmUgdGhlIGJ5dGVzIGJldHdlZW5cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnxzdHJpbmd9IHZhbHVlIEJ5dGUgdmFsdWUgdG8gZmlsbCB3aXRoLiBJZiBnaXZlbiBhcyBhIHN0cmluZywgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyB1c2VkLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBCZWdpbiBvZmZzZXQuIFdpbGwgdXNlIGFuZCBpbmNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICB3cml0dGVuIGlmIG9taXR0ZWQuIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBFbmQgb2Zmc2V0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBleGFtcGxlIGBzb21lQnl0ZUJ1ZmZlci5jbGVhcigpLmZpbGwoMClgIGZpbGxzIHRoZSBlbnRpcmUgYmFja2luZyBidWZmZXIgd2l0aCB6ZXJvZXNcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24odmFsdWUsIGJlZ2luLCBlbmQpIHtcclxuICAgICAgICB2YXIgcmVsYXRpdmUgPSB0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUuY2hhckNvZGVBdCgwKTtcclxuICAgICAgICBpZiAodHlwZW9mIGJlZ2luID09PSAndW5kZWZpbmVkJykgYmVnaW4gPSB0aGlzLm9mZnNldDtcclxuICAgICAgICBpZiAodHlwZW9mIGVuZCA9PT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGltaXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8IHZhbHVlICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHZhbHVlOiBcIit2YWx1ZStcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgdmFsdWUgfD0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJlZ2luID49IGVuZClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7IC8vIE5vdGhpbmcgdG8gZmlsbFxyXG4gICAgICAgIHdoaWxlIChiZWdpbiA8IGVuZCkgdGhpcy52aWV3W2JlZ2luKytdID0gdmFsdWU7XHJcbiAgICAgICAgaWYgKHJlbGF0aXZlKSB0aGlzLm9mZnNldCA9IGJlZ2luO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ha2VzIHRoaXMgQnl0ZUJ1ZmZlciByZWFkeSBmb3IgYSBuZXcgc2VxdWVuY2Ugb2Ygd3JpdGUgb3IgcmVsYXRpdmUgcmVhZCBvcGVyYXRpb25zLiBTZXRzIGBsaW1pdCA9IG9mZnNldGAgYW5kXHJcbiAgICAgKiAgYG9mZnNldCA9IDBgLiBNYWtlIHN1cmUgYWx3YXlzIHRvIGZsaXAgYSBCeXRlQnVmZmVyIHdoZW4gYWxsIHJlbGF0aXZlIHJlYWQgb3Igd3JpdGUgb3BlcmF0aW9ucyBhcmUgY29tcGxldGUuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5mbGlwID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdGhpcy5saW1pdCA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIE1hcmtzIGFuIG9mZnNldCBvbiB0aGlzIEJ5dGVCdWZmZXIgdG8gYmUgdXNlZCBsYXRlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb2Zmc2V0IE9mZnNldCB0byBtYXJrLiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGBvZmZzZXRgIGlzIG5vdCBhIHZhbGlkIG51bWJlclxyXG4gICAgICogQHRocm93cyB7UmFuZ2VFcnJvcn0gSWYgYG9mZnNldGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3Jlc2V0XHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUubWFyayA9IGZ1bmN0aW9uKG9mZnNldCkge1xyXG4gICAgICAgIG9mZnNldCA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnID8gdGhpcy5vZmZzZXQgOiBvZmZzZXQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2Zmc2V0ICE9PSAnbnVtYmVyJyB8fCBvZmZzZXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgb2Zmc2V0OiBcIitvZmZzZXQrXCIgKG5vdCBhbiBpbnRlZ2VyKVwiKTtcbiAgICAgICAgICAgIG9mZnNldCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgKyAwID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IDAgPD0gXCIrb2Zmc2V0K1wiICgrXCIrMCtcIikgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm1hcmtlZE9mZnNldCA9IG9mZnNldDtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGJ5dGUgb3JkZXIuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxpdHRsZUVuZGlhbiBgdHJ1ZWAgZm9yIGxpdHRsZSBlbmRpYW4gYnl0ZSBvcmRlciwgYGZhbHNlYCBmb3IgYmlnIGVuZGlhblxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUub3JkZXIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBsaXR0bGVFbmRpYW4gIT09ICdib29sZWFuJylcclxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgbGl0dGxlRW5kaWFuOiBOb3QgYSBib29sZWFuXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmxpdHRsZUVuZGlhbiA9ICEhbGl0dGxlRW5kaWFuO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN3aXRjaGVzICh0bykgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIERlZmF1bHRzIHRvIGB0cnVlYCwgb3RoZXJ3aXNlIHVzZXMgYmlnIGVuZGlhblxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuTEUgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcclxuICAgICAgICB0aGlzLmxpdHRsZUVuZGlhbiA9IHR5cGVvZiBsaXR0bGVFbmRpYW4gIT09ICd1bmRlZmluZWQnID8gISFsaXR0bGVFbmRpYW4gOiB0cnVlO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFN3aXRjaGVzICh0bykgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gYmlnRW5kaWFuIERlZmF1bHRzIHRvIGB0cnVlYCwgb3RoZXJ3aXNlIHVzZXMgbGl0dGxlIGVuZGlhblxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuQkUgPSBmdW5jdGlvbihiaWdFbmRpYW4pIHtcclxuICAgICAgICB0aGlzLmxpdHRsZUVuZGlhbiA9IHR5cGVvZiBiaWdFbmRpYW4gIT09ICd1bmRlZmluZWQnID8gIWJpZ0VuZGlhbiA6IGZhbHNlO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUHJlcGVuZHMgc29tZSBkYXRhIHRvIHRoaXMgQnl0ZUJ1ZmZlci4gVGhpcyB3aWxsIG92ZXJ3cml0ZSBhbnkgY29udGVudHMgYmVmb3JlIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHVwIHRvIHRoZVxyXG4gICAgICogIHByZXBlbmRlZCBkYXRhJ3MgbGVuZ3RoLiBJZiB0aGVyZSBpcyBub3QgZW5vdWdoIHNwYWNlIGF2YWlsYWJsZSBiZWZvcmUgdGhlIHNwZWNpZmllZCBgb2Zmc2V0YCwgdGhlIGJhY2tpbmcgYnVmZmVyXHJcbiAgICAgKiAgd2lsbCBiZSByZXNpemVkIGFuZCBpdHMgY29udGVudHMgbW92ZWQgYWNjb3JkaW5nbHkuXHJcbiAgICAgKiBAcGFyYW0geyFCeXRlQnVmZmVyfHN0cmluZ3whQXJyYXlCdWZmZXJ9IHNvdXJjZSBEYXRhIHRvIHByZXBlbmQuIElmIGBzb3VyY2VgIGlzIGEgQnl0ZUJ1ZmZlciwgaXRzIG9mZnNldCB3aWxsIGJlXHJcbiAgICAgKiAgbW9kaWZpZWQgYWNjb3JkaW5nIHRvIHRoZSBwZXJmb3JtZWQgcmVhZCBvcGVyYXRpb24uXHJcbiAgICAgKiBAcGFyYW0geyhzdHJpbmd8bnVtYmVyKT19IGVuY29kaW5nIEVuY29kaW5nIGlmIGBkYXRhYCBpcyBhIHN0cmluZyAoXCJiYXNlNjRcIiwgXCJoZXhcIiwgXCJiaW5hcnlcIiwgZGVmYXVsdHMgdG8gXCJ1dGY4XCIpXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9mZnNldCBPZmZzZXQgdG8gcHJlcGVuZCBhdC4gV2lsbCB1c2UgYW5kIGRlY3JlYXNlIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYnkgdGhlIG51bWJlciBvZiBieXRlc1xyXG4gICAgICogIHByZXBlbmRlZCBpZiBvbWl0dGVkLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKiBAZXhhbXBsZSBBIHJlbGF0aXZlIGAwMDwwMSAwMiAwMz4ucHJlcGVuZCg8MDQgMDU+KWAgcmVzdWx0cyBpbiBgPDA0IDA1IDAxIDAyIDAzPiwgMDQgMDV8YFxyXG4gICAgICogQGV4YW1wbGUgQW4gYWJzb2x1dGUgYDAwPDAxIDAyIDAzPi5wcmVwZW5kKDwwNCAwNT4sIDIpYCByZXN1bHRzIGluIGAwNDwwNSAwMiAwMz4sIDA0IDA1fGBcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5wcmVwZW5kID0gZnVuY3Rpb24oc291cmNlLCBlbmNvZGluZywgb2Zmc2V0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ251bWJlcicgfHwgdHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICBvZmZzZXQgPSBlbmNvZGluZztcclxuICAgICAgICAgICAgZW5jb2RpbmcgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciByZWxhdGl2ZSA9IHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnO1xuICAgICAgICBpZiAocmVsYXRpdmUpIG9mZnNldCA9IHRoaXMub2Zmc2V0O1xuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvZmZzZXQgIT09ICdudW1iZXInIHx8IG9mZnNldCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBvZmZzZXQ6IFwiK29mZnNldCtcIiAobm90IGFuIGludGVnZXIpXCIpO1xuICAgICAgICAgICAgb2Zmc2V0ID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCArIDAgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogMCA8PSBcIitvZmZzZXQrXCIgKCtcIiswK1wiKSA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghKHNvdXJjZSBpbnN0YW5jZW9mIEJ5dGVCdWZmZXIpKVxyXG4gICAgICAgICAgICBzb3VyY2UgPSBCeXRlQnVmZmVyLndyYXAoc291cmNlLCBlbmNvZGluZyk7XHJcbiAgICAgICAgdmFyIGxlbiA9IHNvdXJjZS5saW1pdCAtIHNvdXJjZS5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKGxlbiA8PSAwKSByZXR1cm4gdGhpczsgLy8gTm90aGluZyB0byBwcmVwZW5kXHJcbiAgICAgICAgdmFyIGRpZmYgPSBsZW4gLSBvZmZzZXQ7XHJcbiAgICAgICAgaWYgKGRpZmYgPiAwKSB7IC8vIE5vdCBlbm91Z2ggc3BhY2UgYmVmb3JlIG9mZnNldCwgc28gcmVzaXplICsgbW92ZVxyXG4gICAgICAgICAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGggKyBkaWZmKTtcclxuICAgICAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xyXG4gICAgICAgICAgICB2aWV3LnNldCh0aGlzLnZpZXcuc3ViYXJyYXkob2Zmc2V0LCB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKSwgbGVuKTtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7XHJcbiAgICAgICAgICAgIHRoaXMudmlldyA9IHZpZXc7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ICs9IGRpZmY7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1hcmtlZE9mZnNldCA+PSAwKSB0aGlzLm1hcmtlZE9mZnNldCArPSBkaWZmO1xyXG4gICAgICAgICAgICB0aGlzLmxpbWl0ICs9IGRpZmY7XHJcbiAgICAgICAgICAgIG9mZnNldCArPSBkaWZmO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBhcnJheVZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmJ1ZmZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudmlldy5zZXQoc291cmNlLnZpZXcuc3ViYXJyYXkoc291cmNlLm9mZnNldCwgc291cmNlLmxpbWl0KSwgb2Zmc2V0IC0gbGVuKTtcclxuXHJcbiAgICAgICAgc291cmNlLm9mZnNldCA9IHNvdXJjZS5saW1pdDtcclxuICAgICAgICBpZiAocmVsYXRpdmUpXHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0IC09IGxlbjtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVwZW5kcyB0aGlzIEJ5dGVCdWZmZXIgdG8gYW5vdGhlciBCeXRlQnVmZmVyLiBUaGlzIHdpbGwgb3ZlcndyaXRlIGFueSBjb250ZW50cyBiZWZvcmUgdGhlIHNwZWNpZmllZCBvZmZzZXQgdXAgdG8gdGhlXHJcbiAgICAgKiAgcHJlcGVuZGVkIGRhdGEncyBsZW5ndGguIElmIHRoZXJlIGlzIG5vdCBlbm91Z2ggc3BhY2UgYXZhaWxhYmxlIGJlZm9yZSB0aGUgc3BlY2lmaWVkIGBvZmZzZXRgLCB0aGUgYmFja2luZyBidWZmZXJcclxuICAgICAqICB3aWxsIGJlIHJlc2l6ZWQgYW5kIGl0cyBjb250ZW50cyBtb3ZlZCBhY2NvcmRpbmdseS5cclxuICAgICAqIEBwYXJhbSB7IUJ5dGVCdWZmZXJ9IHRhcmdldCBUYXJnZXQgQnl0ZUJ1ZmZlclxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBvZmZzZXQgT2Zmc2V0IHRvIHByZXBlbmQgYXQuIFdpbGwgdXNlIGFuZCBkZWNyZWFzZSB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGJ5IHRoZSBudW1iZXIgb2YgYnl0ZXNcclxuICAgICAqICBwcmVwZW5kZWQgaWYgb21pdHRlZC5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICogQHNlZSBCeXRlQnVmZmVyI3ByZXBlbmRcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS5wcmVwZW5kVG8gPSBmdW5jdGlvbih0YXJnZXQsIG9mZnNldCkge1xyXG4gICAgICAgIHRhcmdldC5wcmVwZW5kKHRoaXMsIG9mZnNldCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQcmludHMgZGVidWcgaW5mb3JtYXRpb24gYWJvdXQgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMuXHJcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHN0cmluZyk9fSBvdXQgT3V0cHV0IGZ1bmN0aW9uIHRvIGNhbGwsIGRlZmF1bHRzIHRvIGNvbnNvbGUubG9nXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucHJpbnREZWJ1ZyA9IGZ1bmN0aW9uKG91dCkge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygb3V0ICE9PSAnZnVuY3Rpb24nKSBvdXQgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO1xyXG4gICAgICAgIG91dChcclxuICAgICAgICAgICAgdGhpcy50b1N0cmluZygpK1wiXFxuXCIrXHJcbiAgICAgICAgICAgIFwiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxcblwiK1xyXG4gICAgICAgICAgICB0aGlzLnRvRGVidWcoLyogY29sdW1ucyAqLyB0cnVlKVxyXG4gICAgICAgICk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIHJlbWFpbmluZyByZWFkYWJsZSBieXRlcy4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LCBzbyB0aGlzIHJldHVybnMgYGxpbWl0IC0gb2Zmc2V0YC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJlbWFpbmluZyByZWFkYWJsZSBieXRlcy4gTWF5IGJlIG5lZ2F0aXZlIGlmIGBvZmZzZXQgPiBsaW1pdGAuXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVtYWluaW5nID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGltaXQgLSB0aGlzLm9mZnNldDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlc2V0cyB0aGlzIEJ5dGVCdWZmZXIncyB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LiBJZiBhbiBvZmZzZXQgaGFzIGJlZW4gbWFya2VkIHRocm91Z2gge0BsaW5rIEJ5dGVCdWZmZXIjbWFya31cclxuICAgICAqICBiZWZvcmUsIGBvZmZzZXRgIHdpbGwgYmUgc2V0IHRvIHtAbGluayBCeXRlQnVmZmVyI21hcmtlZE9mZnNldH0sIHdoaWNoIHdpbGwgdGhlbiBiZSBkaXNjYXJkZWQuIElmIG5vIG9mZnNldCBoYXMgYmVlblxyXG4gICAgICogIG1hcmtlZCwgc2V0cyBgb2Zmc2V0ID0gMGAuXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciNtYXJrXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBpZiAodGhpcy5tYXJrZWRPZmZzZXQgPj0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLm9mZnNldCA9IHRoaXMubWFya2VkT2Zmc2V0O1xyXG4gICAgICAgICAgICB0aGlzLm1hcmtlZE9mZnNldCA9IC0xO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXNpemVzIHRoaXMgQnl0ZUJ1ZmZlciB0byBiZSBiYWNrZWQgYnkgYSBidWZmZXIgb2YgYXQgbGVhc3QgdGhlIGdpdmVuIGNhcGFjaXR5LiBXaWxsIGRvIG5vdGhpbmcgaWYgYWxyZWFkeSB0aGF0XHJcbiAgICAgKiAgbGFyZ2Ugb3IgbGFyZ2VyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNhcGFjaXR5IENhcGFjaXR5IHJlcXVpcmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IHRoaXNcclxuICAgICAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYGNhcGFjaXR5YCBpcyBub3QgYSBudW1iZXJcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBjYXBhY2l0eSA8IDBgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24oY2FwYWNpdHkpIHtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjYXBhY2l0eSAhPT0gJ251bWJlcicgfHwgY2FwYWNpdHkgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgY2FwYWNpdHk6IFwiK2NhcGFjaXR5K1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBjYXBhY2l0eSB8PSAwO1xuICAgICAgICAgICAgaWYgKGNhcGFjaXR5IDwgMClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIGNhcGFjaXR5OiAwIDw9IFwiK2NhcGFjaXR5KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGggPCBjYXBhY2l0eSkge1xyXG4gICAgICAgICAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGNhcGFjaXR5KTtcclxuICAgICAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xyXG4gICAgICAgICAgICB2aWV3LnNldCh0aGlzLnZpZXcpO1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcclxuICAgICAgICAgICAgdGhpcy52aWV3ID0gdmlldztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXZlcnNlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gT2Zmc2V0IHRvIHN0YXJ0IGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH1cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gdGhpc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnJldmVyc2UgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGJlZ2luICE9PSAnbnVtYmVyJyB8fCBiZWdpbiAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBiZWdpbjogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBiZWdpbiA+Pj49IDA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVuZCAhPT0gJ251bWJlcicgfHwgZW5kICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGVuZDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBlbmQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKGJlZ2luIDwgMCB8fCBiZWdpbiA+IGVuZCB8fCBlbmQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK2JlZ2luK1wiIDw9IFwiK2VuZCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChiZWdpbiA9PT0gZW5kKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpczsgLy8gTm90aGluZyB0byByZXZlcnNlXHJcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnJldmVyc2UuY2FsbCh0aGlzLnZpZXcuc3ViYXJyYXkoYmVnaW4sIGVuZCkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2tpcHMgdGhlIG5leHQgYGxlbmd0aGAgYnl0ZXMuIFRoaXMgd2lsbCBqdXN0IGFkdmFuY2VcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGJ5dGVzIHRvIHNraXAuIE1heSBhbHNvIGJlIG5lZ2F0aXZlIHRvIG1vdmUgdGhlIG9mZnNldCBiYWNrLlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSB0aGlzXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUuc2tpcCA9IGZ1bmN0aW9uKGxlbmd0aCkge1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGxlbmd0aCAhPT0gJ251bWJlcicgfHwgbGVuZ3RoICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGxlbmd0aDogXCIrbGVuZ3RoK1wiIChub3QgYW4gaW50ZWdlcilcIik7XG4gICAgICAgICAgICBsZW5ndGggfD0gMDtcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLm9mZnNldCArIGxlbmd0aDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIGxlbmd0aDogMCA8PSBcIit0aGlzLm9mZnNldCtcIiArIFwiK2xlbmd0aCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5vZmZzZXQgPSBvZmZzZXQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2xpY2VzIHRoaXMgQnl0ZUJ1ZmZlciBieSBjcmVhdGluZyBhIGNsb25lZCBpbnN0YW5jZSB3aXRoIGBvZmZzZXQgPSBiZWdpbmAgYW5kIGBsaW1pdCA9IGVuZGAuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGJlZ2luIEJlZ2luIG9mZnNldCwgZGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gZW5kIEVuZCBvZmZzZXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQ2xvbmUgb2YgdGhpcyBCeXRlQnVmZmVyIHdpdGggc2xpY2luZyBhcHBsaWVkLCBiYWNrZWQgYnkgdGhlIHNhbWUge0BsaW5rIEJ5dGVCdWZmZXIjYnVmZmVyfVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgYmIgPSB0aGlzLmNsb25lKCk7XHJcbiAgICAgICAgYmIub2Zmc2V0ID0gYmVnaW47XHJcbiAgICAgICAgYmIubGltaXQgPSBlbmQ7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhlIGJhY2tpbmcgYnVmZmVyIHRoYXQgY29udGFpbnMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMuIENvbnRlbnRzIGFyZSB0aGUgYnl0ZXMgYmV0d2VlblxyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0gYW5kIHtAbGluayBCeXRlQnVmZmVyI2xpbWl0fS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGZvcmNlQ29weSBJZiBgdHJ1ZWAgcmV0dXJucyBhIGNvcHksIG90aGVyd2lzZSByZXR1cm5zIGEgdmlldyByZWZlcmVuY2luZyB0aGUgc2FtZSBtZW1vcnkgaWZcclxuICAgICAqICBwb3NzaWJsZS4gRGVmYXVsdHMgdG8gYGZhbHNlYFxyXG4gICAgICogQHJldHVybnMgeyFBcnJheUJ1ZmZlcn0gQ29udGVudHMgYXMgYW4gQXJyYXlCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlclByb3RvdHlwZS50b0J1ZmZlciA9IGZ1bmN0aW9uKGZvcmNlQ29weSkge1xyXG4gICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLm9mZnNldCxcclxuICAgICAgICAgICAgbGltaXQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGlmICghdGhpcy5ub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIG9mZnNldDogTm90IGFuIGludGVnZXJcIik7XG4gICAgICAgICAgICBvZmZzZXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBsaW1pdCAhPT0gJ251bWJlcicgfHwgbGltaXQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgbGltaXQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgbGltaXQgPj4+PSAwO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gbGltaXQgfHwgbGltaXQgPiB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiAwIDw9IFwiK29mZnNldCtcIiA8PSBcIitsaW1pdCtcIiA8PSBcIit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKTtcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE5PVEU6IEl0J3Mgbm90IHBvc3NpYmxlIHRvIGhhdmUgYW5vdGhlciBBcnJheUJ1ZmZlciByZWZlcmVuY2UgdGhlIHNhbWUgbWVtb3J5IGFzIHRoZSBiYWNraW5nIGJ1ZmZlci4gVGhpcyBpc1xyXG4gICAgICAgIC8vIHBvc3NpYmxlIHdpdGggVWludDhBcnJheSNzdWJhcnJheSBvbmx5LCBidXQgd2UgaGF2ZSB0byByZXR1cm4gYW4gQXJyYXlCdWZmZXIgYnkgY29udHJhY3QuIFNvOlxyXG4gICAgICAgIGlmICghZm9yY2VDb3B5ICYmIG9mZnNldCA9PT0gMCAmJiBsaW1pdCA9PT0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyO1xyXG4gICAgICAgIGlmIChvZmZzZXQgPT09IGxpbWl0KVxyXG4gICAgICAgICAgICByZXR1cm4gRU1QVFlfQlVGRkVSO1xyXG4gICAgICAgIHZhciBidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIobGltaXQgLSBvZmZzZXQpO1xyXG4gICAgICAgIG5ldyBVaW50OEFycmF5KGJ1ZmZlcikuc2V0KG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyKS5zdWJhcnJheShvZmZzZXQsIGxpbWl0KSwgMCk7XHJcbiAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgcmF3IGJ1ZmZlciBjb21wYWN0ZWQgdG8gY29udGFpbiB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cy4gQ29udGVudHMgYXJlIHRoZSBieXRlcyBiZXR3ZWVuXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIjb2Zmc2V0fSBhbmQge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBCeXRlQnVmZmVyI3RvQnVmZmVyfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gZm9yY2VDb3B5IElmIGB0cnVlYCByZXR1cm5zIGEgY29weSwgb3RoZXJ3aXNlIHJldHVybnMgYSB2aWV3IHJlZmVyZW5jaW5nIHRoZSBzYW1lIG1lbW9yeS5cclxuICAgICAqICBEZWZhdWx0cyB0byBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5QnVmZmVyfSBDb250ZW50cyBhcyBhbiBBcnJheUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvQXJyYXlCdWZmZXIgPSBCeXRlQnVmZmVyUHJvdG90eXBlLnRvQnVmZmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIEJ5dGVCdWZmZXIncyBjb250ZW50cyB0byBhIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nPX0gZW5jb2RpbmcgT3V0cHV0IGVuY29kaW5nLiBSZXR1cm5zIGFuIGluZm9ybWF0aXZlIHN0cmluZyByZXByZXNlbnRhdGlvbiBpZiBvbWl0dGVkIGJ1dCBhbHNvIGFsbG93c1xyXG4gICAgICogIGRpcmVjdCBjb252ZXJzaW9uIHRvIFwidXRmOFwiLCBcImhleFwiLCBcImJhc2U2NFwiIGFuZCBcImJpbmFyeVwiIGVuY29kaW5nLiBcImRlYnVnXCIgcmV0dXJucyBhIGhleCByZXByZXNlbnRhdGlvbiB3aXRoXHJcbiAgICAgKiAgaGlnaGxpZ2h0ZWQgb2Zmc2V0cy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gT2Zmc2V0IHRvIGJlZ2luIGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH1cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyByZXByZXNlbnRhdGlvblxyXG4gICAgICogQHRocm93cyB7RXJyb3J9IElmIGBlbmNvZGluZ2AgaXMgaW52YWxpZFxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oZW5jb2RpbmcsIGJlZ2luLCBlbmQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgcmV0dXJuIFwiQnl0ZUJ1ZmZlckFCKG9mZnNldD1cIit0aGlzLm9mZnNldCtcIixtYXJrZWRPZmZzZXQ9XCIrdGhpcy5tYXJrZWRPZmZzZXQrXCIsbGltaXQ9XCIrdGhpcy5saW1pdCtcIixjYXBhY2l0eT1cIit0aGlzLmNhcGFjaXR5KCkrXCIpXCI7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ251bWJlcicpXHJcbiAgICAgICAgICAgIGVuY29kaW5nID0gXCJ1dGY4XCIsXHJcbiAgICAgICAgICAgIGJlZ2luID0gZW5jb2RpbmcsXHJcbiAgICAgICAgICAgIGVuZCA9IGJlZ2luO1xyXG4gICAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcclxuICAgICAgICAgICAgY2FzZSBcInV0ZjhcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvVVRGOChiZWdpbiwgZW5kKTtcclxuICAgICAgICAgICAgY2FzZSBcImJhc2U2NFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9CYXNlNjQoYmVnaW4sIGVuZCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJoZXhcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvSGV4KGJlZ2luLCBlbmQpO1xyXG4gICAgICAgICAgICBjYXNlIFwiYmluYXJ5XCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0JpbmFyeShiZWdpbiwgZW5kKTtcclxuICAgICAgICAgICAgY2FzZSBcImRlYnVnXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0RlYnVnKCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJjb2x1bW5zXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0NvbHVtbnMoKTtcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiVW5zdXBwb3J0ZWQgZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIGx4aXYtZW1iZWRkYWJsZVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogbHhpdi1lbWJlZGRhYmxlIChjKSAyMDE0IERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiAgICAgKiBSZWxlYXNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wXHJcbiAgICAgKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL2x4aXYgZm9yIGRldGFpbHNcclxuICAgICAqL1xyXG4gICAgdmFyIGx4aXYgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogbHhpdiBuYW1lc3BhY2UuXHJcbiAgICAgICAgICogQHR5cGUgeyFPYmplY3QuPHN0cmluZywqPn1cclxuICAgICAgICAgKiBAZXhwb3J0cyBseGl2XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIGx4aXYgPSB7fTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2hhcmFjdGVyIGNvZGVzIGZvciBvdXRwdXQuXHJcbiAgICAgICAgICogQHR5cGUgeyFBcnJheS48bnVtYmVyPn1cclxuICAgICAgICAgKiBAaW5uZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgYW91dCA9IFtcclxuICAgICAgICAgICAgNjUsIDY2LCA2NywgNjgsIDY5LCA3MCwgNzEsIDcyLCA3MywgNzQsIDc1LCA3NiwgNzcsIDc4LCA3OSwgODAsXHJcbiAgICAgICAgICAgIDgxLCA4MiwgODMsIDg0LCA4NSwgODYsIDg3LCA4OCwgODksIDkwLCA5NywgOTgsIDk5LCAxMDAsIDEwMSwgMTAyLFxyXG4gICAgICAgICAgICAxMDMsIDEwNCwgMTA1LCAxMDYsIDEwNywgMTA4LCAxMDksIDExMCwgMTExLCAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsXHJcbiAgICAgICAgICAgIDExOSwgMTIwLCAxMjEsIDEyMiwgNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MywgNTQsIDU1LCA1NiwgNTcsIDQzLCA0N1xyXG4gICAgICAgIF07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENoYXJhY3RlciBjb2RlcyBmb3IgaW5wdXQuXHJcbiAgICAgICAgICogQHR5cGUgeyFBcnJheS48bnVtYmVyPn1cclxuICAgICAgICAgKiBAaW5uZXJcclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgYWluID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgaT0wLCBrPWFvdXQubGVuZ3RoOyBpPGs7ICsraSlcclxuICAgICAgICAgICAgYWluW2FvdXRbaV1dID0gaTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRW5jb2RlcyBieXRlcyB0byBiYXNlNjQgY2hhciBjb2Rlcy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQnl0ZXMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGJ5dGUgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZlxyXG4gICAgICAgICAqICB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBDaGFyYWN0ZXJzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIGVhY2ggZW5jb2RlZCBjaGFyXHJcbiAgICAgICAgICogIGNvZGUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbHhpdi5lbmNvZGUgPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgYiwgdDtcclxuICAgICAgICAgICAgd2hpbGUgKChiID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBkc3QoYW91dFsoYj4+MikmMHgzZl0pO1xyXG4gICAgICAgICAgICAgICAgdCA9IChiJjB4Myk8PDQ7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGIgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICB0IHw9IChiPj40KSYweGY7XHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGFvdXRbKHR8KChiPj40KSYweGYpKSYweDNmXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdCA9IChiJjB4Zik8PDI7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChiID0gc3JjKCkpICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFsodHwoKGI+PjYpJjB4MykpJjB4M2ZdKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHN0KGFvdXRbYiYweDNmXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkc3QoYW91dFt0JjB4M2ZdKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHN0KDYxKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdChhb3V0W3QmMHgzZl0pLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCg2MSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KDYxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlY29kZXMgYmFzZTY0IGNoYXIgY29kZXMgdG8gYnl0ZXMuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gc3JjIENoYXJhY3RlcnMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNoYXIgY29kZSByZXNwZWN0aXZlbHlcclxuICAgICAgICAgKiAgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNoYXJhY3RlcnMgbGVmdC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQnl0ZXMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggdGhlIG5leHQgYnl0ZS5cclxuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgYSBjaGFyYWN0ZXIgY29kZSBpcyBpbnZhbGlkXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgbHhpdi5kZWNvZGUgPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB2YXIgYywgdDEsIHQyO1xyXG4gICAgICAgICAgICBmdW5jdGlvbiBmYWlsKGMpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFwiSWxsZWdhbCBjaGFyYWN0ZXIgY29kZTogXCIrYyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgd2hpbGUgKChjID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICB0MSA9IGFpbltjXTtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdDEgPT09ICd1bmRlZmluZWQnKSBmYWlsKGMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKChjID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdDIgPSBhaW5bY107XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0MiA9PT0gJ3VuZGVmaW5lZCcpIGZhaWwoYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCh0MTw8Mik+Pj4wfCh0MiYweDMwKT4+NCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChjID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHQxID0gYWluW2NdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQxID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID09PSA2MSkgYnJlYWs7IGVsc2UgZmFpbChjKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZHN0KCgodDImMHhmKTw8NCk+Pj4wfCh0MSYweDNjKT4+Mik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYyA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdDIgPSBhaW5bY107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHQyID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA9PT0gNjEpIGJyZWFrOyBlbHNlIGZhaWwoYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3QoKCh0MSYweDMpPDw2KT4+PjB8dDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGVzdHMgaWYgYSBzdHJpbmcgaXMgdmFsaWQgYmFzZTY0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIHRlc3RcclxuICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHZhbGlkLCBvdGhlcndpc2UgYGZhbHNlYFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGx4aXYudGVzdCA9IGZ1bmN0aW9uKHN0cikge1xyXG4gICAgICAgICAgICByZXR1cm4gL14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQvLnRlc3Qoc3RyKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gbHhpdjtcclxuICAgIH0oKTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvYmFzZTY0XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFbmNvZGVzIHRoaXMgQnl0ZUJ1ZmZlcidzIGNvbnRlbnRzIHRvIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBiZWdpbiBPZmZzZXQgdG8gYmVnaW4gYXQsIGRlZmF1bHRzIHRvIHtAbGluayBCeXRlQnVmZmVyI29mZnNldH0uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcj19IGVuZCBPZmZzZXQgdG8gZW5kIGF0LCBkZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0uXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICAgICAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IElmIGBiZWdpbmAgb3IgYGVuZGAgaXMgb3V0IG9mIGJvdW5kc1xyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyUHJvdG90eXBlLnRvQmFzZTY0ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJylcclxuICAgICAgICAgICAgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBiZWdpbiA9IGJlZ2luIHwgMDsgZW5kID0gZW5kIHwgMDtcclxuICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGVuZCA+IHRoaXMuY2FwYWNpdHkgfHwgYmVnaW4gPiBlbmQpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJiZWdpbiwgZW5kXCIpO1xyXG4gICAgICAgIHZhciBzZDsgbHhpdi5lbmNvZGUoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBiZWdpbiA8IGVuZCA/IHRoaXMudmlld1tiZWdpbisrXSA6IG51bGw7XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpLCBzZCA9IHN0cmluZ0Rlc3RpbmF0aW9uKCkpO1xyXG4gICAgICAgIHJldHVybiBzZCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gZGVjb2RlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tQmFzZTY0ID0gZnVuY3Rpb24oc3RyLCBsaXR0bGVFbmRpYW4pIHtcclxuICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcInN0clwiKTtcclxuICAgICAgICB2YXIgYmIgPSBuZXcgQnl0ZUJ1ZmZlcihzdHIubGVuZ3RoLzQqMywgbGl0dGxlRW5kaWFuKSxcclxuICAgICAgICAgICAgaSA9IDA7XHJcbiAgICAgICAgbHhpdi5kZWNvZGUoc3RyaW5nU291cmNlKHN0ciksIGZ1bmN0aW9uKGIpIHtcclxuICAgICAgICAgICAgYmIudmlld1tpKytdID0gYjtcclxuICAgICAgICB9KTtcclxuICAgICAgICBiYi5saW1pdCA9IGk7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgYSBiaW5hcnkgc3RyaW5nIHRvIGJhc2U2NCBsaWtlIGB3aW5kb3cuYnRvYWAgZG9lcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgQmluYXJ5IHN0cmluZ1xyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQmFzZTY0IGVuY29kZWQgc3RyaW5nXHJcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cuYnRvYVxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmJ0b2EgPSBmdW5jdGlvbihzdHIpIHtcclxuICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tQmluYXJ5KHN0cikudG9CYXNlNjQoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWNvZGVzIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nIHRvIGJpbmFyeSBsaWtlIGB3aW5kb3cuYXRvYmAgZG9lcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiNjQgQmFzZTY0IGVuY29kZWQgc3RyaW5nXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBCaW5hcnkgc3RyaW5nXHJcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XaW5kb3cuYXRvYlxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmF0b2IgPSBmdW5jdGlvbihiNjQpIHtcclxuICAgICAgICByZXR1cm4gQnl0ZUJ1ZmZlci5mcm9tQmFzZTY0KGI2NCkudG9CaW5hcnkoKTtcclxuICAgIH07XHJcblxyXG4gICAgLy8gZW5jb2RpbmdzL2JpbmFyeVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIgdG8gYSBiaW5hcnkgZW5jb2RlZCBzdHJpbmcsIHRoYXQgaXMgdXNpbmcgb25seSBjaGFyYWN0ZXJzIDB4MDAtMHhGRiBhcyBieXRlcy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gT2Zmc2V0IHRvIGJlZ2luIGF0LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgT2Zmc2V0IHRvIGVuZCBhdC4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQmluYXJ5IGVuY29kZWQgc3RyaW5nXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0ID4gbGltaXRgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9CaW5hcnkgPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIGJlZ2luID0gdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBlbmQgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICBlbmQgPSB0aGlzLmxpbWl0O1xyXG4gICAgICAgIGJlZ2luIHw9IDA7IGVuZCB8PSAwO1xyXG4gICAgICAgIGlmIChiZWdpbiA8IDAgfHwgZW5kID4gdGhpcy5jYXBhY2l0eSgpIHx8IGJlZ2luID4gZW5kKVxyXG4gICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiYmVnaW4sIGVuZFwiKTtcclxuICAgICAgICBpZiAoYmVnaW4gPT09IGVuZClcclxuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICAgICAgdmFyIGNoYXJzID0gW10sXHJcbiAgICAgICAgICAgIHBhcnRzID0gW107XHJcbiAgICAgICAgd2hpbGUgKGJlZ2luIDwgZW5kKSB7XHJcbiAgICAgICAgICAgIGNoYXJzLnB1c2godGhpcy52aWV3W2JlZ2luKytdKTtcclxuICAgICAgICAgICAgaWYgKGNoYXJzLmxlbmd0aCA+PSAxMDI0KVxyXG4gICAgICAgICAgICAgICAgcGFydHMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2hhcnMpKSxcclxuICAgICAgICAgICAgICAgIGNoYXJzID0gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKCcnKSArIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaGFycyk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGJpbmFyeSBlbmNvZGVkIHN0cmluZywgdGhhdCBpcyB1c2luZyBvbmx5IGNoYXJhY3RlcnMgMHgwMC0weEZGIGFzIGJ5dGVzLCB0byBhIEJ5dGVCdWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBkZWNvZGVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IGxpdHRsZUVuZGlhbiBXaGV0aGVyIHRvIHVzZSBsaXR0bGUgb3IgYmlnIGVuZGlhbiBieXRlIG9yZGVyLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfRU5ESUFOfS5cclxuICAgICAqIEByZXR1cm5zIHshQnl0ZUJ1ZmZlcn0gQnl0ZUJ1ZmZlclxyXG4gICAgICogQGV4cG9zZVxyXG4gICAgICovXHJcbiAgICBCeXRlQnVmZmVyLmZyb21CaW5hcnkgPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwic3RyXCIpO1xyXG4gICAgICAgIHZhciBpID0gMCxcclxuICAgICAgICAgICAgayA9IHN0ci5sZW5ndGgsXHJcbiAgICAgICAgICAgIGNoYXJDb2RlLFxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKGssIGxpdHRsZUVuZGlhbik7XHJcbiAgICAgICAgd2hpbGUgKGk8aykge1xyXG4gICAgICAgICAgICBjaGFyQ29kZSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgICAgICBpZiAoY2hhckNvZGUgPiAweGZmKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcImlsbGVnYWwgY2hhciBjb2RlOiBcIitjaGFyQ29kZSk7XHJcbiAgICAgICAgICAgIGJiLnZpZXdbaSsrXSA9IGNoYXJDb2RlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBiYi5saW1pdCA9IGs7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBlbmNvZGluZ3MvZGVidWdcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgdGhpcyBCeXRlQnVmZmVyIHRvIGEgaGV4IGVuY29kZWQgc3RyaW5nIHdpdGggbWFya2VkIG9mZnNldHMuIE9mZnNldCBzeW1ib2xzIGFyZTpcclxuICAgICAqICogYDxgIDogb2Zmc2V0LFxyXG4gICAgICogKiBgJ2AgOiBtYXJrZWRPZmZzZXQsXHJcbiAgICAgKiAqIGA+YCA6IGxpbWl0LFxyXG4gICAgICogKiBgfGAgOiBvZmZzZXQgYW5kIGxpbWl0LFxyXG4gICAgICogKiBgW2AgOiBvZmZzZXQgYW5kIG1hcmtlZE9mZnNldCxcclxuICAgICAqICogYF1gIDogbWFya2VkT2Zmc2V0IGFuZCBsaW1pdCxcclxuICAgICAqICogYCFgIDogb2Zmc2V0LCBtYXJrZWRPZmZzZXQgYW5kIGxpbWl0XHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBjb2x1bW5zIElmIGB0cnVlYCByZXR1cm5zIHR3byBjb2x1bW5zIGhleCArIGFzY2lpLCBkZWZhdWx0cyB0byBgZmFsc2VgXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfCFBcnJheS48c3RyaW5nPn0gRGVidWcgc3RyaW5nIG9yIGFycmF5IG9mIGxpbmVzIGlmIGBhc0FycmF5ID0gdHJ1ZWBcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBleGFtcGxlIGA+MDAnMDEgMDI8MDNgIGNvbnRhaW5zIGZvdXIgYnl0ZXMgd2l0aCBgbGltaXQ9MCwgbWFya2VkT2Zmc2V0PTEsIG9mZnNldD0zYFxyXG4gICAgICogQGV4YW1wbGUgYDAwWzAxIDAyIDAzPmAgY29udGFpbnMgZm91ciBieXRlcyB3aXRoIGBvZmZzZXQ9bWFya2VkT2Zmc2V0PTEsIGxpbWl0PTRgXHJcbiAgICAgKiBAZXhhbXBsZSBgMDB8MDEgMDIgMDNgIGNvbnRhaW5zIGZvdXIgYnl0ZXMgd2l0aCBgb2Zmc2V0PWxpbWl0PTEsIG1hcmtlZE9mZnNldD0tMWBcclxuICAgICAqIEBleGFtcGxlIGB8YCBjb250YWlucyB6ZXJvIGJ5dGVzIHdpdGggYG9mZnNldD1saW1pdD0wLCBtYXJrZWRPZmZzZXQ9LTFgXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9EZWJ1ZyA9IGZ1bmN0aW9uKGNvbHVtbnMpIHtcclxuICAgICAgICB2YXIgaSA9IC0xLFxyXG4gICAgICAgICAgICBrID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCxcclxuICAgICAgICAgICAgYixcclxuICAgICAgICAgICAgaGV4ID0gXCJcIixcclxuICAgICAgICAgICAgYXNjID0gXCJcIixcclxuICAgICAgICAgICAgb3V0ID0gXCJcIjtcclxuICAgICAgICB3aGlsZSAoaTxrKSB7XHJcbiAgICAgICAgICAgIGlmIChpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgYiA9IHRoaXMudmlld1tpXTtcclxuICAgICAgICAgICAgICAgIGlmIChiIDwgMHgxMCkgaGV4ICs9IFwiMFwiK2IudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGhleCArPSBiLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbHVtbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgYXNjICs9IGIgPiAzMiAmJiBiIDwgMTI3ID8gU3RyaW5nLmZyb21DaGFyQ29kZShiKSA6ICcuJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICArK2k7XHJcbiAgICAgICAgICAgIGlmIChjb2x1bW5zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSA+IDAgJiYgaSAlIDE2ID09PSAwICYmIGkgIT09IGspIHtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaGV4Lmxlbmd0aCA8IDMqMTYrMykgaGV4ICs9IFwiIFwiO1xyXG4gICAgICAgICAgICAgICAgICAgIG91dCArPSBoZXgrYXNjK1wiXFxuXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgaGV4ID0gYXNjID0gXCJcIjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaSA9PT0gdGhpcy5vZmZzZXQgJiYgaSA9PT0gdGhpcy5saW1pdClcclxuICAgICAgICAgICAgICAgIGhleCArPSBpID09PSB0aGlzLm1hcmtlZE9mZnNldCA/IFwiIVwiIDogXCJ8XCI7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGkgPT09IHRoaXMub2Zmc2V0KVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IGkgPT09IHRoaXMubWFya2VkT2Zmc2V0ID8gXCJbXCIgOiBcIjxcIjtcclxuICAgICAgICAgICAgZWxzZSBpZiAoaSA9PT0gdGhpcy5saW1pdClcclxuICAgICAgICAgICAgICAgIGhleCArPSBpID09PSB0aGlzLm1hcmtlZE9mZnNldCA/IFwiXVwiIDogXCI+XCI7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIGhleCArPSBpID09PSB0aGlzLm1hcmtlZE9mZnNldCA/IFwiJ1wiIDogKGNvbHVtbnMgfHwgKGkgIT09IDAgJiYgaSAhPT0gaykgPyBcIiBcIiA6IFwiXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29sdW1ucyAmJiBoZXggIT09IFwiIFwiKSB7XHJcbiAgICAgICAgICAgIHdoaWxlIChoZXgubGVuZ3RoIDwgMyoxNiszKVxyXG4gICAgICAgICAgICAgICAgaGV4ICs9IFwiIFwiO1xyXG4gICAgICAgICAgICBvdXQgKz0gaGV4ICsgYXNjICsgXCJcXG5cIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNvbHVtbnMgPyBvdXQgOiBoZXg7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhIGhleCBlbmNvZGVkIHN0cmluZyB3aXRoIG1hcmtlZCBvZmZzZXRzIHRvIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgRGVidWcgc3RyaW5nIHRvIGRlY29kZSAobm90IGJlIGdlbmVyYXRlZCB3aXRoIGBjb2x1bW5zID0gdHJ1ZWApXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqIEBzZWUgQnl0ZUJ1ZmZlciN0b0RlYnVnXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuZnJvbURlYnVnID0gZnVuY3Rpb24oc3RyLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgdmFyIGsgPSBzdHIubGVuZ3RoLFxyXG4gICAgICAgICAgICBiYiA9IG5ldyBCeXRlQnVmZmVyKCgoaysxKS8zKXwwLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KTtcclxuICAgICAgICB2YXIgaSA9IDAsIGogPSAwLCBjaCwgYixcclxuICAgICAgICAgICAgcnMgPSBmYWxzZSwgLy8gUmVxdWlyZSBzeW1ib2wgbmV4dFxyXG4gICAgICAgICAgICBobyA9IGZhbHNlLCBobSA9IGZhbHNlLCBobCA9IGZhbHNlLCAvLyBBbHJlYWR5IGhhcyBvZmZzZXQgKGhvKSwgbWFya2VkT2Zmc2V0IChobSksIGxpbWl0IChobCk/XHJcbiAgICAgICAgICAgIGZhaWwgPSBmYWxzZTtcclxuICAgICAgICB3aGlsZSAoaTxrKSB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAoY2ggPSBzdHIuY2hhckF0KGkrKykpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJyEnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhvIHx8IGhtIHx8IGhsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvID0gaG0gPSBobCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLm9mZnNldCA9IGJiLm1hcmtlZE9mZnNldCA9IGJiLmxpbWl0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnfCc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG8gfHwgaGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG8gPSBobCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLm9mZnNldCA9IGJiLmxpbWl0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnWyc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG8gfHwgaG0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG8gPSBobSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLm9mZnNldCA9IGJiLm1hcmtlZE9mZnNldCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgJzwnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWlsID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIub2Zmc2V0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnXSc6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGwgfHwgaG0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaGwgPSBobSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGJiLmxpbWl0ID0gYmIubWFya2VkT2Zmc2V0ID0gajtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnPic6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaGwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5saW1pdCA9IGo7XHJcbiAgICAgICAgICAgICAgICAgICAgcnMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgXCInXCI6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaG0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaG0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiYi5tYXJrZWRPZmZzZXQgPSBqO1xyXG4gICAgICAgICAgICAgICAgICAgIHJzID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICcgJzpcclxuICAgICAgICAgICAgICAgICAgICBycyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChycykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFpbCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBiID0gcGFyc2VJbnQoY2grc3RyLmNoYXJBdChpKyspLCAxNik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYU4oYikgfHwgYiA8IDAgfHwgYiA+IDI1NSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgc3RyOiBOb3QgYSBkZWJ1ZyBlbmNvZGVkIHN0cmluZ1wiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYmIudmlld1tqKytdID0gYjtcclxuICAgICAgICAgICAgICAgICAgICBycyA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGZhaWwpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogSW52YWxpZCBzeW1ib2wgYXQgXCIraSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghbm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKCFobyB8fCAhaGwpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTWlzc2luZyBvZmZzZXQgb3IgbGltaXRcIik7XHJcbiAgICAgICAgICAgIGlmIChqPGJiLmJ1ZmZlci5ieXRlTGVuZ3RoKVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBzdHI6IE5vdCBhIGRlYnVnIGVuY29kZWQgc3RyaW5nIChpcyBpdCBoZXg/KSBcIitqK1wiIDwgXCIrayk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBiYjtcclxuICAgIH07XHJcblxyXG4gICAgLy8gZW5jb2RpbmdzL2hleFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jb2RlcyB0aGlzIEJ5dGVCdWZmZXIncyBjb250ZW50cyB0byBhIGhleCBlbmNvZGVkIHN0cmluZy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gYmVnaW4gT2Zmc2V0IHRvIGJlZ2luIGF0LiBEZWZhdWx0cyB0byB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBlbmQgT2Zmc2V0IHRvIGVuZCBhdC4gRGVmYXVsdHMgdG8ge0BsaW5rIEJ5dGVCdWZmZXIjbGltaXR9LlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gSGV4IGVuY29kZWQgc3RyaW5nXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbihiZWdpbiwgZW5kKSB7XHJcbiAgICAgICAgYmVnaW4gPSB0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnID8gdGhpcy5vZmZzZXQgOiBiZWdpbjtcclxuICAgICAgICBlbmQgPSB0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJyA/IHRoaXMubGltaXQgOiBlbmQ7XHJcbiAgICAgICAgaWYgKCF0aGlzLm5vQXNzZXJ0KSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmVnaW4gIT09ICdudW1iZXInIHx8IGJlZ2luICUgMSAhPT0gMClcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGJlZ2luOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGJlZ2luID4+Pj0gMDtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kICE9PSAnbnVtYmVyJyB8fCBlbmQgJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgZW5kOiBOb3QgYW4gaW50ZWdlclwiKTtcbiAgICAgICAgICAgIGVuZCA+Pj49IDA7XG4gICAgICAgICAgICBpZiAoYmVnaW4gPCAwIHx8IGJlZ2luID4gZW5kIHx8IGVuZCA+IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpXG4gICAgICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgcmFuZ2U6IDAgPD0gXCIrYmVnaW4rXCIgPD0gXCIrZW5kK1wiIDw9IFwiK3RoaXMuYnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgICB9XHJcbiAgICAgICAgdmFyIG91dCA9IG5ldyBBcnJheShlbmQgLSBiZWdpbiksXHJcbiAgICAgICAgICAgIGI7XHJcbiAgICAgICAgd2hpbGUgKGJlZ2luIDwgZW5kKSB7XHJcbiAgICAgICAgICAgIGIgPSB0aGlzLnZpZXdbYmVnaW4rK107XHJcbiAgICAgICAgICAgIGlmIChiIDwgMHgxMClcclxuICAgICAgICAgICAgICAgIG91dC5wdXNoKFwiMFwiLCBiLnRvU3RyaW5nKDE2KSk7XHJcbiAgICAgICAgICAgIGVsc2Ugb3V0LnB1c2goYi50b1N0cmluZygxNikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0LmpvaW4oJycpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY29kZXMgYSBoZXggZW5jb2RlZCBzdHJpbmcgdG8gYSBCeXRlQnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciBTdHJpbmcgdG8gZGVjb2RlXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBsaXR0bGVFbmRpYW4gV2hldGhlciB0byB1c2UgbGl0dGxlIG9yIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci4gRGVmYXVsdHMgdG9cclxuICAgICAqICB7QGxpbmsgQnl0ZUJ1ZmZlci5ERUZBVUxUX0VORElBTn0uXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBub0Fzc2VydCBXaGV0aGVyIHRvIHNraXAgYXNzZXJ0aW9ucyBvZiBvZmZzZXRzIGFuZCB2YWx1ZXMuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9OT0FTU0VSVH0uXHJcbiAgICAgKiBAcmV0dXJucyB7IUJ5dGVCdWZmZXJ9IEJ5dGVCdWZmZXJcclxuICAgICAqIEBleHBvc2VcclxuICAgICAqL1xyXG4gICAgQnl0ZUJ1ZmZlci5mcm9tSGV4ID0gZnVuY3Rpb24oc3RyLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XHJcbiAgICAgICAgaWYgKCFub0Fzc2VydCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgICAgICBpZiAoc3RyLmxlbmd0aCAlIDIgIT09IDApXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTGVuZ3RoIG5vdCBhIG11bHRpcGxlIG9mIDJcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBrID0gc3RyLmxlbmd0aCxcclxuICAgICAgICAgICAgYmIgPSBuZXcgQnl0ZUJ1ZmZlcigoayAvIDIpIHwgMCwgbGl0dGxlRW5kaWFuKSxcclxuICAgICAgICAgICAgYjtcclxuICAgICAgICBmb3IgKHZhciBpPTAsIGo9MDsgaTxrOyBpKz0yKSB7XHJcbiAgICAgICAgICAgIGIgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkrMiksIDE2KTtcclxuICAgICAgICAgICAgaWYgKCFub0Fzc2VydClcclxuICAgICAgICAgICAgICAgIGlmICghaXNGaW5pdGUoYikgfHwgYiA8IDAgfHwgYiA+IDI1NSlcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogQ29udGFpbnMgbm9uLWhleCBjaGFyYWN0ZXJzXCIpO1xyXG4gICAgICAgICAgICBiYi52aWV3W2orK10gPSBiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBiYi5saW1pdCA9IGo7XHJcbiAgICAgICAgcmV0dXJuIGJiO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyB1dGZ4LWVtYmVkZGFibGVcclxuXHJcbiAgICAvKipcclxuICAgICAqIHV0ZngtZW1iZWRkYWJsZSAoYykgMjAxNCBEYW5pZWwgV2lydHogPGRjb2RlQGRjb2RlLmlvPlxyXG4gICAgICogUmVsZWFzZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMFxyXG4gICAgICogc2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGNvZGVJTy91dGZ4IGZvciBkZXRhaWxzXHJcbiAgICAgKi9cclxuICAgIHZhciB1dGZ4ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIHV0ZnggbmFtZXNwYWNlLlxyXG4gICAgICAgICAqIEBpbm5lclxyXG4gICAgICAgICAqIEB0eXBlIHshT2JqZWN0LjxzdHJpbmcsKj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIHV0ZnggPSB7fTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWF4aW11bSB2YWxpZCBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICogQGNvbnN0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5NQVhfQ09ERVBPSU5UID0gMHgxMEZGRkY7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEVuY29kZXMgVVRGOCBjb2RlIHBvaW50cyB0byBVVEY4IGJ5dGVzLlxyXG4gICAgICAgICAqIEBwYXJhbSB7KCFmdW5jdGlvbigpOm51bWJlcnxudWxsKSB8IG51bWJlcn0gc3JjIENvZGUgcG9pbnRzIHNvdXJjZSwgZWl0aGVyIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNvZGUgcG9pbnRcclxuICAgICAgICAgKiAgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjb2RlIHBvaW50cyBsZWZ0IG9yIGEgc2luZ2xlIG51bWVyaWMgY29kZSBwb2ludC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQnl0ZXMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggdGhlIG5leHQgYnl0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguZW5jb2RlVVRGOCA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBjcCA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3JjID09PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgICAgIGNwID0gc3JjLFxyXG4gICAgICAgICAgICAgICAgc3JjID0gZnVuY3Rpb24oKSB7IHJldHVybiBudWxsOyB9O1xyXG4gICAgICAgICAgICB3aGlsZSAoY3AgIT09IG51bGwgfHwgKGNwID0gc3JjKCkpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoY3AgPCAweDgwKVxyXG4gICAgICAgICAgICAgICAgICAgIGRzdChjcCYweDdGKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNwIDwgMHg4MDApXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjYpJjB4MUYpfDB4QzApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoY3AmMHgzRil8MHg4MCk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjcCA8IDB4MTAwMDApXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjEyKSYweDBGKXwweEUwKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+NikmMHgzRil8MHg4MCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KChjcCYweDNGKXwweDgwKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChjcD4+MTgpJjB4MDcpfDB4RjApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGNwPj4xMikmMHgzRil8MHg4MCksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoY3A+PjYpJjB4M0YpfDB4ODApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoY3AmMHgzRil8MHg4MCk7XHJcbiAgICAgICAgICAgICAgICBjcCA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEZWNvZGVzIFVURjggYnl0ZXMgdG8gVVRGOCBjb2RlIHBvaW50cy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQnl0ZXMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGJ5dGUgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZiB0aGVyZVxyXG4gICAgICAgICAqICBhcmUgbm8gbW9yZSBieXRlcyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBDb2RlIHBvaW50cyBkZXN0aW5hdGlvbiBhcyBhIGZ1bmN0aW9uIHN1Y2Nlc3NpdmVseSBjYWxsZWQgd2l0aCBlYWNoIGRlY29kZWQgY29kZSBwb2ludC5cclxuICAgICAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBhIHN0YXJ0aW5nIGJ5dGUgaXMgaW52YWxpZCBpbiBVVEY4XHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBsYXN0IHNlcXVlbmNlIGlzIHRydW5jYXRlZC4gSGFzIGFuIGFycmF5IHByb3BlcnR5IGBieXRlc2AgaG9sZGluZyB0aGVcclxuICAgICAgICAgKiAgcmVtYWluaW5nIGJ5dGVzLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguZGVjb2RlVVRGOCA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBhLCBiLCBjLCBkLCBmYWlsID0gZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICAgICAgYiA9IGIuc2xpY2UoMCwgYi5pbmRleE9mKG51bGwpKTtcclxuICAgICAgICAgICAgICAgIHZhciBlcnIgPSBFcnJvcihiLnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgZXJyLm5hbWUgPSBcIlRydW5jYXRlZEVycm9yXCI7XHJcbiAgICAgICAgICAgICAgICBlcnJbJ2J5dGVzJ10gPSBiO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB3aGlsZSAoKGEgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGlmICgoYSYweDgwKSA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICBkc3QoYSk7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICgoYSYweEUwKSA9PT0gMHhDMClcclxuICAgICAgICAgICAgICAgICAgICAoKGIgPSBzcmMoKSkgPT09IG51bGwpICYmIGZhaWwoW2EsIGJdKSxcclxuICAgICAgICAgICAgICAgICAgICBkc3QoKChhJjB4MUYpPDw2KSB8IChiJjB4M0YpKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChhJjB4RjApID09PSAweEUwKVxyXG4gICAgICAgICAgICAgICAgICAgICgoYj1zcmMoKSkgPT09IG51bGwgfHwgKGM9c3JjKCkpID09PSBudWxsKSAmJiBmYWlsKFthLCBiLCBjXSksXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KCgoYSYweDBGKTw8MTIpIHwgKChiJjB4M0YpPDw2KSB8IChjJjB4M0YpKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKChhJjB4RjgpID09PSAweEYwKVxyXG4gICAgICAgICAgICAgICAgICAgICgoYj1zcmMoKSkgPT09IG51bGwgfHwgKGM9c3JjKCkpID09PSBudWxsIHx8IChkPXNyYygpKSA9PT0gbnVsbCkgJiYgZmFpbChbYSwgYiwgYyAsZF0pLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoKGEmMHgwNyk8PDE4KSB8ICgoYiYweDNGKTw8MTIpIHwgKChjJjB4M0YpPDw2KSB8IChkJjB4M0YpKTtcclxuICAgICAgICAgICAgICAgIGVsc2UgdGhyb3cgUmFuZ2VFcnJvcihcIklsbGVnYWwgc3RhcnRpbmcgYnl0ZTogXCIrYSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb252ZXJ0cyBVVEYxNiBjaGFyYWN0ZXJzIHRvIFVURjggY29kZSBwb2ludHMuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gc3JjIENoYXJhY3RlcnMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNoYXIgY29kZSByZXNwZWN0aXZlbHlcclxuICAgICAgICAgKiAgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNoYXJhY3RlcnMgbGVmdC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQ29kZSBwb2ludHMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggZWFjaCBjb252ZXJ0ZWQgY29kZVxyXG4gICAgICAgICAqICBwb2ludC5cclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LlVURjE2dG9VVEY4ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdmFyIGMxLCBjMiA9IG51bGw7XHJcbiAgICAgICAgICAgIHdoaWxlICh0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoKGMxID0gYzIgIT09IG51bGwgPyBjMiA6IHNyYygpKSA9PT0gbnVsbClcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGlmIChjMSA+PSAweEQ4MDAgJiYgYzEgPD0gMHhERkZGKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChjMiA9IHNyYygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYzIgPj0gMHhEQzAwICYmIGMyIDw9IDB4REZGRikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0KChjMS0weEQ4MDApKjB4NDAwK2MyLTB4REMwMCsweDEwMDAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMyID0gbnVsbDsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBkc3QoYzEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChjMiAhPT0gbnVsbCkgZHN0KGMyKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb252ZXJ0cyBVVEY4IGNvZGUgcG9pbnRzIHRvIFVURjE2IGNoYXJhY3RlcnMuXHJcbiAgICAgICAgICogQHBhcmFtIHsoIWZ1bmN0aW9uKCk6bnVtYmVyfG51bGwpIHwgbnVtYmVyfSBzcmMgQ29kZSBwb2ludHMgc291cmNlLCBlaXRoZXIgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY29kZSBwb2ludFxyXG4gICAgICAgICAqICByZXNwZWN0aXZlbHkgYG51bGxgIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNvZGUgcG9pbnRzIGxlZnQgb3IgYSBzaW5nbGUgbnVtZXJpYyBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBDaGFyYWN0ZXJzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIGVhY2ggY29udmVydGVkIGNoYXIgY29kZS5cclxuICAgICAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBhIGNvZGUgcG9pbnQgaXMgb3V0IG9mIHJhbmdlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdXRmeC5VVEY4dG9VVEYxNiA9IGZ1bmN0aW9uKHNyYywgZHN0KSB7XHJcbiAgICAgICAgICAgIHZhciBjcCA9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3JjID09PSAnbnVtYmVyJylcclxuICAgICAgICAgICAgICAgIGNwID0gc3JjLCBzcmMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG51bGw7IH07XHJcbiAgICAgICAgICAgIHdoaWxlIChjcCAhPT0gbnVsbCB8fCAoY3AgPSBzcmMoKSkgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjcCA8PSAweEZGRkYpXHJcbiAgICAgICAgICAgICAgICAgICAgZHN0KGNwKTtcclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBjcCAtPSAweDEwMDAwLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoY3A+PjEwKSsweEQ4MDApLFxyXG4gICAgICAgICAgICAgICAgICAgIGRzdCgoY3AlMHg0MDApKzB4REMwMCk7XHJcbiAgICAgICAgICAgICAgICBjcCA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb252ZXJ0cyBhbmQgZW5jb2RlcyBVVEYxNiBjaGFyYWN0ZXJzIHRvIFVURjggYnl0ZXMuXHJcbiAgICAgICAgICogQHBhcmFtIHshZnVuY3Rpb24oKTpudW1iZXJ8bnVsbH0gc3JjIENoYXJhY3RlcnMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNoYXIgY29kZSByZXNwZWN0aXZlbHkgYG51bGxgXHJcbiAgICAgICAgICogIGlmIHRoZXJlIGFyZSBubyBtb3JlIGNoYXJhY3RlcnMgbGVmdC5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbihudW1iZXIpfSBkc3QgQnl0ZXMgZGVzdGluYXRpb24gYXMgYSBmdW5jdGlvbiBzdWNjZXNzaXZlbHkgY2FsbGVkIHdpdGggdGhlIG5leHQgYnl0ZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmVuY29kZVVURjE2dG9VVEY4ID0gZnVuY3Rpb24oc3JjLCBkc3QpIHtcclxuICAgICAgICAgICAgdXRmeC5VVEYxNnRvVVRGOChzcmMsIGZ1bmN0aW9uKGNwKSB7XHJcbiAgICAgICAgICAgICAgICB1dGZ4LmVuY29kZVVURjgoY3AsIGRzdCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIERlY29kZXMgYW5kIGNvbnZlcnRzIFVURjggYnl0ZXMgdG8gVVRGMTYgY2hhcmFjdGVycy5cclxuICAgICAgICAgKiBAcGFyYW0geyFmdW5jdGlvbigpOm51bWJlcnxudWxsfSBzcmMgQnl0ZXMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGJ5dGUgcmVzcGVjdGl2ZWx5IGBudWxsYCBpZiB0aGVyZVxyXG4gICAgICAgICAqICBhcmUgbm8gbW9yZSBieXRlcyBsZWZ0LlxyXG4gICAgICAgICAqIEBwYXJhbSB7IWZ1bmN0aW9uKG51bWJlcil9IGRzdCBDaGFyYWN0ZXJzIGRlc3RpbmF0aW9uIGFzIGEgZnVuY3Rpb24gc3VjY2Vzc2l2ZWx5IGNhbGxlZCB3aXRoIGVhY2ggY29udmVydGVkIGNoYXIgY29kZS5cclxuICAgICAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBhIHN0YXJ0aW5nIGJ5dGUgaXMgaW52YWxpZCBpbiBVVEY4XHJcbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBsYXN0IHNlcXVlbmNlIGlzIHRydW5jYXRlZC4gSGFzIGFuIGFycmF5IHByb3BlcnR5IGBieXRlc2AgaG9sZGluZyB0aGUgcmVtYWluaW5nIGJ5dGVzLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguZGVjb2RlVVRGOHRvVVRGMTYgPSBmdW5jdGlvbihzcmMsIGRzdCkge1xyXG4gICAgICAgICAgICB1dGZ4LmRlY29kZVVURjgoc3JjLCBmdW5jdGlvbihjcCkge1xyXG4gICAgICAgICAgICAgICAgdXRmeC5VVEY4dG9VVEYxNihjcCwgZHN0KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2FsY3VsYXRlcyB0aGUgYnl0ZSBsZW5ndGggb2YgYW4gVVRGOCBjb2RlIHBvaW50LlxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjcCBVVEY4IGNvZGUgcG9pbnRcclxuICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlIGxlbmd0aFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguY2FsY3VsYXRlQ29kZVBvaW50ID0gZnVuY3Rpb24oY3ApIHtcclxuICAgICAgICAgICAgcmV0dXJuIChjcCA8IDB4ODApID8gMSA6IChjcCA8IDB4ODAwKSA/IDIgOiAoY3AgPCAweDEwMDAwKSA/IDMgOiA0O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVVEY4IGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIFVURjggY29kZSBwb2ludHMuXHJcbiAgICAgICAgICogQHBhcmFtIHsoIWZ1bmN0aW9uKCk6bnVtYmVyfG51bGwpfSBzcmMgQ29kZSBwb2ludHMgc291cmNlIGFzIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBuZXh0IGNvZGUgcG9pbnQgcmVzcGVjdGl2ZWx5XHJcbiAgICAgICAgICogIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gbW9yZSBjb2RlIHBvaW50cyBsZWZ0LlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgVVRGOCBieXRlcyByZXF1aXJlZFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHV0ZnguY2FsY3VsYXRlVVRGOCA9IGZ1bmN0aW9uKHNyYykge1xyXG4gICAgICAgICAgICB2YXIgY3AsIGw9MDtcclxuICAgICAgICAgICAgd2hpbGUgKChjcCA9IHNyYygpKSAhPT0gbnVsbClcclxuICAgICAgICAgICAgICAgIGwgKz0gKGNwIDwgMHg4MCkgPyAxIDogKGNwIDwgMHg4MDApID8gMiA6IChjcCA8IDB4MTAwMDApID8gMyA6IDQ7XHJcbiAgICAgICAgICAgIHJldHVybiBsO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBVVEY4IGNvZGUgcG9pbnRzIHJlc3BlY3RpdmVseSBVVEY4IGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIFVURjE2IGNoYXIgY29kZXMuXHJcbiAgICAgICAgICogQHBhcmFtIHsoIWZ1bmN0aW9uKCk6bnVtYmVyfG51bGwpfSBzcmMgQ2hhcmFjdGVycyBzb3VyY2UgYXMgYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG5leHQgY2hhciBjb2RlIHJlc3BlY3RpdmVseVxyXG4gICAgICAgICAqICBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIG1vcmUgY2hhcmFjdGVycyBsZWZ0LlxyXG4gICAgICAgICAqIEByZXR1cm5zIHshQXJyYXkuPG51bWJlcj59IFRoZSBudW1iZXIgb2YgVVRGOCBjb2RlIHBvaW50cyBhdCBpbmRleCAwIGFuZCB0aGUgbnVtYmVyIG9mIFVURjggYnl0ZXMgcmVxdWlyZWQgYXQgaW5kZXggMS5cclxuICAgICAgICAgKi9cclxuICAgICAgICB1dGZ4LmNhbGN1bGF0ZVVURjE2YXNVVEY4ID0gZnVuY3Rpb24oc3JjKSB7XHJcbiAgICAgICAgICAgIHZhciBuPTAsIGw9MDtcclxuICAgICAgICAgICAgdXRmeC5VVEYxNnRvVVRGOChzcmMsIGZ1bmN0aW9uKGNwKSB7XHJcbiAgICAgICAgICAgICAgICArK247IGwgKz0gKGNwIDwgMHg4MCkgPyAxIDogKGNwIDwgMHg4MDApID8gMiA6IChjcCA8IDB4MTAwMDApID8gMyA6IDQ7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gW24sbF07XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHV0Zng7XHJcbiAgICB9KCk7XHJcblxyXG4gICAgLy8gZW5jb2RpbmdzL3V0ZjhcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY29kZXMgdGhpcyBCeXRlQnVmZmVyJ3MgY29udGVudHMgYmV0d2VlbiB7QGxpbmsgQnl0ZUJ1ZmZlciNvZmZzZXR9IGFuZCB7QGxpbmsgQnl0ZUJ1ZmZlciNsaW1pdH0gdG8gYW4gVVRGOCBlbmNvZGVkXHJcbiAgICAgKiAgc3RyaW5nLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gSGV4IGVuY29kZWQgc3RyaW5nXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgb2Zmc2V0ID4gbGltaXRgXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXJQcm90b3R5cGUudG9VVEY4ID0gZnVuY3Rpb24oYmVnaW4sIGVuZCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgYmVnaW4gPT09ICd1bmRlZmluZWQnKSBiZWdpbiA9IHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmICh0eXBlb2YgZW5kID09PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5saW1pdDtcclxuICAgICAgICBpZiAoIXRoaXMubm9Bc3NlcnQpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBiZWdpbiAhPT0gJ251bWJlcicgfHwgYmVnaW4gJSAxICE9PSAwKVxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIklsbGVnYWwgYmVnaW46IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgYmVnaW4gPj4+PSAwO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbmQgIT09ICdudW1iZXInIHx8IGVuZCAlIDEgIT09IDApXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiSWxsZWdhbCBlbmQ6IE5vdCBhbiBpbnRlZ2VyXCIpO1xuICAgICAgICAgICAgZW5kID4+Pj0gMDtcbiAgICAgICAgICAgIGlmIChiZWdpbiA8IDAgfHwgYmVnaW4gPiBlbmQgfHwgZW5kID4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICB0aHJvdyBSYW5nZUVycm9yKFwiSWxsZWdhbCByYW5nZTogMCA8PSBcIitiZWdpbitcIiA8PSBcIitlbmQrXCIgPD0gXCIrdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCk7XG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc2Q7IHRyeSB7XHJcbiAgICAgICAgICAgIHV0ZnguZGVjb2RlVVRGOHRvVVRGMTYoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYmVnaW4gPCBlbmQgPyB0aGlzLnZpZXdbYmVnaW4rK10gOiBudWxsO1xyXG4gICAgICAgICAgICB9LmJpbmQodGhpcyksIHNkID0gc3RyaW5nRGVzdGluYXRpb24oKSk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBpZiAoYmVnaW4gIT09IGVuZClcclxuICAgICAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoXCJJbGxlZ2FsIHJhbmdlOiBUcnVuY2F0ZWQgZGF0YSwgXCIrYmVnaW4rXCIgIT0gXCIrZW5kKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNkKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGVjb2RlcyBhbiBVVEY4IGVuY29kZWQgc3RyaW5nIHRvIGEgQnl0ZUJ1ZmZlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgU3RyaW5nIHRvIGRlY29kZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGl0dGxlRW5kaWFuIFdoZXRoZXIgdG8gdXNlIGxpdHRsZSBvciBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuIERlZmF1bHRzIHRvXHJcbiAgICAgKiAge0BsaW5rIEJ5dGVCdWZmZXIuREVGQVVMVF9FTkRJQU59LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbm9Bc3NlcnQgV2hldGhlciB0byBza2lwIGFzc2VydGlvbnMgb2Ygb2Zmc2V0cyBhbmQgdmFsdWVzLiBEZWZhdWx0cyB0b1xyXG4gICAgICogIHtAbGluayBCeXRlQnVmZmVyLkRFRkFVTFRfTk9BU1NFUlR9LlxyXG4gICAgICogQHJldHVybnMgeyFCeXRlQnVmZmVyfSBCeXRlQnVmZmVyXHJcbiAgICAgKiBAZXhwb3NlXHJcbiAgICAgKi9cclxuICAgIEJ5dGVCdWZmZXIuZnJvbVVURjggPSBmdW5jdGlvbihzdHIsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcclxuICAgICAgICBpZiAoIW5vQXNzZXJ0KVxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJJbGxlZ2FsIHN0cjogTm90IGEgc3RyaW5nXCIpO1xyXG4gICAgICAgIHZhciBiYiA9IG5ldyBCeXRlQnVmZmVyKHV0ZnguY2FsY3VsYXRlVVRGMTZhc1VURjgoc3RyaW5nU291cmNlKHN0ciksIHRydWUpWzFdLCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSxcclxuICAgICAgICAgICAgaSA9IDA7XHJcbiAgICAgICAgdXRmeC5lbmNvZGVVVEYxNnRvVVRGOChzdHJpbmdTb3VyY2Uoc3RyKSwgZnVuY3Rpb24oYikge1xyXG4gICAgICAgICAgICBiYi52aWV3W2krK10gPSBiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGJiLmxpbWl0ID0gaTtcclxuICAgICAgICByZXR1cm4gYmI7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBCeXRlQnVmZmVyO1xyXG59KTtcclxuIiwidmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuaW5oZXJpdHMoQ2lwaGVyQmFzZSwgVHJhbnNmb3JtKVxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIHRoaXMuX2RlY29kZXIgPSBudWxsXG4gIHRoaXMuX2VuY29kaW5nID0gbnVsbFxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGlucHV0RW5jLCBvdXRwdXRFbmMpIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGlucHV0RW5jKVxuICB9XG4gIHZhciBvdXREYXRhID0gdGhpcy5fdXBkYXRlKGRhdGEpXG4gIGlmICh0aGlzLmhhc2hNb2RlKSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuICByZXR1cm4gb3V0RGF0YVxufVxuXG5DaXBoZXJCYXNlLnByb3RvdHlwZS5zZXRBdXRvUGFkZGluZyA9IGZ1bmN0aW9uICgpIHt9XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9maW5hbCgpKVxuICB9IGNhdGNoIChlKSB7XG4gICAgZXJyID0gZVxuICB9IGZpbmFsbHkge1xuICAgIGRvbmUoZXJyKVxuICB9XG59XG5DaXBoZXJCYXNlLnByb3RvdHlwZS5fZmluYWxPckRpZ2VzdCA9IGZ1bmN0aW9uIChvdXRwdXRFbmMpIHtcbiAgdmFyIG91dERhdGEgPSB0aGlzLl9maW5hbCgpIHx8IG5ldyBCdWZmZXIoJycpXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW4pIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG4gIGlmICh0aGlzLl9lbmNvZGluZyAhPT0gZW5jKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYW5cXCd0IHN3aXRjaCBlbmNvZGluZ3MnKVxuICB9XG4gIHZhciBvdXQgPSB0aGlzLl9kZWNvZGVyLndyaXRlKHZhbHVlKVxuICBpZiAoZmluKSB7XG4gICAgb3V0ICs9IHRoaXMuX2RlY29kZXIuZW5kKClcbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBNRDUgPSByZXF1aXJlKCdtZDUuanMnKVxudmFyIFJJUEVNRDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG52YXIgc2hhID0gcmVxdWlyZSgnc2hhLmpzJylcbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG5mdW5jdGlvbiBIYXNoIChoYXNoKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcblxuICB0aGlzLl9oYXNoID0gaGFzaFxufVxuXG5pbmhlcml0cyhIYXNoLCBCYXNlKVxuXG5IYXNoLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSGFzaC5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5faGFzaC5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhhc2ggKGFsZykge1xuICBhbGcgPSBhbGcudG9Mb3dlckNhc2UoKVxuICBpZiAoYWxnID09PSAnbWQ1JykgcmV0dXJuIG5ldyBNRDUoKVxuICBpZiAoYWxnID09PSAncm1kMTYwJyB8fCBhbGcgPT09ICdyaXBlbWQxNjAnKSByZXR1cm4gbmV3IFJJUEVNRDE2MCgpXG5cbiAgcmV0dXJuIG5ldyBIYXNoKHNoYShhbGcpKVxufVxuIiwidmFyIE1ENSA9IHJlcXVpcmUoJ21kNS5qcycpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICByZXR1cm4gbmV3IE1ENSgpLnVwZGF0ZShidWZmZXIpLmRpZ2VzdCgpXG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBMZWdhY3kgPSByZXF1aXJlKCcuL2xlZ2FjeScpXG52YXIgQmFzZSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG52YXIgUklQRU1EMTYwID0gcmVxdWlyZSgncmlwZW1kMTYwJylcblxudmFyIHNoYSA9IHJlcXVpcmUoJ3NoYS5qcycpXG5cbnZhciBaRVJPUyA9IEJ1ZmZlci5hbGxvYygxMjgpXG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdmFyIGJsb2Nrc2l6ZSA9IChhbGcgPT09ICdzaGE1MTInIHx8IGFsZyA9PT0gJ3NoYTM4NCcpID8gMTI4IDogNjRcblxuICB0aGlzLl9hbGcgPSBhbGdcbiAgdGhpcy5fa2V5ID0ga2V5XG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAgdmFyIGhhc2ggPSBhbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKGFsZylcbiAgICBrZXkgPSBoYXNoLnVwZGF0ZShrZXkpLmRpZ2VzdCgpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuICB2YXIgb3BhZCA9IHRoaXMuX29wYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cbiAgdGhpcy5faGFzaCA9IGFsZyA9PT0gJ3JtZDE2MCcgPyBuZXcgUklQRU1EMTYwKCkgOiBzaGEoYWxnKVxuICB0aGlzLl9oYXNoLnVwZGF0ZShpcGFkKVxufVxuXG5pbmhlcml0cyhIbWFjLCBCYXNlKVxuXG5IbWFjLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSG1hYy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcbiAgdmFyIGhhc2ggPSB0aGlzLl9hbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKHRoaXMuX2FsZylcbiAgcmV0dXJuIGhhc2gudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMgKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHtcbiAgICByZXR1cm4gbmV3IEhtYWMoJ3JtZDE2MCcsIGtleSlcbiAgfVxuICBpZiAoYWxnID09PSAnbWQ1Jykge1xuICAgIHJldHVybiBuZXcgTGVnYWN5KG1kNSwga2V5KVxuICB9XG4gIHJldHVybiBuZXcgSG1hYyhhbGcsIGtleSlcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxudmFyIGJsb2Nrc2l6ZSA9IDY0XG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdGhpcy5fYWxnID0gYWxnXG4gIHRoaXMuX2tleSA9IGtleVxuXG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gYWxnKGtleSlcbiAgfSBlbHNlIGlmIChrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBaRVJPU10sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gdGhpcy5faXBhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG4gIHZhciBvcGFkID0gdGhpcy5fb3BhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBbaXBhZF1cbn1cblxuaW5oZXJpdHMoSG1hYywgQmFzZSlcblxuSG1hYy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gucHVzaChkYXRhKVxufVxuXG5IbWFjLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoID0gdGhpcy5fYWxnKEJ1ZmZlci5jb25jYXQodGhpcy5faGFzaCkpXG4gIHJldHVybiB0aGlzLl9hbGcoQnVmZmVyLmNvbmNhdChbdGhpcy5fb3BhZCwgaF0pKVxufVxubW9kdWxlLmV4cG9ydHMgPSBIbWFjXG4iLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSwgcmVxdWlyZShcIi4vZW5jLWJhc2U2NFwiKSwgcmVxdWlyZShcIi4vbWQ1XCIpLCByZXF1aXJlKFwiLi9ldnBrZGZcIiksIHJlcXVpcmUoXCIuL2NpcGhlci1jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIiwgXCIuL2VuYy1iYXNlNjRcIiwgXCIuL21kNVwiLCBcIi4vZXZwa2RmXCIsIFwiLi9jaXBoZXItY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXI7XG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvO1xuXG5cdCAgICAvLyBMb29rdXAgdGFibGVzXG5cdCAgICB2YXIgU0JPWCA9IFtdO1xuXHQgICAgdmFyIElOVl9TQk9YID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8wID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8xID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8yID0gW107XG5cdCAgICB2YXIgU1VCX01JWF8zID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMCA9IFtdO1xuXHQgICAgdmFyIElOVl9TVUJfTUlYXzEgPSBbXTtcblx0ICAgIHZhciBJTlZfU1VCX01JWF8yID0gW107XG5cdCAgICB2YXIgSU5WX1NVQl9NSVhfMyA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIGxvb2t1cCB0YWJsZXNcblx0ICAgIChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgLy8gQ29tcHV0ZSBkb3VibGUgdGFibGVcblx0ICAgICAgICB2YXIgZCA9IFtdO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0ICAgICAgICAgICAgaWYgKGkgPCAxMjgpIHtcblx0ICAgICAgICAgICAgICAgIGRbaV0gPSBpIDw8IDE7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBkW2ldID0gKGkgPDwgMSkgXiAweDExYjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIFdhbGsgR0YoMl44KVxuXHQgICAgICAgIHZhciB4ID0gMDtcblx0ICAgICAgICB2YXIgeGkgPSAwO1xuXHQgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBzYm94XG5cdCAgICAgICAgICAgIHZhciBzeCA9IHhpIF4gKHhpIDw8IDEpIF4gKHhpIDw8IDIpIF4gKHhpIDw8IDMpIF4gKHhpIDw8IDQpO1xuXHQgICAgICAgICAgICBzeCA9IChzeCA+Pj4gOCkgXiAoc3ggJiAweGZmKSBeIDB4NjM7XG5cdCAgICAgICAgICAgIFNCT1hbeF0gPSBzeDtcblx0ICAgICAgICAgICAgSU5WX1NCT1hbc3hdID0geDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIG11bHRpcGxpY2F0aW9uXG5cdCAgICAgICAgICAgIHZhciB4MiA9IGRbeF07XG5cdCAgICAgICAgICAgIHZhciB4NCA9IGRbeDJdO1xuXHQgICAgICAgICAgICB2YXIgeDggPSBkW3g0XTtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIHN1YiBieXRlcywgbWl4IGNvbHVtbnMgdGFibGVzXG5cdCAgICAgICAgICAgIHZhciB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKTtcblx0ICAgICAgICAgICAgU1VCX01JWF8wW3hdID0gKHQgPDwgMjQpIHwgKHQgPj4+IDgpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzFbeF0gPSAodCA8PCAxNikgfCAodCA+Pj4gMTYpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzJbeF0gPSAodCA8PCA4KSAgfCAodCA+Pj4gMjQpO1xuXHQgICAgICAgICAgICBTVUJfTUlYXzNbeF0gPSB0O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgaW52IHN1YiBieXRlcywgaW52IG1peCBjb2x1bW5zIHRhYmxlc1xuXHQgICAgICAgICAgICB2YXIgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMFtzeF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOCk7XG5cdCAgICAgICAgICAgIElOVl9TVUJfTUlYXzFbc3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KTtcblx0ICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltzeF0gPSAodCA8PCA4KSAgfCAodCA+Pj4gMjQpO1xuXHQgICAgICAgICAgICBJTlZfU1VCX01JWF8zW3N4XSA9IHQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBuZXh0IGNvdW50ZXJcblx0ICAgICAgICAgICAgaWYgKCF4KSB7XG5cdCAgICAgICAgICAgICAgICB4ID0geGkgPSAxO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgeCA9IHgyIF4gZFtkW2RbeDggXiB4Ml1dXTtcblx0ICAgICAgICAgICAgICAgIHhpIF49IGRbZFt4aV1dO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXHQgICAgfSgpKTtcblxuXHQgICAgLy8gUHJlY29tcHV0ZWQgUmNvbiBsb29rdXBcblx0ICAgIHZhciBSQ09OID0gWzB4MDAsIDB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzZdO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICovXG5cdCAgICB2YXIgQUVTID0gQ19hbGdvLkFFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2tpcCByZXNldCBvZiBuUm91bmRzIGhhcyBiZWVuIHNldCBiZWZvcmUgYW5kIGtleSBkaWQgbm90IGNoYW5nZVxuXHQgICAgICAgICAgICBpZiAodGhpcy5fblJvdW5kcyAmJiB0aGlzLl9rZXlQcmlvclJlc2V0ID09PSB0aGlzLl9rZXkpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIga2V5ID0gdGhpcy5fa2V5UHJpb3JSZXNldCA9IHRoaXMuX2tleTtcblx0ICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGtleS5zaWdCeXRlcyAvIDQ7XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0ZSBudW1iZXIgb2Ygcm91bmRzXG5cdCAgICAgICAgICAgIHZhciBuUm91bmRzID0gdGhpcy5fblJvdW5kcyA9IGtleVNpemUgKyA2O1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIGtleSBzY2hlZHVsZSByb3dzXG5cdCAgICAgICAgICAgIHZhciBrc1Jvd3MgPSAoblJvdW5kcyArIDEpICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGtleSBzY2hlZHVsZVxuXHQgICAgICAgICAgICB2YXIga2V5U2NoZWR1bGUgPSB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBrc1JvdyA9IDA7IGtzUm93IDwga3NSb3dzOyBrc1JvdysrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoa3NSb3cgPCBrZXlTaXplKSB7XG5cdCAgICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5V29yZHNba3NSb3ddO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93IC0gMV07XG5cblx0ICAgICAgICAgICAgICAgICAgICBpZiAoIShrc1JvdyAlIGtleVNpemUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJvdCB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAodCA8PCA4KSB8ICh0ID4+PiAyNCk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmRcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdCA9IChTQk9YW3QgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsodCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3QgJiAweGZmXTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAvLyBNaXggUmNvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICB0IF49IFJDT05bKGtzUm93IC8ga2V5U2l6ZSkgfCAwXSA8PCAyNDtcblx0ICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PSA0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1YiB3b3JkXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAoU0JPWFt0ID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFt0ICYgMHhmZl07XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQ7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIGludiBrZXkgc2NoZWR1bGVcblx0ICAgICAgICAgICAgdmFyIGludktleVNjaGVkdWxlID0gdGhpcy5faW52S2V5U2NoZWR1bGUgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaW52S3NSb3cgPSAwOyBpbnZLc1JvdyA8IGtzUm93czsgaW52S3NSb3crKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGtzUm93ID0ga3NSb3dzIC0gaW52S3NSb3c7XG5cblx0ICAgICAgICAgICAgICAgIGlmIChpbnZLc1JvdyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93XTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrc1JvdyAtIDRdO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBpZiAoaW52S3NSb3cgPCA0IHx8IGtzUm93IDw9IDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSB0O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSBJTlZfU1VCX01JWF8wW1NCT1hbdCA+Pj4gMjRdXSBeIElOVl9TVUJfTUlYXzFbU0JPWFsodCA+Pj4gMTYpICYgMHhmZl1dIF5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlZfU1VCX01JWF8yW1NCT1hbKHQgPj4+IDgpICYgMHhmZl1dIF4gSU5WX1NVQl9NSVhfM1tTQk9YW3QgJiAweGZmXV07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgZW5jcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX2tleVNjaGVkdWxlLCBTVUJfTUlYXzAsIFNVQl9NSVhfMSwgU1VCX01JWF8yLCBTVUJfTUlYXzMsIFNCT1gpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBkZWNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU3dhcCAybmQgYW5kIDR0aCByb3dzXG5cdCAgICAgICAgICAgIHZhciB0ID0gTVtvZmZzZXQgKyAxXTtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IE1bb2Zmc2V0ICsgM107XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0O1xuXG5cdCAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX2ludktleVNjaGVkdWxlLCBJTlZfU1VCX01JWF8wLCBJTlZfU1VCX01JWF8xLCBJTlZfU1VCX01JWF8yLCBJTlZfU1VCX01JWF8zLCBJTlZfU0JPWCk7XG5cblx0ICAgICAgICAgICAgLy8gSW52IHN3YXAgMm5kIGFuZCA0dGggcm93c1xuXHQgICAgICAgICAgICB2YXIgdCA9IE1bb2Zmc2V0ICsgMV07XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvQ3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCwga2V5U2NoZWR1bGUsIFNVQl9NSVhfMCwgU1VCX01JWF8xLCBTVUJfTUlYXzIsIFNVQl9NSVhfMywgU0JPWCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgblJvdW5kcyA9IHRoaXMuX25Sb3VuZHM7XG5cblx0ICAgICAgICAgICAgLy8gR2V0IGlucHV0LCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgIHZhciBzMCA9IE1bb2Zmc2V0XSAgICAgXiBrZXlTY2hlZHVsZVswXTtcblx0ICAgICAgICAgICAgdmFyIHMxID0gTVtvZmZzZXQgKyAxXSBeIGtleVNjaGVkdWxlWzFdO1xuXHQgICAgICAgICAgICB2YXIgczIgPSBNW29mZnNldCArIDJdIF4ga2V5U2NoZWR1bGVbMl07XG5cdCAgICAgICAgICAgIHZhciBzMyA9IE1bb2Zmc2V0ICsgM10gXiBrZXlTY2hlZHVsZVszXTtcblxuXHQgICAgICAgICAgICAvLyBLZXkgc2NoZWR1bGUgcm93IGNvdW50ZXJcblx0ICAgICAgICAgICAgdmFyIGtzUm93ID0gNDtcblxuXHQgICAgICAgICAgICAvLyBSb3VuZHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IG5Sb3VuZHM7IHJvdW5kKyspIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNoaWZ0IHJvd3MsIHN1YiBieXRlcywgbWl4IGNvbHVtbnMsIGFkZCByb3VuZCBrZXlcblx0ICAgICAgICAgICAgICAgIHZhciB0MCA9IFNVQl9NSVhfMFtzMCA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMSA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MzICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MSA9IFNVQl9NSVhfMFtzMSA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMiA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMzID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MwICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MiA9IFNVQl9NSVhfMFtzMiA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMwID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MxICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgICAgIHZhciB0MyA9IFNVQl9NSVhfMFtzMyA+Pj4gMjRdIF4gU1VCX01JWF8xWyhzMCA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYXzJbKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWF8zW3MyICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblxuXHQgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHN0YXRlXG5cdCAgICAgICAgICAgICAgICBzMCA9IHQwO1xuXHQgICAgICAgICAgICAgICAgczEgPSB0MTtcblx0ICAgICAgICAgICAgICAgIHMyID0gdDI7XG5cdCAgICAgICAgICAgICAgICBzMyA9IHQzO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBhZGQgcm91bmQga2V5XG5cdCAgICAgICAgICAgIHZhciB0MCA9ICgoU0JPWFtzMCA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMSA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMyID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMyAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXHQgICAgICAgICAgICB2YXIgdDEgPSAoKFNCT1hbczEgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczIgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMyA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczAgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTtcblx0ICAgICAgICAgICAgdmFyIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107XG5cdCAgICAgICAgICAgIHZhciB0MyA9ICgoU0JPWFtzMyA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMCA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMxID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMiAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBvdXRwdXRcblx0ICAgICAgICAgICAgTVtvZmZzZXRdICAgICA9IHQwO1xuXHQgICAgICAgICAgICBNW29mZnNldCArIDFdID0gdDE7XG5cdCAgICAgICAgICAgIE1bb2Zmc2V0ICsgMl0gPSB0Mjtcblx0ICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBrZXlTaXplOiAyNTYvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLkFFUy5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTtcblx0ICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkFFUy5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAqL1xuXHQgICAgQy5BRVMgPSBCbG9ja0NpcGhlci5fY3JlYXRlSGVscGVyKEFFUyk7XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuQUVTO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL2V2cGtkZlwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCIsIFwiLi9ldnBrZGZcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdC8qKlxuXHQgKiBDaXBoZXIgY29yZSBjb21wb25lbnRzLlxuXHQgKi9cblx0Q3J5cHRvSlMubGliLkNpcGhlciB8fCAoZnVuY3Rpb24gKHVuZGVmaW5lZCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBDX2xpYi5CdWZmZXJlZEJsb2NrQWxnb3JpdGhtO1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmM7XG5cdCAgICB2YXIgVXRmOCA9IENfZW5jLlV0Zjg7XG5cdCAgICB2YXIgQmFzZTY0ID0gQ19lbmMuQmFzZTY0O1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblx0ICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2UgY2lwaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoaXMgY2lwaGVyJ3Mga2V5IHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGl2U2l6ZSBUaGlzIGNpcGhlcidzIElWIHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKVxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9FTkNfWEZPUk1fTU9ERSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyBlbmNyeXB0aW9uIG1vZGUuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX0RFQ19YRk9STV9NT0RFIEEgY29uc3RhbnQgcmVwcmVzZW50aW5nIGRlY3J5cHRpb24gbW9kZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENpcGhlciA9IENfbGliLkNpcGhlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gaXYgVGhlIElWIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBlbmNyeXB0aW9uIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVFbmNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVFbmNyeXB0b3I6IGZ1bmN0aW9uIChrZXksIGNmZykge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fRU5DX1hGT1JNX01PREUsIGtleSwgY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBkZWNyeXB0aW9uIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVEZWNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVEZWNyeXB0b3I6IGZ1bmN0aW9uIChrZXksIGNmZykge1xuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fREVDX1hGT1JNX01PREUsIGtleSwgY2ZnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGNpcGhlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4Zm9ybU1vZGUgRWl0aGVyIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gdHJhbnNvcm1hdGlvbiBtb2RlIGNvbnN0YW50LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVyID0gQ3J5cHRvSlMuYWxnby5BRVMuY3JlYXRlKENyeXB0b0pTLmFsZ28uQUVTLl9FTkNfWEZPUk1fTU9ERSwga2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoeGZvcm1Nb2RlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTdG9yZSB0cmFuc2Zvcm0gbW9kZSBhbmQga2V5XG5cdCAgICAgICAgICAgIHRoaXMuX3hmb3JtTW9kZSA9IHhmb3JtTW9kZTtcblx0ICAgICAgICAgICAgdGhpcy5fa2V5ID0ga2V5O1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIGNpcGhlciB0byBpdHMgaW5pdGlhbCBzdGF0ZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgY2lwaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gUmVzZXQgZGF0YSBidWZmZXJcblx0ICAgICAgICAgICAgQnVmZmVyZWRCbG9ja0FsZ29yaXRobS5yZXNldC5jYWxsKHRoaXMpO1xuXG5cdCAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljXG5cdCAgICAgICAgICAgIHRoaXMuX2RvUmVzZXQoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQWRkcyBkYXRhIHRvIGJlIGVuY3J5cHRlZCBvciBkZWNyeXB0ZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGRhdGFVcGRhdGUgVGhlIGRhdGEgdG8gZW5jcnlwdCBvciBkZWNyeXB0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGF0YSBhZnRlciBwcm9jZXNzaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLnByb2Nlc3MoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5wcm9jZXNzKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcHJvY2VzczogZnVuY3Rpb24gKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTtcblxuXHQgICAgICAgICAgICAvLyBQcm9jZXNzIGF2YWlsYWJsZSBibG9ja3Ncblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3MoKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gcHJvY2Vzcy5cblx0ICAgICAgICAgKiBOb3RlIHRoYXQgdGhlIGZpbmFsaXplIG9wZXJhdGlvbiBpcyBlZmZlY3RpdmVseSBhIGRlc3RydWN0aXZlLCByZWFkLW9uY2Ugb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhVXBkYXRlIFRoZSBmaW5hbCBkYXRhIHRvIGVuY3J5cHQgb3IgZGVjcnlwdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgZmluYWwgcHJvY2Vzc2luZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgZW5jcnlwdGVkID0gY2lwaGVyLmZpbmFsaXplKCdkYXRhJyk7XG5cdCAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gRmluYWwgZGF0YSB1cGRhdGVcblx0ICAgICAgICAgICAgaWYgKGRhdGFVcGRhdGUpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljXG5cdCAgICAgICAgICAgIHZhciBmaW5hbFByb2Nlc3NlZERhdGEgPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZpbmFsUHJvY2Vzc2VkRGF0YTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAga2V5U2l6ZTogMTI4LzMyLFxuXG5cdCAgICAgICAgaXZTaXplOiAxMjgvMzIsXG5cblx0ICAgICAgICBfRU5DX1hGT1JNX01PREU6IDEsXG5cblx0ICAgICAgICBfREVDX1hGT1JNX01PREU6IDIsXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHNob3J0Y3V0IGZ1bmN0aW9ucyB0byBhIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgdG8gY3JlYXRlIGEgaGVscGVyIGZvci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gQW4gb2JqZWN0IHdpdGggZW5jcnlwdCBhbmQgZGVjcnlwdCBzaG9ydGN1dCBmdW5jdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBBRVMgPSBDcnlwdG9KUy5saWIuQ2lwaGVyLl9jcmVhdGVIZWxwZXIoQ3J5cHRvSlMuYWxnby5BRVMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9jcmVhdGVIZWxwZXI6IChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIGZ1bmN0aW9uIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkge1xuXHQgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBrZXkgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gUGFzc3dvcmRCYXNlZENpcGhlcjtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNlcmlhbGl6YWJsZUNpcGhlcjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoY2lwaGVyKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0Q2lwaGVyU3RyYXRlZ3koa2V5KS5lbmNyeXB0KGNpcGhlciwgbWVzc2FnZSwga2V5LCBjZmcpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgICAgICAgICBkZWNyeXB0OiBmdW5jdGlvbiAoY2lwaGVydGV4dCwga2V5LCBjZmcpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGVjdENpcGhlclN0cmF0ZWd5KGtleSkuZGVjcnlwdChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0oKSlcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEFic3RyYWN0IGJhc2Ugc3RyZWFtIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxICgzMiBiaXRzKVxuXHQgICAgICovXG5cdCAgICB2YXIgU3RyZWFtQ2lwaGVyID0gQ19saWIuU3RyZWFtQ2lwaGVyID0gQ2lwaGVyLmV4dGVuZCh7XG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGZpbmFsUHJvY2Vzc2VkQmxvY2tzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBibG9ja1NpemU6IDFcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIE1vZGUgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19tb2RlID0gQy5tb2RlID0ge307XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYmFzZSBibG9jayBjaXBoZXIgbW9kZSB0ZW1wbGF0ZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyTW9kZSA9IENfbGliLkJsb2NrQ2lwaGVyTW9kZSA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIHRoaXMgbW9kZSBmb3IgZW5jcnlwdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLmNyZWF0ZUVuY3J5cHRvcihjaXBoZXIsIGl2LndvcmRzKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjcmVhdGVFbmNyeXB0b3I6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzLkVuY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdik7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENyZWF0ZXMgdGhpcyBtb2RlIGZvciBkZWNyeXB0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuY3JlYXRlRGVjcnlwdG9yKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuRGVjcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG1vZGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIG1vZGUgPSBDcnlwdG9KUy5tb2RlLkNCQy5FbmNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYud29yZHMpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2NpcGhlciA9IGNpcGhlcjtcblx0ICAgICAgICAgICAgdGhpcy5faXYgPSBpdjtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENCQyA9IENfbW9kZS5DQkMgPSAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEFic3RyYWN0IGJhc2UgQ0JDIG1vZGUuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdmFyIENCQyA9IEJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENCQyBlbmNyeXB0b3IuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgQ0JDLkVuY3J5cHRvciA9IENCQy5leHRlbmQoe1xuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogUHJvY2Vzc2VzIHRoZSBkYXRhIGJsb2NrIGF0IG9mZnNldC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi5cblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgb2Zmc2V0IHdoZXJlIHRoZSBibG9jayBzdGFydHMuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFhPUiBhbmQgZW5jcnlwdFxuXHQgICAgICAgICAgICAgICAgeG9yQmxvY2suY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpO1xuXHQgICAgICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB3b3Jkcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJsb2NrU2l6ZSk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENCQyBkZWNyeXB0b3IuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgQ0JDLkRlY3J5cHRvciA9IENCQy5leHRlbmQoe1xuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogUHJvY2Vzc2VzIHRoZSBkYXRhIGJsb2NrIGF0IG9mZnNldC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi5cblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBUaGUgb2Zmc2V0IHdoZXJlIHRoZSBibG9jayBzdGFydHMuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9ja1xuXHQgICAgICAgICAgICAgICAgdmFyIHRoaXNCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gRGVjcnlwdCBhbmQgWE9SXG5cdCAgICAgICAgICAgICAgICBjaXBoZXIuZGVjcnlwdEJsb2NrKHdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgeG9yQmxvY2suY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBUaGlzIGJsb2NrIGJlY29tZXMgdGhlIHByZXZpb3VzIGJsb2NrXG5cdCAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB0aGlzQmxvY2s7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9KTtcblxuXHQgICAgICAgIGZ1bmN0aW9uIHhvckJsb2NrKHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjtcblxuXHQgICAgICAgICAgICAvLyBDaG9vc2UgbWl4aW5nIGJsb2NrXG5cdCAgICAgICAgICAgIGlmIChpdikge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaXY7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3Ncblx0ICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gdGhpcy5fcHJldkJsb2NrO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gWE9SIGJsb2Nrc1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBibG9ja1tpXTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBDQkM7XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBhZGRpbmcgbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19wYWQgPSBDLnBhZCA9IHt9O1xuXG5cdCAgICAvKipcblx0ICAgICAqIFBLQ1MgIzUvNyBwYWRkaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGtjczcgPSBDX3BhZC5Qa2NzNyA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBQYWRzIGRhdGEgdXNpbmcgdGhlIGFsZ29yaXRobSBkZWZpbmVkIGluIFBLQ1MgIzUvNy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHBhZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gYmxvY2tTaXplIFRoZSBtdWx0aXBsZSB0aGF0IHRoZSBkYXRhIHNob3VsZCBiZSBwYWRkZWQgdG8uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy5wYWQod29yZEFycmF5LCA0KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzXG5cdCAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gYmxvY2tTaXplQnl0ZXMgLSBkYXRhLnNpZ0J5dGVzICUgYmxvY2tTaXplQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmcgd29yZFxuXHQgICAgICAgICAgICB2YXIgcGFkZGluZ1dvcmQgPSAoblBhZGRpbmdCeXRlcyA8PCAyNCkgfCAoblBhZGRpbmdCeXRlcyA8PCAxNikgfCAoblBhZGRpbmdCeXRlcyA8PCA4KSB8IG5QYWRkaW5nQnl0ZXM7XG5cblx0ICAgICAgICAgICAgLy8gQ3JlYXRlIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdXb3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5QYWRkaW5nQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgcGFkZGluZ1dvcmRzLnB1c2gocGFkZGluZ1dvcmQpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nID0gV29yZEFycmF5LmNyZWF0ZShwYWRkaW5nV29yZHMsIG5QYWRkaW5nQnl0ZXMpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nXG5cdCAgICAgICAgICAgIGRhdGEuY29uY2F0KHBhZGRpbmcpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVbnBhZHMgZGF0YSB0aGF0IGhhZCBiZWVuIHBhZGRlZCB1c2luZyB0aGUgYWxnb3JpdGhtIGRlZmluZWQgaW4gUEtDUyAjNS83LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGRhdGEgVGhlIGRhdGEgdG8gdW5wYWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIENyeXB0b0pTLnBhZC5Qa2NzNy51bnBhZCh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkge1xuXHQgICAgICAgICAgICAvLyBHZXQgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgZnJvbSBsYXN0IGJ5dGVcblx0ICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBkYXRhLndvcmRzWyhkYXRhLnNpZ0J5dGVzIC0gMSkgPj4+IDJdICYgMHhmZjtcblxuXHQgICAgICAgICAgICAvLyBSZW1vdmUgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzIC09IG5QYWRkaW5nQnl0ZXM7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBYnN0cmFjdCBiYXNlIGJsb2NrIGNpcGhlciB0ZW1wbGF0ZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiA0ICgxMjggYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEJsb2NrQ2lwaGVyID0gQ19saWIuQmxvY2tDaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdG8gdXNlLiBEZWZhdWx0OiBDQkNcblx0ICAgICAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc3RyYXRlZ3kgdG8gdXNlLiBEZWZhdWx0OiBQa2NzN1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBtb2RlOiBDQkMsXG5cdCAgICAgICAgICAgIHBhZGRpbmc6IFBrY3M3XG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBSZXNldCBjaXBoZXJcblx0ICAgICAgICAgICAgQ2lwaGVyLnJlc2V0LmNhbGwodGhpcyk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZztcblx0ICAgICAgICAgICAgdmFyIGl2ID0gY2ZnLml2O1xuXHQgICAgICAgICAgICB2YXIgbW9kZSA9IGNmZy5tb2RlO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGJsb2NrIG1vZGVcblx0ICAgICAgICAgICAgaWYgKHRoaXMuX3hmb3JtTW9kZSA9PSB0aGlzLl9FTkNfWEZPUk1fTU9ERSkge1xuXHQgICAgICAgICAgICAgICAgdmFyIG1vZGVDcmVhdG9yID0gbW9kZS5jcmVhdGVFbmNyeXB0b3I7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3IgPSBtb2RlLmNyZWF0ZURlY3J5cHRvcjtcblx0ICAgICAgICAgICAgICAgIC8vIEtlZXAgYXQgbGVhc3Qgb25lIGJsb2NrIGluIHRoZSBidWZmZXIgZm9yIHVucGFkZGluZ1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbWluQnVmZmVyU2l6ZSA9IDE7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBpZiAodGhpcy5fbW9kZSAmJiB0aGlzLl9tb2RlLl9fY3JlYXRvciA9PSBtb2RlQ3JlYXRvcikge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fbW9kZS5pbml0KHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUgPSBtb2RlQ3JlYXRvci5jYWxsKG1vZGUsIHRoaXMsIGl2ICYmIGl2LndvcmRzKTtcblx0ICAgICAgICAgICAgICAgIHRoaXMuX21vZGUuX19jcmVhdG9yID0gbW9kZUNyZWF0b3I7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkge1xuXHQgICAgICAgICAgICB0aGlzLl9tb2RlLnByb2Nlc3NCbG9jayh3b3Jkcywgb2Zmc2V0KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmcgPSB0aGlzLmNmZy5wYWRkaW5nO1xuXG5cdCAgICAgICAgICAgIC8vIEZpbmFsaXplXG5cdCAgICAgICAgICAgIGlmICh0aGlzLl94Zm9ybU1vZGUgPT0gdGhpcy5fRU5DX1hGT1JNX01PREUpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnBhZCh0aGlzLl9kYXRhLCB0aGlzLmJsb2NrU2l6ZSk7XG5cblx0ICAgICAgICAgICAgICAgIC8vIFByb2Nlc3MgZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgICAgICB2YXIgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKCEhJ2ZsdXNoJyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqLyB7XG5cdCAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2VzcyghISdmbHVzaCcpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBVbnBhZCBkYXRhXG5cdCAgICAgICAgICAgICAgICBwYWRkaW5nLnVucGFkKGZpbmFsUHJvY2Vzc2VkQmxvY2tzKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBmaW5hbFByb2Nlc3NlZEJsb2Nrcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgYmxvY2tTaXplOiAxMjgvMzJcblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEEgY29sbGVjdGlvbiBvZiBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAqXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gY2lwaGVydGV4dCBUaGUgcmF3IGNpcGhlcnRleHQuXG5cdCAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkgdG8gdGhpcyBjaXBoZXJ0ZXh0LlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB1c2VkIGluIHRoZSBjaXBoZXJpbmcgb3BlcmF0aW9uLlxuXHQgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IHNhbHQgVGhlIHNhbHQgdXNlZCB3aXRoIGEga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge0NpcGhlcn0gYWxnb3JpdGhtIFRoZSBjaXBoZXIgYWxnb3JpdGhtLlxuXHQgICAgICogQHByb3BlcnR5IHtNb2RlfSBtb2RlIFRoZSBibG9jayBtb2RlIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge1BhZGRpbmd9IHBhZGRpbmcgVGhlIHBhZGRpbmcgc2NoZW1lIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBibG9jayBzaXplIG9mIHRoZSBjaXBoZXIuXG5cdCAgICAgKiBAcHJvcGVydHkge0Zvcm1hdH0gZm9ybWF0dGVyIFRoZSBkZWZhdWx0IGZvcm1hdHRpbmcgc3RyYXRlZ3kgdG8gY29udmVydCB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ2lwaGVyUGFyYW1zID0gQ19saWIuQ2lwaGVyUGFyYW1zID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaXBoZXJQYXJhbXMgQW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBwb3NzaWJsZSBjaXBoZXIgcGFyYW1ldGVycy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlclBhcmFtcyA9IENyeXB0b0pTLmxpYi5DaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgKiAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBrZXk6IGtleVdvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIGl2OiBpdldvcmRBcnJheSxcblx0ICAgICAgICAgKiAgICAgICAgIHNhbHQ6IHNhbHRXb3JkQXJyYXksXG5cdCAgICAgICAgICogICAgICAgICBhbGdvcml0aG06IENyeXB0b0pTLmFsZ28uQUVTLFxuXHQgICAgICAgICAqICAgICAgICAgbW9kZTogQ3J5cHRvSlMubW9kZS5DQkMsXG5cdCAgICAgICAgICogICAgICAgICBwYWRkaW5nOiBDcnlwdG9KUy5wYWQuUEtDUzcsXG5cdCAgICAgICAgICogICAgICAgICBibG9ja1NpemU6IDQsXG5cdCAgICAgICAgICogICAgICAgICBmb3JtYXR0ZXI6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMXG5cdCAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXJQYXJhbXMpIHtcblx0ICAgICAgICAgICAgdGhpcy5taXhJbihjaXBoZXJQYXJhbXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR9IGZvcm1hdHRlciAoT3B0aW9uYWwpIFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIHVzZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIGNpcGhlciBwYXJhbXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAdGhyb3dzIEVycm9yIElmIG5laXRoZXIgdGhlIGZvcm1hdHRlciBub3IgdGhlIGRlZmF1bHQgZm9ybWF0dGVyIGlzIHNldC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IGNpcGhlclBhcmFtcyArICcnO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSBjaXBoZXJQYXJhbXMudG9TdHJpbmcoQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoZm9ybWF0dGVyKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAoZm9ybWF0dGVyIHx8IHRoaXMuZm9ybWF0dGVyKS5zdHJpbmdpZnkodGhpcyk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogRm9ybWF0IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZm9ybWF0ID0gQy5mb3JtYXQgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGZvcm1hdHRpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBPcGVuU1NMRm9ybWF0dGVyID0gQ19mb3JtYXQuT3BlblNTTCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc30gY2lwaGVyUGFyYW1zIFRoZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBvcGVuU1NMU3RyaW5nID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wuc3RyaW5naWZ5KGNpcGhlclBhcmFtcyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IGNpcGhlclBhcmFtcy5jaXBoZXJ0ZXh0O1xuXHQgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0O1xuXG5cdCAgICAgICAgICAgIC8vIEZvcm1hdFxuXHQgICAgICAgICAgICBpZiAoc2FsdCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IFdvcmRBcnJheS5jcmVhdGUoWzB4NTM2MTZjNzQsIDB4NjU2NDVmNWZdKS5jb25jYXQoc2FsdCkuY29uY2F0KGNpcGhlcnRleHQpO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheSA9IGNpcGhlcnRleHQ7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gd29yZEFycmF5LnRvU3RyaW5nKEJhc2U2NCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVuU1NMU3RyIFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgY2lwaGVyIHBhcmFtcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTC5wYXJzZShvcGVuU1NMU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKG9wZW5TU0xTdHIpIHtcblx0ICAgICAgICAgICAgLy8gUGFyc2UgYmFzZTY0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gQmFzZTY0LnBhcnNlKG9wZW5TU0xTdHIpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0V29yZHMgPSBjaXBoZXJ0ZXh0LndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFRlc3QgZm9yIHNhbHRcblx0ICAgICAgICAgICAgaWYgKGNpcGhlcnRleHRXb3Jkc1swXSA9PSAweDUzNjE2Yzc0ICYmIGNpcGhlcnRleHRXb3Jkc1sxXSA9PSAweDY1NjQ1ZjVmKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHNhbHRcblx0ICAgICAgICAgICAgICAgIHZhciBzYWx0ID0gV29yZEFycmF5LmNyZWF0ZShjaXBoZXJ0ZXh0V29yZHMuc2xpY2UoMiwgNCkpO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHRcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7XG5cdCAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoeyBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LCBzYWx0OiBzYWx0IH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0Zvcm1hdHRlcn0gZm9ybWF0IFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIGNvbnZlcnQgY2lwaGVyIHBhcmFtIG9iamVjdHMgdG8gYW5kIGZyb20gYSBzdHJpbmcuIERlZmF1bHQ6IE9wZW5TU0xcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgZm9ybWF0OiBPcGVuU1NMRm9ybWF0dGVyXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuXG5cdCAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXksIHsgaXY6IGl2IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJ0ZXh0ID0gZW5jcnlwdG9yLmZpbmFsaXplKG1lc3NhZ2UpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0XG5cdCAgICAgICAgICAgIHZhciBjaXBoZXJDZmcgPSBlbmNyeXB0b3IuY2ZnO1xuXG5cdCAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zXG5cdCAgICAgICAgICAgIHJldHVybiBDaXBoZXJQYXJhbXMuY3JlYXRlKHtcblx0ICAgICAgICAgICAgICAgIGNpcGhlcnRleHQ6IGNpcGhlcnRleHQsXG5cdCAgICAgICAgICAgICAgICBrZXk6IGtleSxcblx0ICAgICAgICAgICAgICAgIGl2OiBjaXBoZXJDZmcuaXYsXG5cdCAgICAgICAgICAgICAgICBhbGdvcml0aG06IGNpcGhlcixcblx0ICAgICAgICAgICAgICAgIG1vZGU6IGNpcGhlckNmZy5tb2RlLFxuXHQgICAgICAgICAgICAgICAgcGFkZGluZzogY2lwaGVyQ2ZnLnBhZGRpbmcsXG5cdCAgICAgICAgICAgICAgICBibG9ja1NpemU6IGNpcGhlci5ibG9ja1NpemUsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGNmZy5mb3JtYXRcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dCB0byBkZWNyeXB0LlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZyB0byBDaXBoZXJQYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dCA9IHRoaXMuX3BhcnNlKGNpcGhlcnRleHQsIGNmZy5mb3JtYXQpO1xuXG5cdCAgICAgICAgICAgIC8vIERlY3J5cHRcblx0ICAgICAgICAgICAgdmFyIHBsYWludGV4dCA9IGNpcGhlci5jcmVhdGVEZWNyeXB0b3Ioa2V5LCBjZmcpLmZpbmFsaXplKGNpcGhlcnRleHQuY2lwaGVydGV4dCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHRvIENpcGhlclBhcmFtcyxcblx0ICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBUaGUgdW5zZXJpYWxpemVkIGNpcGhlcnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5fcGFyc2UoY2lwaGVydGV4dFN0cmluZ09yUGFyYW1zLCBmb3JtYXQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wYXJzZTogZnVuY3Rpb24gKGNpcGhlcnRleHQsIGZvcm1hdCkge1xuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfa2RmID0gQy5rZGYgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLlxuXHQgICAgICovXG5cdCAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVyaXZlcyBhIGtleSBhbmQgSVYgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZXJpdmUgZnJvbS5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0ga2V5U2l6ZSBUaGUgc2l6ZSBpbiB3b3JkcyBvZiB0aGUga2V5IHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gc2FsdCAoT3B0aW9uYWwpIEEgNjQtYml0IHNhbHQgdG8gdXNlLiBJZiBvbWl0dGVkLCBhIHNhbHQgd2lsbCBiZSBnZW5lcmF0ZWQgcmFuZG9tbHkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7XG5cdCAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMiwgJ3NhbHRzYWx0Jyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQpIHtcblx0ICAgICAgICAgICAgLy8gR2VuZXJhdGUgcmFuZG9tIHNhbHRcblx0ICAgICAgICAgICAgaWYgKCFzYWx0KSB7XG5cdCAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NC84KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIERlcml2ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBrZXkgPSBFdnBLREYuY3JlYXRlKHsga2V5U2l6ZToga2V5U2l6ZSArIGl2U2l6ZSB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblxuXHQgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWXG5cdCAgICAgICAgICAgIHZhciBpdiA9IFdvcmRBcnJheS5jcmVhdGUoa2V5LndvcmRzLnNsaWNlKGtleVNpemUpLCBpdlNpemUgKiA0KTtcblx0ICAgICAgICAgICAga2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIHBhcmFtc1xuXHQgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7IGtleToga2V5LCBpdjogaXYsIHNhbHQ6IHNhbHQgfSk7XG5cdCAgICAgICAgfVxuXHQgICAgfTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsXG5cdCAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICovXG5cdCAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcHJvcGVydHkge0tERn0ga2RmIFRoZSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiB0byB1c2UgdG8gZ2VuZXJhdGUgYSBrZXkgYW5kIElWIGZyb20gYSBwYXNzd29yZC4gRGVmYXVsdDogT3BlblNTTFxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZGY6IE9wZW5TU0xLZGZcblx0ICAgICAgICB9KSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBUaGUgY2lwaGVyIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC5cblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7Q2lwaGVyUGFyYW1zfSBBIGNpcGhlciBwYXJhbXMgb2JqZWN0LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcpO1xuXHQgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBlbmNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBtZXNzYWdlLCBwYXNzd29yZCwgY2ZnKSB7XG5cdCAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0c1xuXHQgICAgICAgICAgICBjZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplKTtcblxuXHQgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnXG5cdCAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7XG5cblx0ICAgICAgICAgICAgLy8gRW5jcnlwdFxuXHQgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBNaXggaW4gZGVyaXZlZCBwYXJhbXNcblx0ICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0IHVzaW5nIGEgcGFzc3dvcmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS5cblx0ICAgICAgICAgKiBAcGFyYW0ge0NpcGhlclBhcmFtc3xzdHJpbmd9IGNpcGhlcnRleHQgVGhlIGNpcGhlcnRleHQgdG8gZGVjcnlwdC5cblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmQgVGhlIHBhc3N3b3JkLlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwbGFpbnRleHQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgY2lwaGVydGV4dCwgcGFzc3dvcmQsIGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gQ2lwaGVyUGFyYW1zXG5cdCAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTtcblxuXHQgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQpO1xuXG5cdCAgICAgICAgICAgIC8vIEFkZCBJViB0byBjb25maWdcblx0ICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjtcblxuXHQgICAgICAgICAgICAvLyBEZWNyeXB0XG5cdCAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblx0fSgpKTtcblxuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KCk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG5cdC8qKlxuXHQgKiBDcnlwdG9KUyBjb3JlIGNvbXBvbmVudHMuXG5cdCAqL1xuXHR2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCAoZnVuY3Rpb24gKE1hdGgsIHVuZGVmaW5lZCkge1xuXHQgICAgLypcblx0ICAgICAqIExvY2FsIHBvbHlmaWwgb2YgT2JqZWN0LmNyZWF0ZVxuXHQgICAgICovXG5cdCAgICB2YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZ1bmN0aW9uIEYoKSB7fTtcblxuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJ0eXBlO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gb2JqO1xuXG5cdCAgICAgICAgICAgIHN1YnR5cGUgPSBuZXcgRigpO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gbnVsbDtcblxuXHQgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICB9O1xuXHQgICAgfSgpKVxuXG5cdCAgICAvKipcblx0ICAgICAqIENyeXB0b0pTIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBMaWJyYXJ5IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbGliID0gQy5saWIgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gKGZ1bmN0aW9uICgpIHtcblxuXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG92ZXJyaWRlcyBQcm9wZXJ0aWVzIHRvIGNvcHkgaW50byB0aGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgdmFyIE15VHlwZSA9IENyeXB0b0pTLmxpYi5CYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScsXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgfVxuXHQgICAgICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uIChvdmVycmlkZXMpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNwYXduXG5cdCAgICAgICAgICAgICAgICB2YXIgc3VidHlwZSA9IGNyZWF0ZSh0aGlzKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQXVnbWVudFxuXHQgICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YnR5cGUubWl4SW4ob3ZlcnJpZGVzKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXJcblx0ICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgc3VidHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0XG5cdCAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHN1cGVydHlwZVxuXHQgICAgICAgICAgICAgICAgc3VidHlwZS4kc3VwZXIgPSB0aGlzO1xuXG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogRXh0ZW5kcyB0aGlzIG9iamVjdCBhbmQgcnVucyB0aGUgaW5pdCBtZXRob2QuXG5cdCAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIG5ldyBvYmplY3QuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBpbnN0YW5jZSA9IE15VHlwZS5jcmVhdGUoKTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5leHRlbmQoKTtcblx0ICAgICAgICAgICAgICAgIGluc3RhbmNlLmluaXQuYXBwbHkoaW5zdGFuY2UsIGFyZ3VtZW50cyk7XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG9iamVjdC5cblx0ICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgICogICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLlxuXHQgICAgICAgICAgICAgKiAgICAgICAgIH1cblx0ICAgICAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBUaGUgcHJvcGVydGllcyB0byBtaXggaW4uXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oe1xuXHQgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnXG5cdCAgICAgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIG1peEluOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIElFIHdvbid0IGNvcHkgdG9TdHJpbmcgdXNpbmcgdGhlIGxvb3AgYWJvdmVcblx0ICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCd0b1N0cmluZycpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IGluc3RhbmNlLmNsb25lKCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgKi9cblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyAoT3B0aW9uYWwpIEFuIGFycmF5IG9mIDMyLWJpdCB3b3Jkcy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10pO1xuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddLCA2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgd29yZCBhcnJheSB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXhcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IHdvcmRBcnJheS50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gd29yZEFycmF5LnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGVuY29kZXIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25jYXRlbmF0ZXMgYSB3b3JkIGFycmF5IHRvIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbmNhdDogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGF0V29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGlzU2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHRoaXMuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDb25jYXRcblx0ICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXRCeXRlID0gKHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gKDI0IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzWyh0aGlzU2lnQnl0ZXMgKyBpKSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgKDI0IC0gKCh0aGlzU2lnQnl0ZXMgKyBpKSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBDb3B5IG9uZSB3b3JkIGF0IGEgdGltZVxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGF0U2lnQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXNXb3Jkc1sodGhpc1NpZ0J5dGVzICsgaSkgPj4+IDJdID0gdGhhdFdvcmRzW2kgPj4+IDJdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgKz0gdGhhdFNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVtb3ZlcyBpbnNpZ25pZmljYW50IGJpdHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsYW1wOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wXG5cdCAgICAgICAgICAgIHdvcmRzW3NpZ0J5dGVzID4+PiAyXSAmPSAweGZmZmZmZmZmIDw8ICgzMiAtIChzaWdCeXRlcyAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gd29yZEFycmF5LmNsb25lKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gQmFzZS5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgd29yZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzIFRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmFuZG9tOiBmdW5jdGlvbiAobkJ5dGVzKSB7XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXG5cdCAgICAgICAgICAgIHZhciByID0gKGZ1bmN0aW9uIChtX3cpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtX3cgPSBtX3c7XG5cdCAgICAgICAgICAgICAgICB2YXIgbV96ID0gMHgzYWRlNjhiMTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYXNrID0gMHhmZmZmZmZmZjtcblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICBtX3ogPSAoMHg5MDY5ICogKG1feiAmIDB4RkZGRikgKyAobV96ID4+IDB4MTApKSAmIG1hc2s7XG5cdCAgICAgICAgICAgICAgICAgICAgbV93ID0gKDB4NDY1MCAqIChtX3cgJiAweEZGRkYpICsgKG1fdyA+PiAweDEwKSkgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSAoKG1feiA8PCAweDEwKSArIG1fdykgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAvPSAweDEwMDAwMDAwMDtcblx0ICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gMC41O1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgKiAoTWF0aC5yYW5kb20oKSA+IC41ID8gMSA6IC0xKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIHJjYWNoZTsgaSA8IG5CeXRlczsgaSArPSA0KSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgX3IgPSByKChyY2FjaGUgfHwgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwMDAwMCk7XG5cblx0ICAgICAgICAgICAgICAgIHJjYWNoZSA9IF9yKCkgKiAweDNhZGU2N2I3O1xuXHQgICAgICAgICAgICAgICAgd29yZHMucHVzaCgoX3IoKSAqIDB4MTAwMDAwMDAwKSB8IDApO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBIZXggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXggPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGhleENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJpdGUgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTtcblx0ICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhleENoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhleFN0ciBUaGUgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8ICgyNCAtIChpICUgOCkgKiA0KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQod29yZHMsIGhleFN0ckxlbmd0aCAvIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogTGF0aW4xIGVuY29kaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgTGF0aW4xID0gQ19lbmMuTGF0aW4xID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgTGF0aW4xIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGxhdGluMVN0cmluZyA9IENyeXB0b0pTLmVuYy5MYXRpbjEuc3RyaW5naWZ5KHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBiaXRlID0gKHdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIGxhdGluMUNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaXRlKSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbGF0aW4xQ2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgTGF0aW4xIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF0aW4xU3RyIFRoZSBMYXRpbjEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGxhdGluMVN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGluMVN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSAobGF0aW4xU3RyLmNoYXJDb2RlQXQoaSkgJiAweGZmKSA8PCAoMjQgLSAoaSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtOCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpKSk7XG5cdCAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmOFN0ciBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHV0ZjhTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikge1xuXHQgICAgICAgICAgICByZXR1cm4gTGF0aW4xLnBhcnNlKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh1dGY4U3RyKSkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYnVmZmVyZWQgYmxvY2sgYWxnb3JpdGhtIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIFRoZSBwcm9wZXJ0eSBibG9ja1NpemUgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBhIGNvbmNyZXRlIHN1YnR5cGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9taW5CdWZmZXJTaXplIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgc2hvdWxkIGJlIGtlcHQgdW5wcm9jZXNzZWQgaW4gdGhlIGJ1ZmZlci4gRGVmYXVsdDogMFxuXHQgICAgICovXG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgZGF0YSBidWZmZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLl9kYXRhID0gbmV3IFdvcmRBcnJheS5pbml0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX25EYXRhQnl0ZXMgPSAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIG5ldyBkYXRhIHRvIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgYnVmZmVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGFwcGVuZC4gU3RyaW5ncyBhcmUgY29udmVydGVkIHRvIGEgV29yZEFycmF5IHVzaW5nIFVURi04LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9hcHBlbmQoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2FwcGVuZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2RhdGEuY29uY2F0KGRhdGEpO1xuXHQgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzICs9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFByb2Nlc3NlcyBhdmFpbGFibGUgZGF0YSBibG9ja3MuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIF9kb1Byb2Nlc3NCbG9jayhvZmZzZXQpLCB3aGljaCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgY29uY3JldGUgc3VidHlwZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwcm9jZXNzZWQgZGF0YS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgICogICAgIHZhciBwcm9jZXNzZWREYXRhID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fcHJvY2VzcyghISdmbHVzaCcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHlcblx0ICAgICAgICAgICAgdmFyIG5CbG9ja3NSZWFkeSA9IGRhdGFTaWdCeXRlcyAvIGJsb2NrU2l6ZUJ5dGVzO1xuXHQgICAgICAgICAgICBpZiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAgICAgLy8gUm91bmQgdXAgdG8gaW5jbHVkZSBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgbkJsb2Nrc1JlYWR5ID0gTWF0aC5jZWlsKG5CbG9ja3NSZWFkeSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2Nrcyxcblx0ICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyXG5cdCAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5XG5cdCAgICAgICAgICAgIHZhciBuV29yZHNSZWFkeSA9IG5CbG9ja3NSZWFkeSAqIGJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeVxuXHQgICAgICAgICAgICB2YXIgbkJ5dGVzUmVhZHkgPSBNYXRoLm1pbihuV29yZHNSZWFkeSAqIDQsIGRhdGFTaWdCeXRlcyk7XG5cblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3Ncblx0ICAgICAgICAgICAgaWYgKG5Xb3Jkc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBuV29yZHNSZWFkeTsgb2Zmc2V0ICs9IGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fZG9Qcm9jZXNzQmxvY2soZGF0YVdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkV29yZHMgPSBkYXRhV29yZHMuc3BsaWNlKDAsIG5Xb3Jkc1JlYWR5KTtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gbkJ5dGVzUmVhZHk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQocHJvY2Vzc2VkV29yZHMsIG5CeXRlc1JlYWR5KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5jbG9uZSgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2RhdGEgPSB0aGlzLl9kYXRhLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfbWluQnVmZmVyU2l6ZTogMFxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgaGFzaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBoYXNoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDE2ICg1MTIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaGVyID0gQ3J5cHRvSlMuYWxnby5TSEEyNTYuY3JlYXRlKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBoYXNoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWhhc2hlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBoYXNoZXIgd2l0aCBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7SGFzaGVyfSBUaGlzIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICBoYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaGFzaFxuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGhhc2ggY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBtZXNzYWdlIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogNTEyLzMyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIGEgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2hlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGNmZykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBoYXNoZXIuaW5pdChjZmcpLmZpbmFsaXplKG1lc3NhZ2UpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEhtYWNTSEEyNTYgPSBDcnlwdG9KUy5saWIuSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKENyeXB0b0pTLmFsZ28uU0hBMjU2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBbGdvcml0aG0gbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvID0ge307XG5cblx0ICAgIHJldHVybiBDO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBDX2VuYyA9IEMuZW5jO1xuXG5cdCAgICAvKipcblx0ICAgICAqIEJhc2U2NCBlbmNvZGluZyBzdHJhdGVneS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2U2NCA9IENfZW5jLkJhc2U2NCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBCYXNlNjQgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIEJhc2U2NCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBiYXNlNjRTdHJpbmcgPSBDcnlwdG9KUy5lbmMuQmFzZTY0LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB3b3JkQXJyYXkuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAgd29yZEFycmF5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgYmFzZTY0Q2hhcnMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAzKSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgYnl0ZTEgPSAod29yZHNbaSA+Pj4gMl0gICAgICAgPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgICAgICAgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgdmFyIGJ5dGUyID0gKHdvcmRzWyhpICsgMSkgPj4+IDJdID4+PiAoMjQgLSAoKGkgKyAxKSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIHZhciBieXRlMyA9ICh3b3Jkc1soaSArIDIpID4+PiAyXSA+Pj4gKDI0IC0gKChpICsgMikgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cblx0ICAgICAgICAgICAgICAgIHZhciB0cmlwbGV0ID0gKGJ5dGUxIDw8IDE2KSB8IChieXRlMiA8PCA4KSB8IGJ5dGUzO1xuXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgKGogPCA0KSAmJiAoaSArIGogKiAwLjc1IDwgc2lnQnl0ZXMpOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKG1hcC5jaGFyQXQoKHRyaXBsZXQgPj4+ICg2ICogKDMgLSBqKSkpICYgMHgzZikpO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7XG5cdCAgICAgICAgICAgIGlmIChwYWRkaW5nQ2hhcikge1xuXHQgICAgICAgICAgICAgICAgd2hpbGUgKGJhc2U2NENoYXJzLmxlbmd0aCAlIDQpIHtcblx0ICAgICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKHBhZGRpbmdDaGFyKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBiYXNlNjRDaGFycy5qb2luKCcnKTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSBCYXNlNjQgc3RyaW5nIHRvIGEgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjRTdHIgVGhlIEJhc2U2NCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5wYXJzZShiYXNlNjRTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoYmFzZTY0U3RyKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgYmFzZTY0U3RyTGVuZ3RoID0gYmFzZTY0U3RyLmxlbmd0aDtcblx0ICAgICAgICAgICAgdmFyIG1hcCA9IHRoaXMuX21hcDtcblx0ICAgICAgICAgICAgdmFyIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwO1xuXG5cdCAgICAgICAgICAgIGlmICghcmV2ZXJzZU1hcCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwID0gW107XG5cdCAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXAubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZU1hcFttYXAuY2hhckNvZGVBdChqKV0gPSBqO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElnbm9yZSBwYWRkaW5nXG5cdCAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpO1xuXHQgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nSW5kZXggPSBiYXNlNjRTdHIuaW5kZXhPZihwYWRkaW5nQ2hhcik7XG5cdCAgICAgICAgICAgICAgICBpZiAocGFkZGluZ0luZGV4ICE9PSAtMSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGJhc2U2NFN0ckxlbmd0aCA9IHBhZGRpbmdJbmRleDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgcmV0dXJuIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCk7XG5cblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgX21hcDogJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89J1xuXHQgICAgfTtcblxuXHQgICAgZnVuY3Rpb24gcGFyc2VMb29wKGJhc2U2NFN0ciwgYmFzZTY0U3RyTGVuZ3RoLCByZXZlcnNlTWFwKSB7XG5cdCAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICB2YXIgbkJ5dGVzID0gMDtcblx0ICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiYXNlNjRTdHJMZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgaWYgKGkgJSA0KSB7XG5cdCAgICAgICAgICAgICAgdmFyIGJpdHMxID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpIC0gMSldIDw8ICgoaSAlIDQpICogMik7XG5cdCAgICAgICAgICAgICAgdmFyIGJpdHMyID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpKV0gPj4+ICg2IC0gKGkgJSA0KSAqIDIpO1xuXHQgICAgICAgICAgICAgIHdvcmRzW25CeXRlcyA+Pj4gMl0gfD0gKGJpdHMxIHwgYml0czIpIDw8ICgyNCAtIChuQnl0ZXMgJSA0KSAqIDgpO1xuXHQgICAgICAgICAgICAgIG5CeXRlcysrO1xuXHQgICAgICAgICAgfVxuXHQgICAgICB9XG5cdCAgICAgIHJldHVybiBXb3JkQXJyYXkuY3JlYXRlKHdvcmRzLCBuQnl0ZXMpO1xuXHQgICAgfVxuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLmVuYy5CYXNlNjQ7XG5cbn0pKTsiLCI7KGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuXHRcdC8vIENvbW1vbkpTXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwiLi9jb3JlXCIpKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXCIuL2NvcmVcIl0sIGZhY3RvcnkpO1xuXHR9XG5cdGVsc2Uge1xuXHRcdC8vIEdsb2JhbCAoYnJvd3Nlcilcblx0XHRmYWN0b3J5KHJvb3QuQ3J5cHRvSlMpO1xuXHR9XG59KHRoaXMsIGZ1bmN0aW9uIChDcnlwdG9KUykge1xuXG5cdHJldHVybiBDcnlwdG9KUy5lbmMuSGV4O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIiksIHJlcXVpcmUoXCIuL3NoYTFcIiksIHJlcXVpcmUoXCIuL2htYWNcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiLCBcIi4vc2hhMVwiLCBcIi4vaG1hY1wiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uICgpIHtcblx0ICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgdmFyIEMgPSBDcnlwdG9KUztcblx0ICAgIHZhciBDX2xpYiA9IEMubGliO1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlO1xuXHQgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cdCAgICB2YXIgTUQ1ID0gQ19hbGdvLk1ENTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBUaGlzIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIGlzIG1lYW50IHRvIGNvbmZvcm0gd2l0aCBFVlBfQnl0ZXNUb0tleS5cblx0ICAgICAqIHd3dy5vcGVuc3NsLm9yZy9kb2NzL2NyeXB0by9FVlBfQnl0ZXNUb0tleS5odG1sXG5cdCAgICAgKi9cblx0ICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGID0gQmFzZS5leHRlbmQoe1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoZSBrZXkgc2l6ZSBpbiB3b3JkcyB0byBnZW5lcmF0ZS4gRGVmYXVsdDogNCAoMTI4IGJpdHMpXG5cdCAgICAgICAgICogQHByb3BlcnR5IHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaCBhbGdvcml0aG0gdG8gdXNlLiBEZWZhdWx0OiBNRDVcblx0ICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaXRlcmF0aW9ucyBUaGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdG8gcGVyZm9ybS4gRGVmYXVsdDogMVxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNmZzogQmFzZS5leHRlbmQoe1xuXHQgICAgICAgICAgICBrZXlTaXplOiAxMjgvMzIsXG5cdCAgICAgICAgICAgIGhhc2hlcjogTUQ1LFxuXHQgICAgICAgICAgICBpdGVyYXRpb25zOiAxXG5cdCAgICAgICAgfSksXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQga2V5IGRlcml2YXRpb24gZnVuY3Rpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoZSBkZXJpdmF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIga2RmID0gQ3J5cHRvSlMuYWxnby5FdnBLREYuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pO1xuXHQgICAgICAgICAqICAgICB2YXIga2RmID0gQ3J5cHRvSlMuYWxnby5FdnBLREYuY3JlYXRlKHsga2V5U2l6ZTogOCwgaXRlcmF0aW9uczogMTAwMCB9KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7XG5cdCAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIERlcml2ZXMgYSBrZXkgZnJvbSBhIHBhc3N3b3JkLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbXB1dGU6IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IGNmZy5oYXNoZXIuY3JlYXRlKCk7XG5cblx0ICAgICAgICAgICAgLy8gSW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXkgPSBXb3JkQXJyYXkuY3JlYXRlKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBkZXJpdmVkS2V5V29yZHMgPSBkZXJpdmVkS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGNmZy5rZXlTaXplO1xuXHQgICAgICAgICAgICB2YXIgaXRlcmF0aW9ucyA9IGNmZy5pdGVyYXRpb25zO1xuXG5cdCAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleVxuXHQgICAgICAgICAgICB3aGlsZSAoZGVyaXZlZEtleVdvcmRzLmxlbmd0aCA8IGtleVNpemUpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChibG9jaykge1xuXHQgICAgICAgICAgICAgICAgICAgIGhhc2hlci51cGRhdGUoYmxvY2spO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaGFzaGVyLnVwZGF0ZShwYXNzd29yZCkuZmluYWxpemUoc2FsdCk7XG5cdCAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gSXRlcmF0aW9uc1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBpdGVyYXRpb25zOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBibG9jayA9IGhhc2hlci5maW5hbGl6ZShibG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGRlcml2ZWRLZXkuY29uY2F0KGJsb2NrKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LlxuXHQgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0KTtcblx0ICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7XG5cdCAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLkV2cEtERihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pO1xuXHQgICAgICovXG5cdCAgICBDLkV2cEtERiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7XG5cdCAgICAgICAgcmV0dXJuIEV2cEtERi5jcmVhdGUoY2ZnKS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTtcblx0ICAgIH07XG5cdH0oKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuRXZwS0RGO1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7XG5cdCAgICB2YXIgQ19lbmMgPSBDLmVuYztcblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmODtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8qKlxuXHQgICAgICogSE1BQyBhbGdvcml0aG0uXG5cdCAgICAgKi9cblx0ICAgIHZhciBITUFDID0gQ19hbGdvLkhNQUMgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIEhNQUMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBobWFjSGFzaGVyID0gQ3J5cHRvSlMuYWxnby5ITUFDLmNyZWF0ZShDcnlwdG9KUy5hbGdvLlNIQTI1Niwga2V5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAoaGFzaGVyLCBrZXkpIHtcblx0ICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXJcblx0ICAgICAgICAgICAgaGFzaGVyID0gdGhpcy5faGFzaGVyID0gbmV3IGhhc2hlci5pbml0KCk7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGtleSA9PSAnc3RyaW5nJykge1xuXHQgICAgICAgICAgICAgICAga2V5ID0gVXRmOC5wYXJzZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBoYXNoZXJCbG9ja1NpemUgPSBoYXNoZXIuYmxvY2tTaXplO1xuXHQgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemUgKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEFsbG93IGFyYml0cmFyeSBsZW5ndGgga2V5c1xuXHQgICAgICAgICAgICBpZiAoa2V5LnNpZ0J5dGVzID4gaGFzaGVyQmxvY2tTaXplQnl0ZXMpIHtcblx0ICAgICAgICAgICAgICAgIGtleSA9IGhhc2hlci5maW5hbGl6ZShrZXkpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHNcblx0ICAgICAgICAgICAga2V5LmNsYW1wKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2xvbmUga2V5IGZvciBpbm5lciBhbmQgb3V0ZXIgcGFkc1xuXHQgICAgICAgICAgICB2YXIgb0tleSA9IHRoaXMuX29LZXkgPSBrZXkuY2xvbmUoKTtcblx0ICAgICAgICAgICAgdmFyIGlLZXkgPSB0aGlzLl9pS2V5ID0ga2V5LmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciBvS2V5V29yZHMgPSBvS2V5LndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgaUtleVdvcmRzID0gaUtleS53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBYT1Iga2V5cyB3aXRoIHBhZCBjb25zdGFudHNcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXJCbG9ja1NpemU7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgb0tleVdvcmRzW2ldIF49IDB4NWM1YzVjNWM7XG5cdCAgICAgICAgICAgICAgICBpS2V5V29yZHNbaV0gXj0gMHgzNjM2MzYzNjtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBvS2V5LnNpZ0J5dGVzID0gaUtleS5zaWdCeXRlcyA9IGhhc2hlckJsb2NrU2l6ZUJ5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFJlc2V0cyB0aGlzIEhNQUMgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyO1xuXG5cdCAgICAgICAgICAgIC8vIFJlc2V0XG5cdCAgICAgICAgICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAgICBoYXNoZXIudXBkYXRlKHRoaXMuX2lLZXkpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBVcGRhdGVzIHRoaXMgSE1BQyB3aXRoIGEgbWVzc2FnZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSBUaGUgbWVzc2FnZSB0byBhcHBlbmQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtITUFDfSBUaGlzIEhNQUMgaW5zdGFuY2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKCdtZXNzYWdlJyk7XG5cdCAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoZXIudXBkYXRlKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogRmluYWxpemVzIHRoZSBITUFDIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgKE9wdGlvbmFsKSBBIGZpbmFsIG1lc3NhZ2UgdXBkYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKCk7XG5cdCAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKG1lc3NhZ2VVcGRhdGUpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhhc2hlciA9IHRoaXMuX2hhc2hlcjtcblxuXHQgICAgICAgICAgICAvLyBDb21wdXRlIEhNQUNcblx0ICAgICAgICAgICAgdmFyIGlubmVySGFzaCA9IGhhc2hlci5maW5hbGl6ZShtZXNzYWdlVXBkYXRlKTtcblx0ICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7XG5cdCAgICAgICAgICAgIHZhciBobWFjID0gaGFzaGVyLmZpbmFsaXplKHRoaXMuX29LZXkuY2xvbmUoKS5jb25jYXQoaW5uZXJIYXNoKSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhtYWM7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cdH0oKSk7XG5cblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uIChNYXRoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gQ29uc3RhbnRzIHRhYmxlXG5cdCAgICB2YXIgVCA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIGNvbnN0YW50c1xuXHQgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDY0OyBpKyspIHtcblx0ICAgICAgICAgICAgVFtpXSA9IChNYXRoLmFicyhNYXRoLnNpbihpICsgMSkpICogMHgxMDAwMDAwMDApIHwgMDtcblx0ICAgICAgICB9XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIE1ENSBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIE1ENSA9IENfYWxnby5NRDUgPSBIYXNoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoID0gbmV3IFdvcmRBcnJheS5pbml0KFtcblx0ICAgICAgICAgICAgICAgIDB4Njc0NTIzMDEsIDB4ZWZjZGFiODksXG5cdCAgICAgICAgICAgICAgICAweDk4YmFkY2ZlLCAweDEwMzI1NDc2XG5cdCAgICAgICAgICAgIF0pO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGk7XG5cdCAgICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldO1xuXG5cdCAgICAgICAgICAgICAgICBNW29mZnNldF9pXSA9IChcblx0ICAgICAgICAgICAgICAgICAgICAoKChNX29mZnNldF9pIDw8IDgpICB8IChNX29mZnNldF9pID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgICAgICgoKE1fb2Zmc2V0X2kgPDwgMjQpIHwgKE1fb2Zmc2V0X2kgPj4+IDgpKSAgJiAweGZmMDBmZjAwKVxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7XG5cblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzAgID0gTVtvZmZzZXQgKyAwXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEgID0gTVtvZmZzZXQgKyAxXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzIgID0gTVtvZmZzZXQgKyAyXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzMgID0gTVtvZmZzZXQgKyAzXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzQgID0gTVtvZmZzZXQgKyA0XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzUgID0gTVtvZmZzZXQgKyA1XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzYgID0gTVtvZmZzZXQgKyA2XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzcgID0gTVtvZmZzZXQgKyA3XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzggID0gTVtvZmZzZXQgKyA4XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzkgID0gTVtvZmZzZXQgKyA5XTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEwID0gTVtvZmZzZXQgKyAxMF07XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xMSA9IE1bb2Zmc2V0ICsgMTFdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTIgPSBNW29mZnNldCArIDEyXTtcblx0ICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEzID0gTVtvZmZzZXQgKyAxM107XG5cdCAgICAgICAgICAgIHZhciBNX29mZnNldF8xNCA9IE1bb2Zmc2V0ICsgMTRdO1xuXHQgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMTUgPSBNW29mZnNldCArIDE1XTtcblxuXHQgICAgICAgICAgICAvLyBXb3JraW5nIHZhcmlhbGJlc1xuXHQgICAgICAgICAgICB2YXIgYSA9IEhbMF07XG5cdCAgICAgICAgICAgIHZhciBiID0gSFsxXTtcblx0ICAgICAgICAgICAgdmFyIGMgPSBIWzJdO1xuXHQgICAgICAgICAgICB2YXIgZCA9IEhbM107XG5cblx0ICAgICAgICAgICAgLy8gQ29tcHV0YXRpb25cblx0ICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzAsICA3LCAgVFswXSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF8xLCAgMTIsIFRbMV0pO1xuXHQgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfMiwgIDE3LCBUWzJdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzMsICAyMiwgVFszXSk7XG5cdCAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF80LCAgNywgIFRbNF0pO1xuXHQgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfNSwgIDEyLCBUWzVdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzYsICAxNywgVFs2XSk7XG5cdCAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF83LCAgMjIsIFRbN10pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfOCwgIDcsICBUWzhdKTtcblx0ICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzksICAxMiwgVFs5XSk7XG5cdCAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8xMCwgMTcsIFRbMTBdKTtcblx0ICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzExLCAyMiwgVFsxMV0pO1xuXHQgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDcsICBUWzEyXSk7XG5cdCAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF8xMywgMTIsIFRbMTNdKTtcblx0ICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE0LCAxNywgVFsxNF0pO1xuXHQgICAgICAgICAgICBiID0gRkYoYiwgYywgZCwgYSwgTV9vZmZzZXRfMTUsIDIyLCBUWzE1XSk7XG5cblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEsICA1LCAgVFsxNl0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfNiwgIDksICBUWzE3XSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF8xMSwgMTQsIFRbMThdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzAsICAyMCwgVFsxOV0pO1xuXHQgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfNSwgIDUsICBUWzIwXSk7XG5cdCAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF8xMCwgOSwgIFRbMjFdKTtcblx0ICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNCwgVFsyMl0pO1xuXHQgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfNCwgIDIwLCBUWzIzXSk7XG5cdCAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF85LCAgNSwgIFRbMjRdKTtcblx0ICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE0LCA5LCAgVFsyNV0pO1xuXHQgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfMywgIDE0LCBUWzI2XSk7XG5cdCAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF84LCAgMjAsIFRbMjddKTtcblx0ICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA1LCAgVFsyOF0pO1xuXHQgICAgICAgICAgICBkID0gR0coZCwgYSwgYiwgYywgTV9vZmZzZXRfMiwgIDksICBUWzI5XSk7XG5cdCAgICAgICAgICAgIGMgPSBHRyhjLCBkLCBhLCBiLCBNX29mZnNldF83LCAgMTQsIFRbMzBdKTtcblx0ICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEyLCAyMCwgVFszMV0pO1xuXG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF81LCAgNCwgIFRbMzJdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzgsICAxMSwgVFszM10pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE2LCBUWzM0XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8xNCwgMjMsIFRbMzVdKTtcblx0ICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEsICA0LCAgVFszNl0pO1xuXHQgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfNCwgIDExLCBUWzM3XSk7XG5cdCAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF83LCAgMTYsIFRbMzhdKTtcblx0ICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEwLCAyMywgVFszOV0pO1xuXHQgICAgICAgICAgICBhID0gSEgoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTMsIDQsICBUWzQwXSk7XG5cdCAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8wLCAgMTEsIFRbNDFdKTtcblx0ICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsICAxNiwgVFs0Ml0pO1xuXHQgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfNiwgIDIzLCBUWzQzXSk7XG5cdCAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF85LCAgNCwgIFRbNDRdKTtcblx0ICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzEyLCAxMSwgVFs0NV0pO1xuXHQgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTUsIDE2LCBUWzQ2XSk7XG5cdCAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF8yLCAgMjMsIFRbNDddKTtcblxuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMCwgIDYsICBUWzQ4XSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF83LCAgMTAsIFRbNDldKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE0LCAxNSwgVFs1MF0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfNSwgIDIxLCBUWzUxXSk7XG5cdCAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF8xMiwgNiwgIFRbNTJdKTtcblx0ICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzMsICAxMCwgVFs1M10pO1xuXHQgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE1LCBUWzU0XSk7XG5cdCAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF8xLCAgMjEsIFRbNTVdKTtcblx0ICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsICA2LCAgVFs1Nl0pO1xuXHQgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTUsIDEwLCBUWzU3XSk7XG5cdCAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF82LCAgMTUsIFRbNThdKTtcblx0ICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEzLCAyMSwgVFs1OV0pO1xuXHQgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgIDYsICBUWzYwXSk7XG5cdCAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF8xMSwgMTAsIFRbNjFdKTtcblx0ICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzIsICAxNSwgVFs2Ml0pO1xuXHQgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfOSwgIDIxLCBUWzYzXSk7XG5cblx0ICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcblx0ICAgICAgICAgICAgSFswXSA9IChIWzBdICsgYSkgfCAwO1xuXHQgICAgICAgICAgICBIWzFdID0gKEhbMV0gKyBiKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMl0gPSAoSFsyXSArIGMpIHwgMDtcblx0ICAgICAgICAgICAgSFszXSA9IChIWzNdICsgZCkgfCAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4O1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cblx0ICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxIID0gTWF0aC5mbG9vcihuQml0c1RvdGFsIC8gMHgxMDAwMDAwMDApO1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbEwgPSBuQml0c1RvdGFsO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE1XSA9IChcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxIIDw8IDgpICB8IChuQml0c1RvdGFsSCA+Pj4gMjQpKSAmIDB4MDBmZjAwZmYpIHxcblx0ICAgICAgICAgICAgICAgICgoKG5CaXRzVG90YWxIIDw8IDI0KSB8IChuQml0c1RvdGFsSCA+Pj4gOCkpICAmIDB4ZmYwMGZmMDApXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gKFxuXHQgICAgICAgICAgICAgICAgKCgobkJpdHNUb3RhbEwgPDwgOCkgIHwgKG5CaXRzVG90YWxMID4+PiAyNCkpICYgMHgwMGZmMDBmZikgfFxuXHQgICAgICAgICAgICAgICAgKCgobkJpdHNUb3RhbEwgPDwgMjQpIHwgKG5CaXRzVG90YWxMID4+PiA4KSkgICYgMHhmZjAwZmYwMClcblx0ICAgICAgICAgICAgKTtcblxuXHQgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gKGRhdGFXb3Jkcy5sZW5ndGggKyAxKSAqIDQ7XG5cblx0ICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3Ncblx0ICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpO1xuXG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2hhc2g7XG5cdCAgICAgICAgICAgIHZhciBIID0gaGFzaC53b3JkcztcblxuXHQgICAgICAgICAgICAvLyBTd2FwIGVuZGlhblxuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgICAgIHZhciBIX2kgPSBIW2ldO1xuXG5cdCAgICAgICAgICAgICAgICBIW2ldID0gKCgoSF9pIDw8IDgpICB8IChIX2kgPj4+IDI0KSkgJiAweDAwZmYwMGZmKSB8XG5cdCAgICAgICAgICAgICAgICAgICAgICAgKCgoSF9pIDw8IDI0KSB8IChIX2kgPj4+IDgpKSAgJiAweGZmMDBmZjAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIFJldHVybiBmaW5hbCBjb21wdXRlZCBoYXNoXG5cdCAgICAgICAgICAgIHJldHVybiBoYXNoO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2hhc2ggPSB0aGlzLl9oYXNoLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH1cblx0ICAgIH0pO1xuXG5cdCAgICBmdW5jdGlvbiBGRihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKChiICYgYykgfCAofmIgJiBkKSkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBHRyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKChiICYgZCkgfCAoYyAmIH5kKSkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBISChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKGIgXiBjIF4gZCkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICBmdW5jdGlvbiBJSShhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5cdCAgICAgICAgdmFyIG4gPSBhICsgKGMgXiAoYiB8IH5kKSkgKyB4ICsgdDtcblx0ICAgICAgICByZXR1cm4gKChuIDw8IHMpIHwgKG4gPj4+ICgzMiAtIHMpKSkgKyBiO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuTUQ1KCdtZXNzYWdlJyk7XG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5NRDUod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5NRDUgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihNRDUpO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LlxuXHQgICAgICpcblx0ICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuXG5cdCAgICAgKlxuXHQgICAgICogQHN0YXRpY1xuXHQgICAgICpcblx0ICAgICAqIEBleGFtcGxlXG5cdCAgICAgKlxuXHQgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY01ENShtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNNRDUgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoTUQ1KTtcblx0fShNYXRoKSk7XG5cblxuXHRyZXR1cm4gQ3J5cHRvSlMuTUQ1O1xuXG59KSk7IiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZShcIi4vY29yZVwiKSk7XG5cdH1cblx0ZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcblx0XHQvLyBBTURcblx0XHRkZWZpbmUoW1wiLi9jb3JlXCJdLCBmYWN0b3J5KTtcblx0fVxuXHRlbHNlIHtcblx0XHQvLyBHbG9iYWwgKGJyb3dzZXIpXG5cdFx0ZmFjdG9yeShyb290LkNyeXB0b0pTKTtcblx0fVxufSh0aGlzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHtcblxuXHQoZnVuY3Rpb24gKCkge1xuXHQgICAgLy8gU2hvcnRjdXRzXG5cdCAgICB2YXIgQyA9IENyeXB0b0pTO1xuXHQgICAgdmFyIENfbGliID0gQy5saWI7XG5cdCAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5O1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlcjtcblx0ICAgIHZhciBDX2FsZ28gPSBDLmFsZ287XG5cblx0ICAgIC8vIFJldXNhYmxlIG9iamVjdFxuXHQgICAgdmFyIFcgPSBbXTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTSEEtMSBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNIQTEgPSBDX2FsZ28uU0hBMSA9IEhhc2hlci5leHRlbmQoe1xuXHQgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBuZXcgV29yZEFycmF5LmluaXQoW1xuXHQgICAgICAgICAgICAgICAgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSxcblx0ICAgICAgICAgICAgICAgIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsXG5cdCAgICAgICAgICAgICAgICAweGMzZDJlMWYwXG5cdCAgICAgICAgICAgIF0pO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzXG5cdCAgICAgICAgICAgIHZhciBhID0gSFswXTtcblx0ICAgICAgICAgICAgdmFyIGIgPSBIWzFdO1xuXHQgICAgICAgICAgICB2YXIgYyA9IEhbMl07XG5cdCAgICAgICAgICAgIHZhciBkID0gSFszXTtcblx0ICAgICAgICAgICAgdmFyIGUgPSBIWzRdO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgaWYgKGkgPCAxNikge1xuXHQgICAgICAgICAgICAgICAgICAgIFdbaV0gPSBNW29mZnNldCArIGldIHwgMDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIG4gPSBXW2kgLSAzXSBeIFdbaSAtIDhdIF4gV1tpIC0gMTRdIF4gV1tpIC0gMTZdO1xuXHQgICAgICAgICAgICAgICAgICAgIFdbaV0gPSAobiA8PCAxKSB8IChuID4+PiAzMSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIHZhciB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBlICsgV1tpXTtcblx0ICAgICAgICAgICAgICAgIGlmIChpIDwgMjApIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9ICgoYiAmIGMpIHwgKH5iICYgZCkpICsgMHg1YTgyNzk5OTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDQwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdCArPSAoYiBeIGMgXiBkKSArIDB4NmVkOWViYTE7XG5cdCAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPCA2MCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHQgKz0gKChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKSkgLSAweDcwZTQ0MzI0O1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIC8qIGlmIChpIDwgODApICovIHtcblx0ICAgICAgICAgICAgICAgICAgICB0ICs9IChiIF4gYyBeIGQpIC0gMHgzNTlkM2UyYTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgZSA9IGQ7XG5cdCAgICAgICAgICAgICAgICBkID0gYztcblx0ICAgICAgICAgICAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7XG5cdCAgICAgICAgICAgICAgICBiID0gYTtcblx0ICAgICAgICAgICAgICAgIGEgPSB0O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWVcblx0ICAgICAgICAgICAgSFswXSA9IChIWzBdICsgYSkgfCAwO1xuXHQgICAgICAgICAgICBIWzFdID0gKEhbMV0gKyBiKSB8IDA7XG5cdCAgICAgICAgICAgIEhbMl0gPSAoSFsyXSArIGMpIHwgMDtcblx0ICAgICAgICAgICAgSFszXSA9IChIWzNdICsgZCkgfCAwO1xuXHQgICAgICAgICAgICBIWzRdID0gKEhbNF0gKyBlKSB8IDA7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7XG5cdCAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzO1xuXG5cdCAgICAgICAgICAgIHZhciBuQml0c1RvdGFsID0gdGhpcy5fbkRhdGFCeXRlcyAqIDg7XG5cdCAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODtcblxuXHQgICAgICAgICAgICAvLyBBZGQgcGFkZGluZ1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8ICgyNCAtIG5CaXRzTGVmdCAlIDMyKTtcblx0ICAgICAgICAgICAgZGF0YVdvcmRzWygoKG5CaXRzTGVmdCArIDY0KSA+Pj4gOSkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTVdID0gbkJpdHNUb3RhbDtcblx0ICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0O1xuXG5cdCAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzXG5cdCAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTtcblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaFxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7XG5cdCAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBjbG9uZTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAqXG5cdCAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICpcblx0ICAgICAqIEBzdGF0aWNcblx0ICAgICAqXG5cdCAgICAgKiBAZXhhbXBsZVxuXHQgICAgICpcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTEoJ21lc3NhZ2UnKTtcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTEod29yZEFycmF5KTtcblx0ICAgICAqL1xuXHQgICAgQy5TSEExID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoU0hBMSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAqXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMShtZXNzYWdlLCBrZXkpO1xuXHQgICAgICovXG5cdCAgICBDLkhtYWNTSEExID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTEpO1xuXHR9KCkpO1xuXG5cblx0cmV0dXJuIENyeXB0b0pTLlNIQTE7XG5cbn0pKTsiLCJ2YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIG9iamVjdEtleXMgPSByZXF1aXJlKCcuL2xpYi9rZXlzLmpzJyk7XG52YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2xpYi9pc19hcmd1bWVudHMuanMnKTtcblxudmFyIGRlZXBFcXVhbCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG9wdHMpIHtcbiAgaWYgKCFvcHRzKSBvcHRzID0ge307XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgRGF0ZSAmJiBleHBlY3RlZCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMy4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCB8fCB0eXBlb2YgYWN0dWFsICE9ICdvYmplY3QnICYmIHR5cGVvZiBleHBlY3RlZCAhPSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvcHRzLnN0cmljdCA/IGFjdHVhbCA9PT0gZXhwZWN0ZWQgOiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gNy40LiBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQsIG9wdHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkT3JOdWxsKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAoeCkge1xuICBpZiAoIXggfHwgdHlwZW9mIHggIT09ICdvYmplY3QnIHx8IHR5cGVvZiB4Lmxlbmd0aCAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiB4LmNvcHkgIT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHguc2xpY2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHgubGVuZ3RoID4gMCAmJiB0eXBlb2YgeFswXSAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIsIG9wdHMpIHtcbiAgdmFyIGksIGtleTtcbiAgaWYgKGlzVW5kZWZpbmVkT3JOdWxsKGEpIHx8IGlzVW5kZWZpbmVkT3JOdWxsKGIpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LlxuICBpZiAoYS5wcm90b3R5cGUgIT09IGIucHJvdG90eXBlKSByZXR1cm4gZmFsc2U7XG4gIC8vfn5+SSd2ZSBtYW5hZ2VkIHRvIGJyZWFrIE9iamVjdC5rZXlzIHRocm91Z2ggc2NyZXd5IGFyZ3VtZW50cyBwYXNzaW5nLlxuICAvLyAgIENvbnZlcnRpbmcgdG8gYXJyYXkgc29sdmVzIHRoZSBwcm9ibGVtLlxuICBpZiAoaXNBcmd1bWVudHMoYSkpIHtcbiAgICBpZiAoIWlzQXJndW1lbnRzKGIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGEgPSBwU2xpY2UuY2FsbChhKTtcbiAgICBiID0gcFNsaWNlLmNhbGwoYik7XG4gICAgcmV0dXJuIGRlZXBFcXVhbChhLCBiLCBvcHRzKTtcbiAgfVxuICBpZiAoaXNCdWZmZXIoYSkpIHtcbiAgICBpZiAoIWlzQnVmZmVyKGIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFbaV0gIT09IGJbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdHJ5IHtcbiAgICB2YXIga2EgPSBvYmplY3RLZXlzKGEpLFxuICAgICAgICBrYiA9IG9iamVjdEtleXMoYik7XG4gIH0gY2F0Y2ggKGUpIHsvL2hhcHBlbnMgd2hlbiBvbmUgaXMgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgdGhlIG90aGVyIGlzbid0XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIWRlZXBFcXVhbChhW2tleV0sIGJba2V5XSwgb3B0cykpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHlwZW9mIGEgPT09IHR5cGVvZiBiO1xufVxuIiwidmFyIHN1cHBvcnRzQXJndW1lbnRzQ2xhc3MgPSAoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmd1bWVudHMpXG59KSgpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBzdXBwb3J0c0FyZ3VtZW50c0NsYXNzID8gc3VwcG9ydGVkIDogdW5zdXBwb3J0ZWQ7XG5cbmV4cG9ydHMuc3VwcG9ydGVkID0gc3VwcG9ydGVkO1xuZnVuY3Rpb24gc3VwcG9ydGVkKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59O1xuXG5leHBvcnRzLnVuc3VwcG9ydGVkID0gdW5zdXBwb3J0ZWQ7XG5mdW5jdGlvbiB1bnN1cHBvcnRlZChvYmplY3Qpe1xuICByZXR1cm4gb2JqZWN0ICYmXG4gICAgdHlwZW9mIG9iamVjdCA9PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBvYmplY3QubGVuZ3RoID09ICdudW1iZXInICYmXG4gICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ2NhbGxlZScpICYmXG4gICAgIU9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChvYmplY3QsICdjYWxsZWUnKSB8fFxuICAgIGZhbHNlO1xufTtcbiIsImV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiBPYmplY3Qua2V5cyA9PT0gJ2Z1bmN0aW9uJ1xuICA/IE9iamVjdC5rZXlzIDogc2hpbTtcblxuZXhwb3J0cy5zaGltID0gc2hpbTtcbmZ1bmN0aW9uIHNoaW0gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSBrZXlzLnB1c2goa2V5KTtcbiAgcmV0dXJuIGtleXM7XG59XG4iLCJ2YXIgYXNzZXJ0ID0gcmVxdWlyZSgnYXNzZXJ0JylcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnYmlnaScpXG5cbnZhciBQb2ludCA9IHJlcXVpcmUoJy4vcG9pbnQnKVxuXG5mdW5jdGlvbiBDdXJ2ZSAocCwgYSwgYiwgR3gsIEd5LCBuLCBoKSB7XG4gIHRoaXMucCA9IHBcbiAgdGhpcy5hID0gYVxuICB0aGlzLmIgPSBiXG4gIHRoaXMuRyA9IFBvaW50LmZyb21BZmZpbmUodGhpcywgR3gsIEd5KVxuICB0aGlzLm4gPSBuXG4gIHRoaXMuaCA9IGhcblxuICB0aGlzLmluZmluaXR5ID0gbmV3IFBvaW50KHRoaXMsIG51bGwsIG51bGwsIEJpZ0ludGVnZXIuWkVSTylcblxuICAvLyByZXN1bHQgY2FjaGluZ1xuICB0aGlzLnBPdmVyRm91ciA9IHAuYWRkKEJpZ0ludGVnZXIuT05FKS5zaGlmdFJpZ2h0KDIpXG5cbiAgLy8gZGV0ZXJtaW5lIHNpemUgb2YgcCBpbiBieXRlc1xuICB0aGlzLnBMZW5ndGggPSBNYXRoLmZsb29yKCh0aGlzLnAuYml0TGVuZ3RoKCkgKyA3KSAvIDgpXG59XG5cbkN1cnZlLnByb3RvdHlwZS5wb2ludEZyb21YID0gZnVuY3Rpb24gKGlzT2RkLCB4KSB7XG4gIHZhciBhbHBoYSA9IHgucG93KDMpLmFkZCh0aGlzLmEubXVsdGlwbHkoeCkpLmFkZCh0aGlzLmIpLm1vZCh0aGlzLnApXG4gIHZhciBiZXRhID0gYWxwaGEubW9kUG93KHRoaXMucE92ZXJGb3VyLCB0aGlzLnApIC8vIFhYWDogbm90IGNvbXBhdGlibGUgd2l0aCBhbGwgY3VydmVzXG5cbiAgdmFyIHkgPSBiZXRhXG4gIGlmIChiZXRhLmlzRXZlbigpIF4gIWlzT2RkKSB7XG4gICAgeSA9IHRoaXMucC5zdWJ0cmFjdCh5KSAvLyAteSAlIHBcbiAgfVxuXG4gIHJldHVybiBQb2ludC5mcm9tQWZmaW5lKHRoaXMsIHgsIHkpXG59XG5cbkN1cnZlLnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gKFEpIHtcbiAgaWYgKFEgPT09IHRoaXMuaW5maW5pdHkpIHJldHVybiB0cnVlXG5cbiAgcmV0dXJuIFEuei5zaWdudW0oKSA9PT0gMCAmJiBRLnkuc2lnbnVtKCkgIT09IDBcbn1cblxuQ3VydmUucHJvdG90eXBlLmlzT25DdXJ2ZSA9IGZ1bmN0aW9uIChRKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoUSkpIHJldHVybiB0cnVlXG5cbiAgdmFyIHggPSBRLmFmZmluZVhcbiAgdmFyIHkgPSBRLmFmZmluZVlcbiAgdmFyIGEgPSB0aGlzLmFcbiAgdmFyIGIgPSB0aGlzLmJcbiAgdmFyIHAgPSB0aGlzLnBcblxuICAvLyBDaGVjayB0aGF0IHhRIGFuZCB5USBhcmUgaW50ZWdlcnMgaW4gdGhlIGludGVydmFsIFswLCBwIC0gMV1cbiAgaWYgKHguc2lnbnVtKCkgPCAwIHx8IHguY29tcGFyZVRvKHApID49IDApIHJldHVybiBmYWxzZVxuICBpZiAoeS5zaWdudW0oKSA8IDAgfHwgeS5jb21wYXJlVG8ocCkgPj0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgLy8gYW5kIGNoZWNrIHRoYXQgeV4yID0geF4zICsgYXggKyBiIChtb2QgcClcbiAgdmFyIGxocyA9IHkuc3F1YXJlKCkubW9kKHApXG4gIHZhciByaHMgPSB4LnBvdygzKS5hZGQoYS5tdWx0aXBseSh4KSkuYWRkKGIpLm1vZChwKVxuICByZXR1cm4gbGhzLmVxdWFscyhyaHMpXG59XG5cbi8qKlxuICogVmFsaWRhdGUgYW4gZWxsaXB0aWMgY3VydmUgcG9pbnQuXG4gKlxuICogU2VlIFNFQyAxLCBzZWN0aW9uIDMuMi4yLjE6IEVsbGlwdGljIEN1cnZlIFB1YmxpYyBLZXkgVmFsaWRhdGlvbiBQcmltaXRpdmVcbiAqL1xuQ3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gKFEpIHtcbiAgLy8gQ2hlY2sgUSAhPSBPXG4gIGFzc2VydCghdGhpcy5pc0luZmluaXR5KFEpLCAnUG9pbnQgaXMgYXQgaW5maW5pdHknKVxuICBhc3NlcnQodGhpcy5pc09uQ3VydmUoUSksICdQb2ludCBpcyBub3Qgb24gdGhlIGN1cnZlJylcblxuICAvLyBDaGVjayBuUSA9IE8gKHdoZXJlIFEgaXMgYSBzY2FsYXIgbXVsdGlwbGUgb2YgRylcbiAgdmFyIG5RID0gUS5tdWx0aXBseSh0aGlzLm4pXG4gIGFzc2VydCh0aGlzLmlzSW5maW5pdHkoblEpLCAnUG9pbnQgaXMgbm90IGEgc2NhbGFyIG11bHRpcGxlIG9mIEcnKVxuXG4gIHJldHVybiB0cnVlXG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ3VydmVcbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJzZWNwMTI4cjFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZkZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXCIsXG4gICAgXCJhXCI6IFwiZmZmZmZmZmRmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNcIixcbiAgICBcImJcIjogXCJlODc1NzljMTEwNzlmNDNkZDgyNDk5M2MyY2VlNWVkM1wiLFxuICAgIFwiblwiOiBcImZmZmZmZmZlMDAwMDAwMDA3NWEzMGQxYjkwMzhhMTE1XCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiMTYxZmY3NTI4Yjg5OWIyZDBjMjg2MDdjYTUyYzViODZcIixcbiAgICBcIkd5XCI6IFwiY2Y1YWM4Mzk1YmFmZWIxM2MwMmRhMjkyZGRlZDdhODNcIlxuICB9LFxuICBcInNlY3AxNjBrMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmYWM3M1wiLFxuICAgIFwiYVwiOiBcIjAwXCIsXG4gICAgXCJiXCI6IFwiMDdcIixcbiAgICBcIm5cIjogXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxYjhmYTE2ZGZhYjlhY2ExNmI2YjNcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCIzYjRjMzgyY2UzN2FhMTkyYTQwMTllNzYzMDM2ZjRmNWRkNGQ3ZWJiXCIsXG4gICAgXCJHeVwiOiBcIjkzOGNmOTM1MzE4ZmRjZWQ2YmMyODI4NjUzMTczM2MzZjAzYzRmZWVcIlxuICB9LFxuICBcInNlY3AxNjByMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY3ZmZmZmZmZlwiLFxuICAgIFwiYVwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmN2ZmZmZmZmNcIixcbiAgICBcImJcIjogXCIxYzk3YmVmYzU0YmQ3YThiNjVhY2Y4OWY4MWQ0ZDRhZGM1NjVmYTQ1XCIsXG4gICAgXCJuXCI6IFwiMDEwMDAwMDAwMDAwMDAwMDAwMDAwMWY0YzhmOTI3YWVkM2NhNzUyMjU3XCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiNGE5NmI1Njg4ZWY1NzMyODQ2NjQ2OTg5NjhjMzhiYjkxM2NiZmM4MlwiLFxuICAgIFwiR3lcIjogXCIyM2E2Mjg1NTMxNjg5NDdkNTlkY2M5MTIwNDIzNTEzNzdhYzVmYjMyXCJcbiAgfSxcbiAgXCJzZWNwMTkyazFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZWUzN1wiLFxuICAgIFwiYVwiOiBcIjAwXCIsXG4gICAgXCJiXCI6IFwiMDNcIixcbiAgICBcIm5cIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmUyNmYyZmMxNzBmNjk0NjZhNzRkZWZkOGRcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCJkYjRmZjEwZWMwNTdlOWFlMjZiMDdkMDI4MGI3ZjQzNDFkYTVkMWIxZWFlMDZjN2RcIixcbiAgICBcIkd5XCI6IFwiOWIyZjJmNmQ5YzU2MjhhNzg0NDE2M2QwMTViZTg2MzQ0MDgyYWE4OGQ5NWUyZjlkXCJcbiAgfSxcbiAgXCJzZWNwMTkycjFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmZlwiLFxuICAgIFwiYVwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmY1wiLFxuICAgIFwiYlwiOiBcIjY0MjEwNTE5ZTU5YzgwZTcwZmE3ZTlhYjcyMjQzMDQ5ZmViOGRlZWNjMTQ2YjliMVwiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjk5ZGVmODM2MTQ2YmM5YjFiNGQyMjgzMVwiLFxuICAgIFwiaFwiOiBcIjAxXCIsXG4gICAgXCJHeFwiOiBcIjE4OGRhODBlYjAzMDkwZjY3Y2JmMjBlYjQzYTE4ODAwZjRmZjBhZmQ4MmZmMTAxMlwiLFxuICAgIFwiR3lcIjogXCIwNzE5MmI5NWZmYzhkYTc4NjMxMDExZWQ2YjI0Y2RkNTczZjk3N2ExMWU3OTQ4MTFcIlxuICB9LFxuICBcInNlY3AyNTZrMVwiOiB7XG4gICAgXCJwXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmMyZlwiLFxuICAgIFwiYVwiOiBcIjAwXCIsXG4gICAgXCJiXCI6IFwiMDdcIixcbiAgICBcIm5cIjogXCJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWJhYWVkY2U2YWY0OGEwM2JiZmQyNWU4Y2QwMzY0MTQxXCIsXG4gICAgXCJoXCI6IFwiMDFcIixcbiAgICBcIkd4XCI6IFwiNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OFwiLFxuICAgIFwiR3lcIjogXCI0ODNhZGE3NzI2YTNjNDY1NWRhNGZiZmMwZTExMDhhOGZkMTdiNDQ4YTY4NTU0MTk5YzQ3ZDA4ZmZiMTBkNGI4XCJcbiAgfSxcbiAgXCJzZWNwMjU2cjFcIjoge1xuICAgIFwicFwiOiBcImZmZmZmZmZmMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZcIixcbiAgICBcImFcIjogXCJmZmZmZmZmZjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjXCIsXG4gICAgXCJiXCI6IFwiNWFjNjM1ZDhhYTNhOTNlN2IzZWJiZDU1NzY5ODg2YmM2NTFkMDZiMGNjNTNiMGY2M2JjZTNjM2UyN2QyNjA0YlwiLFxuICAgIFwiblwiOiBcImZmZmZmZmZmMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmYmNlNmZhYWRhNzE3OWU4NGYzYjljYWMyZmM2MzI1NTFcIixcbiAgICBcImhcIjogXCIwMVwiLFxuICAgIFwiR3hcIjogXCI2YjE3ZDFmMmUxMmM0MjQ3ZjhiY2U2ZTU2M2E0NDBmMjc3MDM3ZDgxMmRlYjMzYTBmNGExMzk0NWQ4OThjMjk2XCIsXG4gICAgXCJHeVwiOiBcIjRmZTM0MmUyZmUxYTdmOWI4ZWU3ZWI0YTdjMGY5ZTE2MmJjZTMzNTc2YjMxNWVjZWNiYjY0MDY4MzdiZjUxZjVcIlxuICB9XG59XG4iLCJ2YXIgUG9pbnQgPSByZXF1aXJlKCcuL3BvaW50JylcbnZhciBDdXJ2ZSA9IHJlcXVpcmUoJy4vY3VydmUnKVxuXG52YXIgZ2V0Q3VydmVCeU5hbWUgPSByZXF1aXJlKCcuL25hbWVzJylcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIEN1cnZlOiBDdXJ2ZSxcbiAgUG9pbnQ6IFBvaW50LFxuICBnZXRDdXJ2ZUJ5TmFtZTogZ2V0Q3VydmVCeU5hbWVcbn1cbiIsInZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnYmlnaScpXG5cbnZhciBjdXJ2ZXMgPSByZXF1aXJlKCcuL2N1cnZlcy5qc29uJylcbnZhciBDdXJ2ZSA9IHJlcXVpcmUoJy4vY3VydmUnKVxuXG5mdW5jdGlvbiBnZXRDdXJ2ZUJ5TmFtZSAobmFtZSkge1xuICB2YXIgY3VydmUgPSBjdXJ2ZXNbbmFtZV1cbiAgaWYgKCFjdXJ2ZSkgcmV0dXJuIG51bGxcblxuICB2YXIgcCA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLnAsIDE2KVxuICB2YXIgYSA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLmEsIDE2KVxuICB2YXIgYiA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLmIsIDE2KVxuICB2YXIgbiA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLm4sIDE2KVxuICB2YXIgaCA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLmgsIDE2KVxuICB2YXIgR3ggPSBuZXcgQmlnSW50ZWdlcihjdXJ2ZS5HeCwgMTYpXG4gIHZhciBHeSA9IG5ldyBCaWdJbnRlZ2VyKGN1cnZlLkd5LCAxNilcblxuICByZXR1cm4gbmV3IEN1cnZlKHAsIGEsIGIsIEd4LCBHeSwgbiwgaClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRDdXJ2ZUJ5TmFtZVxuIiwidmFyIGFzc2VydCA9IHJlcXVpcmUoJ2Fzc2VydCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnYmlnaScpXG5cbnZhciBUSFJFRSA9IEJpZ0ludGVnZXIudmFsdWVPZigzKVxuXG5mdW5jdGlvbiBQb2ludCAoY3VydmUsIHgsIHksIHopIHtcbiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKHosIHVuZGVmaW5lZCwgJ01pc3NpbmcgWiBjb29yZGluYXRlJylcblxuICB0aGlzLmN1cnZlID0gY3VydmVcbiAgdGhpcy54ID0geFxuICB0aGlzLnkgPSB5XG4gIHRoaXMueiA9IHpcbiAgdGhpcy5fekludiA9IG51bGxcblxuICB0aGlzLmNvbXByZXNzZWQgPSB0cnVlXG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShQb2ludC5wcm90b3R5cGUsICd6SW52Jywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5fekludiA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fekludiA9IHRoaXMuei5tb2RJbnZlcnNlKHRoaXMuY3VydmUucClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fekludlxuICB9XG59KVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoUG9pbnQucHJvdG90eXBlLCAnYWZmaW5lWCcsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMueC5tdWx0aXBseSh0aGlzLnpJbnYpLm1vZCh0aGlzLmN1cnZlLnApXG4gIH1cbn0pXG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShQb2ludC5wcm90b3R5cGUsICdhZmZpbmVZJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy55Lm11bHRpcGx5KHRoaXMuekludikubW9kKHRoaXMuY3VydmUucClcbiAgfVxufSlcblxuUG9pbnQuZnJvbUFmZmluZSA9IGZ1bmN0aW9uIChjdXJ2ZSwgeCwgeSkge1xuICByZXR1cm4gbmV3IFBvaW50KGN1cnZlLCB4LCB5LCBCaWdJbnRlZ2VyLk9ORSlcbn1cblxuUG9pbnQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAob3RoZXIgPT09IHRoaXMpIHJldHVybiB0cnVlXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiB0aGlzLmN1cnZlLmlzSW5maW5pdHkob3RoZXIpXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkob3RoZXIpKSByZXR1cm4gdGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpXG5cbiAgLy8gdSA9IFkyICogWjEgLSBZMSAqIFoyXG4gIHZhciB1ID0gb3RoZXIueS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueS5tdWx0aXBseShvdGhlci56KSkubW9kKHRoaXMuY3VydmUucClcblxuICBpZiAodS5zaWdudW0oKSAhPT0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgLy8gdiA9IFgyICogWjEgLSBYMSAqIFoyXG4gIHZhciB2ID0gb3RoZXIueC5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueC5tdWx0aXBseShvdGhlci56KSkubW9kKHRoaXMuY3VydmUucClcblxuICByZXR1cm4gdi5zaWdudW0oKSA9PT0gMFxufVxuXG5Qb2ludC5wcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgeSA9IHRoaXMuY3VydmUucC5zdWJ0cmFjdCh0aGlzLnkpXG5cbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLmN1cnZlLCB0aGlzLngsIHksIHRoaXMueilcbn1cblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChiKSB7XG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkodGhpcykpIHJldHVybiBiXG4gIGlmICh0aGlzLmN1cnZlLmlzSW5maW5pdHkoYikpIHJldHVybiB0aGlzXG5cbiAgdmFyIHgxID0gdGhpcy54XG4gIHZhciB5MSA9IHRoaXMueVxuICB2YXIgeDIgPSBiLnhcbiAgdmFyIHkyID0gYi55XG5cbiAgLy8gdSA9IFkyICogWjEgLSBZMSAqIFoyXG4gIHZhciB1ID0geTIubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh5MS5tdWx0aXBseShiLnopKS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB2ID0gWDIgKiBaMSAtIFgxICogWjJcbiAgdmFyIHYgPSB4Mi5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHgxLm11bHRpcGx5KGIueikpLm1vZCh0aGlzLmN1cnZlLnApXG5cbiAgaWYgKHYuc2lnbnVtKCkgPT09IDApIHtcbiAgICBpZiAodS5zaWdudW0oKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMudHdpY2UoKSAvLyB0aGlzID09IGIsIHNvIGRvdWJsZVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmN1cnZlLmluZmluaXR5IC8vIHRoaXMgPSAtYiwgc28gaW5maW5pdHlcbiAgfVxuXG4gIHZhciB2MiA9IHYuc3F1YXJlKClcbiAgdmFyIHYzID0gdjIubXVsdGlwbHkodilcbiAgdmFyIHgxdjIgPSB4MS5tdWx0aXBseSh2MilcbiAgdmFyIHp1MiA9IHUuc3F1YXJlKCkubXVsdGlwbHkodGhpcy56KVxuXG4gIC8vIHgzID0gdiAqICh6MiAqICh6MSAqIHVeMiAtIDIgKiB4MSAqIHZeMikgLSB2XjMpXG4gIHZhciB4MyA9IHp1Mi5zdWJ0cmFjdCh4MXYyLnNoaWZ0TGVmdCgxKSkubXVsdGlwbHkoYi56KS5zdWJ0cmFjdCh2MykubXVsdGlwbHkodikubW9kKHRoaXMuY3VydmUucClcbiAgLy8geTMgPSB6MiAqICgzICogeDEgKiB1ICogdl4yIC0geTEgKiB2XjMgLSB6MSAqIHVeMykgKyB1ICogdl4zXG4gIHZhciB5MyA9IHgxdjIubXVsdGlwbHkoVEhSRUUpLm11bHRpcGx5KHUpLnN1YnRyYWN0KHkxLm11bHRpcGx5KHYzKSkuc3VidHJhY3QoenUyLm11bHRpcGx5KHUpKS5tdWx0aXBseShiLnopLmFkZCh1Lm11bHRpcGx5KHYzKSkubW9kKHRoaXMuY3VydmUucClcbiAgLy8gejMgPSB2XjMgKiB6MSAqIHoyXG4gIHZhciB6MyA9IHYzLm11bHRpcGx5KHRoaXMueikubXVsdGlwbHkoYi56KS5tb2QodGhpcy5jdXJ2ZS5wKVxuXG4gIHJldHVybiBuZXcgUG9pbnQodGhpcy5jdXJ2ZSwgeDMsIHkzLCB6Mylcbn1cblxuUG9pbnQucHJvdG90eXBlLnR3aWNlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gdGhpc1xuICBpZiAodGhpcy55LnNpZ251bSgpID09PSAwKSByZXR1cm4gdGhpcy5jdXJ2ZS5pbmZpbml0eVxuXG4gIHZhciB4MSA9IHRoaXMueFxuICB2YXIgeTEgPSB0aGlzLnlcblxuICB2YXIgeTF6MSA9IHkxLm11bHRpcGx5KHRoaXMueikubW9kKHRoaXMuY3VydmUucClcbiAgdmFyIHkxc3F6MSA9IHkxejEubXVsdGlwbHkoeTEpLm1vZCh0aGlzLmN1cnZlLnApXG4gIHZhciBhID0gdGhpcy5jdXJ2ZS5hXG5cbiAgLy8gdyA9IDMgKiB4MV4yICsgYSAqIHoxXjJcbiAgdmFyIHcgPSB4MS5zcXVhcmUoKS5tdWx0aXBseShUSFJFRSlcblxuICBpZiAoYS5zaWdudW0oKSAhPT0gMCkge1xuICAgIHcgPSB3LmFkZCh0aGlzLnouc3F1YXJlKCkubXVsdGlwbHkoYSkpXG4gIH1cblxuICB3ID0gdy5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB4MyA9IDIgKiB5MSAqIHoxICogKHdeMiAtIDggKiB4MSAqIHkxXjIgKiB6MSlcbiAgdmFyIHgzID0gdy5zcXVhcmUoKS5zdWJ0cmFjdCh4MS5zaGlmdExlZnQoMykubXVsdGlwbHkoeTFzcXoxKSkuc2hpZnRMZWZ0KDEpLm11bHRpcGx5KHkxejEpLm1vZCh0aGlzLmN1cnZlLnApXG4gIC8vIHkzID0gNCAqIHkxXjIgKiB6MSAqICgzICogdyAqIHgxIC0gMiAqIHkxXjIgKiB6MSkgLSB3XjNcbiAgdmFyIHkzID0gdy5tdWx0aXBseShUSFJFRSkubXVsdGlwbHkoeDEpLnN1YnRyYWN0KHkxc3F6MS5zaGlmdExlZnQoMSkpLnNoaWZ0TGVmdCgyKS5tdWx0aXBseSh5MXNxejEpLnN1YnRyYWN0KHcucG93KDMpKS5tb2QodGhpcy5jdXJ2ZS5wKVxuICAvLyB6MyA9IDggKiAoeTEgKiB6MSleM1xuICB2YXIgejMgPSB5MXoxLnBvdygzKS5zaGlmdExlZnQoMykubW9kKHRoaXMuY3VydmUucClcblxuICByZXR1cm4gbmV3IFBvaW50KHRoaXMuY3VydmUsIHgzLCB5MywgejMpXG59XG5cbi8vIFNpbXBsZSBOQUYgKE5vbi1BZGphY2VudCBGb3JtKSBtdWx0aXBsaWNhdGlvbiBhbGdvcml0aG1cbi8vIFRPRE86IG1vZHVsYXJpemUgdGhlIG11bHRpcGxpY2F0aW9uIGFsZ29yaXRobVxuUG9pbnQucHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gKGspIHtcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuIHRoaXNcbiAgaWYgKGsuc2lnbnVtKCkgPT09IDApIHJldHVybiB0aGlzLmN1cnZlLmluZmluaXR5XG5cbiAgdmFyIGUgPSBrXG4gIHZhciBoID0gZS5tdWx0aXBseShUSFJFRSlcblxuICB2YXIgbmVnID0gdGhpcy5uZWdhdGUoKVxuICB2YXIgUiA9IHRoaXNcblxuICBmb3IgKHZhciBpID0gaC5iaXRMZW5ndGgoKSAtIDI7IGkgPiAwOyAtLWkpIHtcbiAgICB2YXIgaEJpdCA9IGgudGVzdEJpdChpKVxuICAgIHZhciBlQml0ID0gZS50ZXN0Qml0KGkpXG5cbiAgICBSID0gUi50d2ljZSgpXG5cbiAgICBpZiAoaEJpdCAhPT0gZUJpdCkge1xuICAgICAgUiA9IFIuYWRkKGhCaXQgPyB0aGlzIDogbmVnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBSXG59XG5cbi8vIENvbXB1dGUgdGhpcypqICsgeCprIChzaW11bHRhbmVvdXMgbXVsdGlwbGljYXRpb24pXG5Qb2ludC5wcm90b3R5cGUubXVsdGlwbHlUd28gPSBmdW5jdGlvbiAoaiwgeCwgaykge1xuICB2YXIgaSA9IE1hdGgubWF4KGouYml0TGVuZ3RoKCksIGsuYml0TGVuZ3RoKCkpIC0gMVxuICB2YXIgUiA9IHRoaXMuY3VydmUuaW5maW5pdHlcbiAgdmFyIGJvdGggPSB0aGlzLmFkZCh4KVxuXG4gIHdoaWxlIChpID49IDApIHtcbiAgICB2YXIgakJpdCA9IGoudGVzdEJpdChpKVxuICAgIHZhciBrQml0ID0gay50ZXN0Qml0KGkpXG5cbiAgICBSID0gUi50d2ljZSgpXG5cbiAgICBpZiAoakJpdCkge1xuICAgICAgaWYgKGtCaXQpIHtcbiAgICAgICAgUiA9IFIuYWRkKGJvdGgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBSID0gUi5hZGQodGhpcylcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGtCaXQpIHtcbiAgICAgIFIgPSBSLmFkZCh4KVxuICAgIH1cbiAgICAtLWlcbiAgfVxuXG4gIHJldHVybiBSXG59XG5cblBvaW50LnByb3RvdHlwZS5nZXRFbmNvZGVkID0gZnVuY3Rpb24gKGNvbXByZXNzZWQpIHtcbiAgaWYgKGNvbXByZXNzZWQgPT0gbnVsbCkgY29tcHJlc3NlZCA9IHRoaXMuY29tcHJlc3NlZFxuICBpZiAodGhpcy5jdXJ2ZS5pc0luZmluaXR5KHRoaXMpKSByZXR1cm4gQnVmZmVyLmFsbG9jKDEsIDApIC8vIEluZmluaXR5IHBvaW50IGVuY29kZWQgaXMgc2ltcGx5ICcwMCdcblxuICB2YXIgeCA9IHRoaXMuYWZmaW5lWFxuICB2YXIgeSA9IHRoaXMuYWZmaW5lWVxuICB2YXIgYnl0ZUxlbmd0aCA9IHRoaXMuY3VydmUucExlbmd0aFxuICB2YXIgYnVmZmVyXG5cbiAgLy8gMHgwMi8weDAzIHwgWFxuICBpZiAoY29tcHJlc3NlZCkge1xuICAgIGJ1ZmZlciA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgxICsgYnl0ZUxlbmd0aClcbiAgICBidWZmZXIud3JpdGVVSW50OCh5LmlzRXZlbigpID8gMHgwMiA6IDB4MDMsIDApXG5cbiAgLy8gMHgwNCB8IFggfCBZXG4gIH0gZWxzZSB7XG4gICAgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKDEgKyBieXRlTGVuZ3RoICsgYnl0ZUxlbmd0aClcbiAgICBidWZmZXIud3JpdGVVSW50OCgweDA0LCAwKVxuXG4gICAgeS50b0J1ZmZlcihieXRlTGVuZ3RoKS5jb3B5KGJ1ZmZlciwgMSArIGJ5dGVMZW5ndGgpXG4gIH1cblxuICB4LnRvQnVmZmVyKGJ5dGVMZW5ndGgpLmNvcHkoYnVmZmVyLCAxKVxuXG4gIHJldHVybiBidWZmZXJcbn1cblxuUG9pbnQuZGVjb2RlRnJvbSA9IGZ1bmN0aW9uIChjdXJ2ZSwgYnVmZmVyKSB7XG4gIHZhciB0eXBlID0gYnVmZmVyLnJlYWRVSW50OCgwKVxuICB2YXIgY29tcHJlc3NlZCA9ICh0eXBlICE9PSA0KVxuXG4gIHZhciBieXRlTGVuZ3RoID0gTWF0aC5mbG9vcigoY3VydmUucC5iaXRMZW5ndGgoKSArIDcpIC8gOClcbiAgdmFyIHggPSBCaWdJbnRlZ2VyLmZyb21CdWZmZXIoYnVmZmVyLnNsaWNlKDEsIDEgKyBieXRlTGVuZ3RoKSlcblxuICB2YXIgUVxuICBpZiAoY29tcHJlc3NlZCkge1xuICAgIGFzc2VydC5lcXVhbChidWZmZXIubGVuZ3RoLCBieXRlTGVuZ3RoICsgMSwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJylcbiAgICBhc3NlcnQodHlwZSA9PT0gMHgwMiB8fCB0eXBlID09PSAweDAzLCAnSW52YWxpZCBzZXF1ZW5jZSB0YWcnKVxuXG4gICAgdmFyIGlzT2RkID0gKHR5cGUgPT09IDB4MDMpXG4gICAgUSA9IGN1cnZlLnBvaW50RnJvbVgoaXNPZGQsIHgpXG4gIH0gZWxzZSB7XG4gICAgYXNzZXJ0LmVxdWFsKGJ1ZmZlci5sZW5ndGgsIDEgKyBieXRlTGVuZ3RoICsgYnl0ZUxlbmd0aCwgJ0ludmFsaWQgc2VxdWVuY2UgbGVuZ3RoJylcblxuICAgIHZhciB5ID0gQmlnSW50ZWdlci5mcm9tQnVmZmVyKGJ1ZmZlci5zbGljZSgxICsgYnl0ZUxlbmd0aCkpXG4gICAgUSA9IFBvaW50LmZyb21BZmZpbmUoY3VydmUsIHgsIHkpXG4gIH1cblxuICBRLmNvbXByZXNzZWQgPSBjb21wcmVzc2VkXG4gIHJldHVybiBRXG59XG5cblBvaW50LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY3VydmUuaXNJbmZpbml0eSh0aGlzKSkgcmV0dXJuICcoSU5GSU5JVFkpJ1xuXG4gIHJldHVybiAnKCcgKyB0aGlzLmFmZmluZVgudG9TdHJpbmcoKSArICcsJyArIHRoaXMuYWZmaW5lWS50b1N0cmluZygpICsgJyknXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUG9pbnRcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHZhciBldmxpc3RlbmVyO1xuICB2YXIgcmV0O1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmICghZXZlbnRzKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIHtcbiAgICBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICAgIGlmICghZXZsaXN0ZW5lcilcbiAgICAgIHJldCA9IFtdO1xuICAgIGVsc2UgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgICAgcmV0ID0gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl07XG4gICAgZWxzZVxuICAgICAgcmV0ID0gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiBIYXNoQmFzZSAoYmxvY2tTaXplKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMpXG5cbiAgdGhpcy5fYmxvY2sgPSBuZXcgQnVmZmVyKGJsb2NrU2l6ZSlcbiAgdGhpcy5fYmxvY2tTaXplID0gYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB0aGlzLl9sZW5ndGggPSBbMCwgMCwgMCwgMF1cblxuICB0aGlzLl9maW5hbGl6ZWQgPSBmYWxzZVxufVxuXG5pbmhlcml0cyhIYXNoQmFzZSwgVHJhbnNmb3JtKVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIHZhciBlcnJvciA9IG51bGxcbiAgdHJ5IHtcbiAgICBpZiAoZW5jb2RpbmcgIT09ICdidWZmZXInKSBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKVxuICAgIHRoaXMudXBkYXRlKGNodW5rKVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvciA9IGVyclxuICB9XG5cbiAgY2FsbGJhY2soZXJyb3IpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fZmx1c2ggPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgdmFyIGVycm9yID0gbnVsbFxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9kaWdlc3QoKSlcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IgPSBlcnJcbiAgfVxuXG4gIGNhbGxiYWNrKGVycm9yKVxufVxuXG5IYXNoQmFzZS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGVuY29kaW5nKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGRhdGEpICYmIHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJykgdGhyb3cgbmV3IFR5cGVFcnJvcignRGF0YSBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgYnVmZmVyJylcbiAgaWYgKHRoaXMuX2ZpbmFsaXplZCkgdGhyb3cgbmV3IEVycm9yKCdEaWdlc3QgYWxyZWFkeSBjYWxsZWQnKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jb2RpbmcgfHwgJ2JpbmFyeScpXG5cbiAgLy8gY29uc3VtZSBkYXRhXG4gIHZhciBibG9jayA9IHRoaXMuX2Jsb2NrXG4gIHZhciBvZmZzZXQgPSAwXG4gIHdoaWxlICh0aGlzLl9ibG9ja09mZnNldCArIGRhdGEubGVuZ3RoIC0gb2Zmc2V0ID49IHRoaXMuX2Jsb2NrU2l6ZSkge1xuICAgIGZvciAodmFyIGkgPSB0aGlzLl9ibG9ja09mZnNldDsgaSA8IHRoaXMuX2Jsb2NrU2l6ZTspIGJsb2NrW2krK10gPSBkYXRhW29mZnNldCsrXVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cbiAgd2hpbGUgKG9mZnNldCA8IGRhdGEubGVuZ3RoKSBibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IGRhdGFbb2Zmc2V0KytdXG5cbiAgLy8gdXBkYXRlIGxlbmd0aFxuICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSBkYXRhLmxlbmd0aCAqIDg7IGNhcnJ5ID4gMDsgKytqKSB7XG4gICAgdGhpcy5fbGVuZ3RoW2pdICs9IGNhcnJ5XG4gICAgY2FycnkgPSAodGhpcy5fbGVuZ3RoW2pdIC8gMHgwMTAwMDAwMDAwKSB8IDBcbiAgICBpZiAoY2FycnkgPiAwKSB0aGlzLl9sZW5ndGhbal0gLT0gMHgwMTAwMDAwMDAwICogY2FycnlcbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIGlzIG5vdCBpbXBsZW1lbnRlZCcpXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5kaWdlc3QgPSBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgaWYgKHRoaXMuX2ZpbmFsaXplZCkgdGhyb3cgbmV3IEVycm9yKCdEaWdlc3QgYWxyZWFkeSBjYWxsZWQnKVxuICB0aGlzLl9maW5hbGl6ZWQgPSB0cnVlXG5cbiAgdmFyIGRpZ2VzdCA9IHRoaXMuX2RpZ2VzdCgpXG4gIGlmIChlbmNvZGluZyAhPT0gdW5kZWZpbmVkKSBkaWdlc3QgPSBkaWdlc3QudG9TdHJpbmcoZW5jb2RpbmcpXG4gIHJldHVybiBkaWdlc3Rcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX2RpZ2VzdCBpcyBub3QgaW1wbGVtZW50ZWQnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hCYXNlXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cbiIsIi8qIVxuICogRGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBhIEJ1ZmZlclxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbi8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3Npbmdcbi8vIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHlcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgKGlzQnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikgfHwgISFvYmouX2lzQnVmZmVyKVxufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAob2JqKSB7XG4gIHJldHVybiAhIW9iai5jb25zdHJ1Y3RvciAmJiB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopXG59XG5cbi8vIEZvciBOb2RlIHYwLjEwIHN1cHBvcnQuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHkuXG5mdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLnNsaWNlID09PSAnZnVuY3Rpb24nICYmIGlzQnVmZmVyKG9iai5zbGljZSgwLCAwKSlcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiLypcclxuIENvcHlyaWdodCAyMDEzIERhbmllbCBXaXJ0eiA8ZGNvZGVAZGNvZGUuaW8+XHJcbiBDb3B5cmlnaHQgMjAwOSBUaGUgQ2xvc3VyZSBMaWJyYXJ5IEF1dGhvcnMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcblxyXG4gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcclxuIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cclxuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxyXG5cclxuIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcclxuIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMtSVNcIiBCQVNJUyxcclxuIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxyXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxyXG4gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBsaWNlbnNlIGxvbmcuanMgKGMpIDIwMTMgRGFuaWVsIFdpcnR6IDxkY29kZUBkY29kZS5pbz5cclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMFxyXG4gKiBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY29kZUlPL2xvbmcuanMgZm9yIGRldGFpbHNcclxuICovXHJcbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcclxuXHJcbiAgICAvKiBBTUQgKi8gaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lW1wiYW1kXCJdKVxyXG4gICAgICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XHJcbiAgICAvKiBDb21tb25KUyAqLyBlbHNlIGlmICh0eXBlb2YgcmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIG1vZHVsZSAmJiBtb2R1bGVbXCJleHBvcnRzXCJdKVxyXG4gICAgICAgIG1vZHVsZVtcImV4cG9ydHNcIl0gPSBmYWN0b3J5KCk7XHJcbiAgICAvKiBHbG9iYWwgKi8gZWxzZVxyXG4gICAgICAgIChnbG9iYWxbXCJkY29kZUlPXCJdID0gZ2xvYmFsW1wiZGNvZGVJT1wiXSB8fCB7fSlbXCJMb25nXCJdID0gZmFjdG9yeSgpO1xyXG5cclxufSkodGhpcywgZnVuY3Rpb24oKSB7XHJcbiAgICBcInVzZSBzdHJpY3RcIjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXHJcbiAgICAgKiAgU2VlIHRoZSBmcm9tKiBmdW5jdGlvbnMgYmVsb3cgZm9yIG1vcmUgY29udmVuaWVudCB3YXlzIG9mIGNvbnN0cnVjdGluZyBMb25ncy5cclxuICAgICAqIEBleHBvcnRzIExvbmdcclxuICAgICAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2ggVGhlIGhpZ2ggKHNpZ25lZCkgMzIgYml0cyBvZiB0aGUgbG9uZ1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgbG93IDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmxvdyA9IGxvdyB8IDA7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgdmFsdWUuXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmhpZ2ggPSBoaWdoIHwgMDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXHJcbiAgICAgICAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGhlIGludGVybmFsIHJlcHJlc2VudGF0aW9uIG9mIGEgbG9uZyBpcyB0aGUgdHdvIGdpdmVuIHNpZ25lZCwgMzItYml0IHZhbHVlcy5cclxuICAgIC8vIFdlIHVzZSAzMi1iaXQgcGllY2VzIGJlY2F1c2UgdGhlc2UgYXJlIHRoZSBzaXplIG9mIGludGVnZXJzIG9uIHdoaWNoXHJcbiAgICAvLyBKYXZhc2NyaXB0IHBlcmZvcm1zIGJpdC1vcGVyYXRpb25zLiAgRm9yIG9wZXJhdGlvbnMgbGlrZSBhZGRpdGlvbiBhbmRcclxuICAgIC8vIG11bHRpcGxpY2F0aW9uLCB3ZSBzcGxpdCBlYWNoIG51bWJlciBpbnRvIDE2IGJpdCBwaWVjZXMsIHdoaWNoIGNhbiBlYXNpbHkgYmVcclxuICAgIC8vIG11bHRpcGxpZWQgd2l0aGluIEphdmFzY3JpcHQncyBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiB3aXRob3V0IG92ZXJmbG93XHJcbiAgICAvLyBvciBjaGFuZ2UgaW4gc2lnbi5cclxuICAgIC8vXHJcbiAgICAvLyBJbiB0aGUgYWxnb3JpdGhtcyBiZWxvdywgd2UgZnJlcXVlbnRseSByZWR1Y2UgdGhlIG5lZ2F0aXZlIGNhc2UgdG8gdGhlXHJcbiAgICAvLyBwb3NpdGl2ZSBjYXNlIGJ5IG5lZ2F0aW5nIHRoZSBpbnB1dChzKSBhbmQgdGhlbiBwb3N0LXByb2Nlc3NpbmcgdGhlIHJlc3VsdC5cclxuICAgIC8vIE5vdGUgdGhhdCB3ZSBtdXN0IEFMV0FZUyBjaGVjayBzcGVjaWFsbHkgd2hldGhlciB0aG9zZSB2YWx1ZXMgYXJlIE1JTl9WQUxVRVxyXG4gICAgLy8gKC0yXjYzKSBiZWNhdXNlIC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFIChzaW5jZSAyXjYzIGNhbm5vdCBiZSByZXByZXNlbnRlZCBhc1xyXG4gICAgLy8gYSBwb3NpdGl2ZSBudW1iZXIsIGl0IG92ZXJmbG93cyBiYWNrIGludG8gYSBuZWdhdGl2ZSkuICBOb3QgaGFuZGxpbmcgdGhpc1xyXG4gICAgLy8gY2FzZSB3b3VsZCBvZnRlbiByZXN1bHQgaW4gaW5maW5pdGUgcmVjdXJzaW9uLlxyXG4gICAgLy9cclxuICAgIC8vIENvbW1vbiBjb25zdGFudCB2YWx1ZXMgWkVSTywgT05FLCBORUdfT05FLCBldGMuIGFyZSBkZWZpbmVkIGJlbG93IHRoZSBmcm9tKlxyXG4gICAgLy8gbWV0aG9kcyBvbiB3aGljaCB0aGV5IGRlcGVuZC5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFuIGluZGljYXRvciB1c2VkIHRvIHJlbGlhYmx5IGRldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBMb25nIG9yIG5vdC5cclxuICAgICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBMb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xyXG5cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMb25nLnByb3RvdHlwZSwgXCJfX2lzTG9uZ19fXCIsIHtcclxuICAgICAgICB2YWx1ZTogdHJ1ZSxcclxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlXHJcbiAgICB9KTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBpc0xvbmcob2JqKSB7XHJcbiAgICAgICAgcmV0dXJuIChvYmogJiYgb2JqW1wiX19pc0xvbmdfX1wiXSkgPT09IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGUgc3BlY2lmaWVkIG9iamVjdCBpcyBhIExvbmcuXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7Kn0gb2JqIE9iamVjdFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmcuaXNMb25nID0gaXNMb25nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgaW50ZWdlciB2YWx1ZXMuXHJcbiAgICAgKiBAdHlwZSB7IU9iamVjdH1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgSU5UX0NBQ0hFID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy5cclxuICAgICAqIEB0eXBlIHshT2JqZWN0fVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBVSU5UX0NBQ0hFID0ge307XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbUludCh2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgICAgICB2YXIgb2JqLCBjYWNoZWRPYmosIGNhY2hlO1xyXG4gICAgICAgIGlmICh1bnNpZ25lZCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA+Pj49IDA7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVkT2JqID0gVUlOVF9DQUNIRVt2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkT2JqKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb2JqID0gZnJvbUJpdHModmFsdWUsICh2YWx1ZSB8IDApIDwgMCA/IC0xIDogMCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgICAgIFVJTlRfQ0FDSEVbdmFsdWVdID0gb2JqO1xyXG4gICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlIHw9IDA7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSA9ICgtMTI4IDw9IHZhbHVlICYmIHZhbHVlIDwgMTI4KSkge1xyXG4gICAgICAgICAgICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgICAgIGlmIChjYWNoZWRPYmopXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlZE9iajtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvYmogPSBmcm9tQml0cyh2YWx1ZSwgdmFsdWUgPCAwID8gLTEgOiAwLCBmYWxzZSk7XHJcbiAgICAgICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgICAgIElOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiAzMiBiaXQgaW50ZWdlciB2YWx1ZS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSAzMiBiaXQgaW50ZWdlciBpbiBxdWVzdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbUludCA9IGZyb21JbnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgICAgICBpZiAoaXNOYU4odmFsdWUpIHx8ICFpc0Zpbml0ZSh2YWx1ZSkpXHJcbiAgICAgICAgICAgIHJldHVybiB1bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcclxuICAgICAgICBpZiAodW5zaWduZWQpIHtcclxuICAgICAgICAgICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICAgICAgICAgIHJldHVybiBVWkVSTztcclxuICAgICAgICAgICAgaWYgKHZhbHVlID49IFRXT19QV1JfNjRfREJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodmFsdWUgPD0gLVRXT19QV1JfNjNfREJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgICAgICAgICAgaWYgKHZhbHVlICsgMSA+PSBUV09fUFdSXzYzX0RCTClcclxuICAgICAgICAgICAgICAgIHJldHVybiBNQVhfVkFMVUU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh2YWx1ZSA8IDApXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tTnVtYmVyKC12YWx1ZSwgdW5zaWduZWQpLm5lZygpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygodmFsdWUgJSBUV09fUFdSXzMyX0RCTCkgfCAwLCAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLCB1bnNpZ25lZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIG51bWJlciBpbiBxdWVzdGlvblxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93Qml0c1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGZyb21CaXRzKGxvd0JpdHMsIGhpZ2hCaXRzLCB1bnNpZ25lZCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgTG9uZyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXHJcbiAgICAgKiAgYXNzdW1lZCB0byB1c2UgMzIgYml0cy5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGlnaEJpdHMgVGhlIGhpZ2ggMzIgYml0c1xyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIGBmYWxzZWAgZm9yIHNpZ25lZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbUJpdHMgPSBmcm9tQml0cztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJhc2VcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgcG93X2RibCA9IE1hdGgucG93OyAvLyBVc2VkIDQgdGltZXMgKDQqOCB0byAxNSs0KVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxyXG4gICAgICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXhcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgdW5zaWduZWQsIHJhZGl4KSB7XHJcbiAgICAgICAgaWYgKHN0ci5sZW5ndGggPT09IDApXHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdlbXB0eSBzdHJpbmcnKTtcclxuICAgICAgICBpZiAoc3RyID09PSBcIk5hTlwiIHx8IHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiLUluZmluaXR5XCIpXHJcbiAgICAgICAgICAgIHJldHVybiBaRVJPO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdW5zaWduZWQgPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgICAgIC8vIEZvciBnb29nLm1hdGgubG9uZyBjb21wYXRpYmlsaXR5XHJcbiAgICAgICAgICAgIHJhZGl4ID0gdW5zaWduZWQsXHJcbiAgICAgICAgICAgIHVuc2lnbmVkID0gZmFsc2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdW5zaWduZWQgPSAhISB1bnNpZ25lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmFkaXggPSByYWRpeCB8fCAxMDtcclxuICAgICAgICBpZiAocmFkaXggPCAyIHx8IDM2IDwgcmFkaXgpXHJcbiAgICAgICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcblxyXG4gICAgICAgIHZhciBwO1xyXG4gICAgICAgIGlmICgocCA9IHN0ci5pbmRleE9mKCctJykpID4gMClcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2ludGVyaW9yIGh5cGhlbicpO1xyXG4gICAgICAgIGVsc2UgaWYgKHAgPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21TdHJpbmcoc3RyLnN1YnN0cmluZygxKSwgdW5zaWduZWQsIHJhZGl4KS5uZWcoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgICAgICAvLyBtaW5pbWl6ZSB0aGUgY2FsbHMgdG8gdGhlIHZlcnkgZXhwZW5zaXZlIGVtdWxhdGVkIGRpdi5cclxuICAgICAgICB2YXIgcmFkaXhUb1Bvd2VyID0gZnJvbU51bWJlcihwb3dfZGJsKHJhZGl4LCA4KSk7XHJcblxyXG4gICAgICAgIHZhciByZXN1bHQgPSBaRVJPO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSArPSA4KSB7XHJcbiAgICAgICAgICAgIHZhciBzaXplID0gTWF0aC5taW4oOCwgc3RyLmxlbmd0aCAtIGkpLFxyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xyXG4gICAgICAgICAgICBpZiAoc2l6ZSA8IDgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBwb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgc2l6ZSkpO1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5tdWwocmFkaXhUb1Bvd2VyKTtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gc3RyaW5nLCB3cml0dGVuIHVzaW5nIHRoZSBzcGVjaWZpZWQgcmFkaXguXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcclxuICAgICAqIEBwYXJhbSB7KGJvb2xlYW58bnVtYmVyKT19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBgZmFsc2VgIGZvciBzaWduZWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gcmFkaXggVGhlIHJhZGl4IGluIHdoaWNoIHRoZSB0ZXh0IGlzIHdyaXR0ZW4gKDItMzYpLCBkZWZhdWx0cyB0byAxMFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIExvbmcuZnJvbVN0cmluZyA9IGZyb21TdHJpbmc7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCkge1xyXG4gICAgICAgIGlmICh2YWwgLyogaXMgY29tcGF0aWJsZSAqLyBpbnN0YW5jZW9mIExvbmcpXHJcbiAgICAgICAgICAgIHJldHVybiB2YWw7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcih2YWwpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJylcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21TdHJpbmcodmFsKTtcclxuICAgICAgICAvLyBUaHJvd3MgZm9yIG5vbi1vYmplY3RzLCBjb252ZXJ0cyBub24taW5zdGFuY2VvZiBMb25nOlxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh2YWwubG93LCB2YWwuaGlnaCwgdmFsLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBzcGVjaWZpZWQgdmFsdWUgdG8gYSBMb25nLlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbCBWYWx1ZVxyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLmZyb21WYWx1ZSA9IGZyb21WYWx1ZTtcclxuXHJcbiAgICAvLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXHJcbiAgICAvLyBubyBydW50aW1lIHBlbmFsdHkgZm9yIHRoZXNlLlxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzE2X0RCTCA9IDEgPDwgMTY7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMjRfREJMID0gMSA8PCAyNDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKiBAY29uc3RcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVFdPX1BXUl8zMl9EQkwgPSBUV09fUFdSXzE2X0RCTCAqIFRXT19QV1JfMTZfREJMO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqIEBjb25zdFxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBUV09fUFdSXzY0X0RCTCA9IFRXT19QV1JfMzJfREJMICogVFdPX1BXUl8zMl9EQkw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfNjNfREJMID0gVFdPX1BXUl82NF9EQkwgLyAyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGNvbnN0XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFRXT19QV1JfMjQgPSBmcm9tSW50KFRXT19QV1JfMjRfREJMKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgWkVSTyA9IGZyb21JbnQoMCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTaWduZWQgemVyby5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5aRVJPID0gWkVSTztcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgVVpFUk8gPSBmcm9tSW50KDAsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5zaWduZWQgemVyby5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5VWkVSTyA9IFVaRVJPO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBPTkUgPSBmcm9tSW50KDEpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogU2lnbmVkIG9uZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5PTkUgPSBPTkU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKiBAaW5uZXJcclxuICAgICAqL1xyXG4gICAgdmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVW5zaWduZWQgb25lLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLlVPTkUgPSBVT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBORUdfT05FID0gZnJvbUludCgtMSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTaWduZWQgbmVnYXRpdmUgb25lLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk5FR19PTkUgPSBORUdfT05FO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBNQVhfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4N0ZGRkZGRkZ8MCwgZmFsc2UpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTWF4aW11bSBzaWduZWQgdmFsdWUuXHJcbiAgICAgKiBAdHlwZSB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmcuTUFYX1ZBTFVFID0gTUFYX1ZBTFVFO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICogQGlubmVyXHJcbiAgICAgKi9cclxuICAgIHZhciBNQVhfVU5TSUdORURfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4RkZGRkZGRkZ8MCwgdHJ1ZSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNYXhpbXVtIHVuc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nLk1BWF9VTlNJR05FRF9WQUxVRSA9IE1BWF9VTlNJR05FRF9WQUxVRTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTUlOX1ZBTFVFID0gZnJvbUJpdHMoMCwgMHg4MDAwMDAwMHwwLCBmYWxzZSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNaW5pbXVtIHNpZ25lZCB2YWx1ZS5cclxuICAgICAqIEB0eXBlIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZy5NSU5fVkFMVUUgPSBNSU5fVkFMVUU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAYWxpYXMgTG9uZy5wcm90b3R5cGVcclxuICAgICAqIEBpbm5lclxyXG4gICAgICovXHJcbiAgICB2YXIgTG9uZ1Byb3RvdHlwZSA9IExvbmcucHJvdG90eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSAzMiBiaXQgaW50ZWdlciwgYXNzdW1pbmcgaXQgaXMgYSAzMiBiaXQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUudG9JbnQgPSBmdW5jdGlvbiB0b0ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IHRoaXMubG93ID4+PiAwIDogdGhpcy5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSB0aGUgbmVhcmVzdCBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHZhbHVlIChkb3VibGUsIDUzIGJpdCBtYW50aXNzYSkuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvTnVtYmVyID0gZnVuY3Rpb24gdG9OdW1iZXIoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgICAgIHJldHVybiAoKHRoaXMuaGlnaCA+Pj4gMCkgKiBUV09fUFdSXzMyX0RCTCkgKyAodGhpcy5sb3cgPj4+IDApO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggKiBUV09fUFdSXzMyX0RCTCArICh0aGlzLmxvdyA+Pj4gMCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhlIExvbmcgdG8gYSBzdHJpbmcgd3JpdHRlbiBpbiB0aGUgc3BlY2lmaWVkIHJhZGl4LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBSYWRpeCAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxyXG4gICAgICogQG92ZXJyaWRlXHJcbiAgICAgKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgcmFkaXhgIGlzIG91dCBvZiByYW5nZVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcocmFkaXgpIHtcclxuICAgICAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xyXG4gICAgICAgIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcclxuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcigncmFkaXgnKTtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuICcwJztcclxuICAgICAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIHsgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlIG5lZWQgdG8gY2hhbmdlIHRoZSBMb25nIHZhbHVlIGJlZm9yZSBpdCBjYW4gYmUgbmVnYXRlZCwgc28gd2UgcmVtb3ZlXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgYm90dG9tLW1vc3QgZGlnaXQgaW4gdGhpcyBiYXNlIGFuZCB0aGVuIHJlY3Vyc2UgdG8gZG8gdGhlIHJlc3QuXHJcbiAgICAgICAgICAgICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXHJcbiAgICAgICAgICAgICAgICAgICAgZGl2ID0gdGhpcy5kaXYocmFkaXhMb25nKSxcclxuICAgICAgICAgICAgICAgICAgICByZW0xID0gZGl2Lm11bChyYWRpeExvbmcpLnN1Yih0aGlzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcclxuICAgICAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJy0nICsgdGhpcy5uZWcoKS50b1N0cmluZyhyYWRpeCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEbyBzZXZlcmFsICg2KSBkaWdpdHMgZWFjaCB0aW1lIHRocm91Z2ggdGhlIGxvb3AsIHNvIGFzIHRvXHJcbiAgICAgICAgLy8gbWluaW1pemUgdGhlIGNhbGxzIHRvIHRoZSB2ZXJ5IGV4cGVuc2l2ZSBlbXVsYXRlZCBkaXYuXHJcbiAgICAgICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxyXG4gICAgICAgICAgICByZW0gPSB0aGlzO1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAnJztcclxuICAgICAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgICAgICB2YXIgcmVtRGl2ID0gcmVtLmRpdihyYWRpeFRvUG93ZXIpLFxyXG4gICAgICAgICAgICAgICAgaW50dmFsID0gcmVtLnN1YihyZW1EaXYubXVsKHJhZGl4VG9Qb3dlcikpLnRvSW50KCkgPj4+IDAsXHJcbiAgICAgICAgICAgICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgICAgICByZW0gPSByZW1EaXY7XHJcbiAgICAgICAgICAgIGlmIChyZW0uaXNaZXJvKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoIDwgNilcclxuICAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAnMCcgKyBkaWdpdHM7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSAnJyArIGRpZ2l0cyArIHJlc3VsdDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFNpZ25lZCBoaWdoIGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0cyA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2g7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaGlnaCAzMiBiaXRzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBVbnNpZ25lZCBoaWdoIGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0SGlnaEJpdHNVbnNpZ25lZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID4+PiAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIGludGVnZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5nZXRMb3dCaXRzID0gZnVuY3Rpb24gZ2V0TG93Qml0cygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFVuc2lnbmVkIGxvdyBiaXRzXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ2V0TG93Qml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0TG93Qml0c1Vuc2lnbmVkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxvdyA+Pj4gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyBuZWVkZWQgdG8gcmVwcmVzZW50IHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGlzIExvbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdldE51bUJpdHNBYnMgPSBmdW5jdGlvbiBnZXROdW1CaXRzQWJzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkgLy8gVW5zaWduZWQgTG9uZ3MgYXJlIG5ldmVyIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSkgPyA2NCA6IHRoaXMubmVnKCkuZ2V0TnVtQml0c0FicygpO1xyXG4gICAgICAgIHZhciB2YWwgPSB0aGlzLmhpZ2ggIT0gMCA/IHRoaXMuaGlnaCA6IHRoaXMubG93O1xyXG4gICAgICAgIGZvciAodmFyIGJpdCA9IDMxOyBiaXQgPiAwOyBiaXQtLSlcclxuICAgICAgICAgICAgaWYgKCh2YWwgJiAoMSA8PCBiaXQpKSAhPSAwKVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaGlnaCAhPSAwID8gYml0ICsgMzMgOiBiaXQgKyAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB6ZXJvLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbmVnYXRpdmUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc05lZ2F0aXZlID0gZnVuY3Rpb24gaXNOZWdhdGl2ZSgpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkIHx8IHRoaXMuaGlnaCA+PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG9kZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmlzT2RkID0gZnVuY3Rpb24gaXNPZGQoKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAxO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGV2ZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5pc0V2ZW4gPSBmdW5jdGlvbiBpc0V2ZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICBpZiAodGhpcy51bnNpZ25lZCAhPT0gb3RoZXIudW5zaWduZWQgJiYgKHRoaXMuaGlnaCA+Pj4gMzEpID09PSAxICYmIChvdGhlci5oaWdoID4+PiAzMSkgPT09IDEpXHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNlcXVhbHN9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5lcSA9IExvbmdQcm90b3R5cGUuZXF1YWxzO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5vdEVxdWFscyA9IGZ1bmN0aW9uIG5vdEVxdWFscyhvdGhlcikge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubmVxID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNsZXNzVGhhbn0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPD0gMDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFuT3JFcXVhbH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmx0ZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuID0gZnVuY3Rpb24gZ3JlYXRlclRoYW4ob3RoZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb21wKC8qIHZhbGlkYXRlcyAqLyBvdGhlcikgPiAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW59LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ndCA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsID0gZnVuY3Rpb24gZ3JlYXRlclRoYW5PckVxdWFsKG90aGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID49IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNncmVhdGVyVGhhbk9yRXF1YWx9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5ndGUgPSBMb25nUHJvdG90eXBlLmdyZWF0ZXJUaGFuT3JFcXVhbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXBhcmVzIHRoaXMgTG9uZydzIHZhbHVlIHdpdGggdGhlIHNwZWNpZmllZCdzLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxyXG4gICAgICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgaWYgKHRoaXMuZXEob3RoZXIpKVxyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB2YXIgdGhpc05lZyA9IHRoaXMuaXNOZWdhdGl2ZSgpLFxyXG4gICAgICAgICAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcclxuICAgICAgICBpZiAodGhpc05lZyAmJiAhb3RoZXJOZWcpXHJcbiAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXHJcbiAgICAgICAgICAgIHJldHVybiAxO1xyXG4gICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNpZ24gYml0cyBhcmUgdGhlIHNhbWVcclxuICAgICAgICBpZiAoIXRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YihvdGhlcikuaXNOZWdhdGl2ZSgpID8gLTEgOiAxO1xyXG4gICAgICAgIC8vIEJvdGggYXJlIHBvc2l0aXZlIGlmIGF0IGxlYXN0IG9uZSBpcyB1bnNpZ25lZFxyXG4gICAgICAgIHJldHVybiAob3RoZXIuaGlnaCA+Pj4gMCkgPiAodGhpcy5oaWdoID4+PiAwKSB8fCAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIChvdGhlci5sb3cgPj4+IDApID4gKHRoaXMubG93ID4+PiAwKSkgPyAtMSA6IDE7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcclxuICAgICAqICBpZiB0aGUgZ2l2ZW4gb25lIGlzIGdyZWF0ZXJcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubmVnYXRlID0gZnVuY3Rpb24gbmVnYXRlKCkge1xyXG4gICAgICAgIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiBNSU5fVkFMVUU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubm90KCkuYWRkKE9ORSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogTmVnYXRlcyB0aGlzIExvbmcncyB2YWx1ZS4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNuZWdhdGV9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IE5lZ2F0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgc3VtIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gYWRkZW5kIEFkZGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTdW1cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoYWRkZW5kKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoYWRkZW5kKSlcclxuICAgICAgICAgICAgYWRkZW5kID0gZnJvbVZhbHVlKGFkZGVuZCk7XHJcblxyXG4gICAgICAgIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxyXG5cclxuICAgICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYjQ4ID0gYWRkZW5kLmhpZ2ggPj4+IDE2O1xyXG4gICAgICAgIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4RkZGRjtcclxuICAgICAgICB2YXIgYjE2ID0gYWRkZW5kLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIwMCA9IGFkZGVuZC5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgICAgIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xyXG4gICAgICAgIGMwMCArPSBhMDAgKyBiMDA7XHJcbiAgICAgICAgYzE2ICs9IGMwMCA+Pj4gMTY7XHJcbiAgICAgICAgYzAwICY9IDB4RkZGRjtcclxuICAgICAgICBjMTYgKz0gYTE2ICsgYjE2O1xyXG4gICAgICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGEzMiArIGIzMjtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGM0OCArPSBhNDggKyBiNDg7XHJcbiAgICAgICAgYzQ4ICY9IDB4RkZGRjtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gc3VidHJhaGVuZCBTdWJ0cmFoZW5kXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KHN1YnRyYWhlbmQpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhzdWJ0cmFoZW5kKSlcclxuICAgICAgICAgICAgc3VidHJhaGVuZCA9IGZyb21WYWx1ZShzdWJ0cmFoZW5kKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5hZGQoc3VidHJhaGVuZC5uZWcoKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc3VidHJhY3R9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLlxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gbXVsdGlwbHkobXVsdGlwbGllcikge1xyXG4gICAgICAgIGlmICh0aGlzLmlzWmVybygpKVxyXG4gICAgICAgICAgICByZXR1cm4gWkVSTztcclxuICAgICAgICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSlcclxuICAgICAgICAgICAgbXVsdGlwbGllciA9IGZyb21WYWx1ZShtdWx0aXBsaWVyKTtcclxuICAgICAgICBpZiAobXVsdGlwbGllci5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICAgICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcbiAgICAgICAgaWYgKG11bHRpcGxpZXIuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgICAgICBpZiAobXVsdGlwbGllci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5tdWwobXVsdGlwbGllci5uZWcoKSk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLm11bChtdWx0aXBsaWVyKS5uZWcoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKG11bHRpcGxpZXIuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XHJcblxyXG4gICAgICAgIC8vIElmIGJvdGggbG9uZ3MgYXJlIHNtYWxsLCB1c2UgZmxvYXQgbXVsdGlwbGljYXRpb25cclxuICAgICAgICBpZiAodGhpcy5sdChUV09fUFdSXzI0KSAmJiBtdWx0aXBsaWVyLmx0KFRXT19QV1JfMjQpKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xyXG5cclxuICAgICAgICAvLyBEaXZpZGUgZWFjaCBsb25nIGludG8gNCBjaHVua3Mgb2YgMTYgYml0cywgYW5kIHRoZW4gYWRkIHVwIDR4NCBwcm9kdWN0cy5cclxuICAgICAgICAvLyBXZSBjYW4gc2tpcCBwcm9kdWN0cyB0aGF0IHdvdWxkIG92ZXJmbG93LlxyXG5cclxuICAgICAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYTMyID0gdGhpcy5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYjQ4ID0gbXVsdGlwbGllci5oaWdoID4+PiAxNjtcclxuICAgICAgICB2YXIgYjMyID0gbXVsdGlwbGllci5oaWdoICYgMHhGRkZGO1xyXG4gICAgICAgIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XHJcbiAgICAgICAgdmFyIGIwMCA9IG11bHRpcGxpZXIubG93ICYgMHhGRkZGO1xyXG5cclxuICAgICAgICB2YXIgYzQ4ID0gMCwgYzMyID0gMCwgYzE2ID0gMCwgYzAwID0gMDtcclxuICAgICAgICBjMDAgKz0gYTAwICogYjAwO1xyXG4gICAgICAgIGMxNiArPSBjMDAgPj4+IDE2O1xyXG4gICAgICAgIGMwMCAmPSAweEZGRkY7XHJcbiAgICAgICAgYzE2ICs9IGExNiAqIGIwMDtcclxuICAgICAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgICAgICBjMTYgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMxNiArPSBhMDAgKiBiMTY7XHJcbiAgICAgICAgYzMyICs9IGMxNiA+Pj4gMTY7XHJcbiAgICAgICAgYzE2ICY9IDB4RkZGRjtcclxuICAgICAgICBjMzIgKz0gYTMyICogYjAwO1xyXG4gICAgICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICAgICAgYzMyICs9IGExNiAqIGIxNjtcclxuICAgICAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgICAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgICAgIGMzMiArPSBhMDAgKiBiMzI7XHJcbiAgICAgICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICAgICAgYzMyICY9IDB4RkZGRjtcclxuICAgICAgICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xyXG4gICAgICAgIGM0OCAmPSAweEZGRkY7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKChjMTYgPDwgMTYpIHwgYzAwLCAoYzQ4IDw8IDE2KSB8IGMzMiwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgcHJvZHVjdCBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbXVsdGlwbHl9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG11bHRpcGxpZXIgTXVsdGlwbGllclxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubXVsID0gTG9uZ1Byb3RvdHlwZS5tdWx0aXBseTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxyXG4gICAgICogIHVuc2lnbmVkIGlmIHRoaXMgTG9uZyBpcyB1bnNpZ25lZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZGl2aWRlID0gZnVuY3Rpb24gZGl2aWRlKGRpdmlzb3IpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcclxuICAgICAgICAgICAgZGl2aXNvciA9IGZyb21WYWx1ZShkaXZpc29yKTtcclxuICAgICAgICBpZiAoZGl2aXNvci5pc1plcm8oKSlcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKTtcclxuICAgICAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyBVWkVSTyA6IFpFUk87XHJcbiAgICAgICAgdmFyIGFwcHJveCwgcmVtLCByZXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKSB7XHJcbiAgICAgICAgICAgIC8vIFRoaXMgc2VjdGlvbiBpcyBvbmx5IHJlbGV2YW50IGZvciBzaWduZWQgbG9uZ3MgYW5kIGlzIGRlcml2ZWQgZnJvbSB0aGVcclxuICAgICAgICAgICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChkaXZpc29yLmVxKE9ORSkgfHwgZGl2aXNvci5lcShORUdfT05FKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAgLy8gcmVjYWxsIHRoYXQgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUVcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpdmlzb3IuZXEoTUlOX1ZBTFVFKSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gT05FO1xyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgd2UgaGF2ZSB8b3RoZXJ8ID49IDIsIHNvIHx0aGlzL290aGVyfCA8IHxNSU5fVkFMVUV8LlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYWxmVGhpcyA9IHRoaXMuc2hyKDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFwcHJveC5lcShaRVJPKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGl2aXNvci5pc05lZ2F0aXZlKCkgPyBPTkUgOiBORUdfT05FO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbSA9IHRoaXMuc3ViKGRpdmlzb3IubXVsKGFwcHJveCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBhcHByb3guYWRkKHJlbS5kaXYoZGl2aXNvcikpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy51bnNpZ25lZCA/IFVaRVJPIDogWkVSTztcclxuICAgICAgICAgICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IubmVnKCkpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkuZGl2KGRpdmlzb3IpLm5lZygpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGl2KGRpdmlzb3IubmVnKCkpLm5lZygpO1xyXG4gICAgICAgICAgICByZXMgPSBaRVJPO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFRoZSBhbGdvcml0aG0gYmVsb3cgaGFzIG5vdCBiZWVuIG1hZGUgZm9yIHVuc2lnbmVkIGxvbmdzLiBJdCdzIHRoZXJlZm9yZVxyXG4gICAgICAgICAgICAvLyByZXF1aXJlZCB0byB0YWtlIHNwZWNpYWwgY2FyZSBvZiB0aGUgTVNCIHByaW9yIHRvIHJ1bm5pbmcgaXQuXHJcbiAgICAgICAgICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcclxuICAgICAgICAgICAgICAgIGRpdmlzb3IgPSBkaXZpc29yLnRvVW5zaWduZWQoKTtcclxuICAgICAgICAgICAgaWYgKGRpdmlzb3IuZ3QodGhpcykpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgICAgIGlmIChkaXZpc29yLmd0KHRoaXMuc2hydSgxKSkpIC8vIDE1ID4+PiAxID0gNyA7IHdpdGggZGl2aXNvciA9IDggOyB0cnVlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVU9ORTtcclxuICAgICAgICAgICAgcmVzID0gVVpFUk87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZXBlYXQgdGhlIGZvbGxvd2luZyB1bnRpbCB0aGUgcmVtYWluZGVyIGlzIGxlc3MgdGhhbiBvdGhlcjogIGZpbmQgYVxyXG4gICAgICAgIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcclxuICAgICAgICAvLyBpbnRvIHRoZSByZXN1bHQsIGFuZCBzdWJ0cmFjdCBpdCBmcm9tIHRoZSByZW1haW5kZXIuICBJdCBpcyBjcml0aWNhbCB0aGF0XHJcbiAgICAgICAgLy8gdGhlIGFwcHJveGltYXRlIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgcmVhbCB2YWx1ZSBzbyB0aGF0IHRoZVxyXG4gICAgICAgIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxyXG4gICAgICAgIHJlbSA9IHRoaXM7XHJcbiAgICAgICAgd2hpbGUgKHJlbS5ndGUoZGl2aXNvcikpIHtcclxuICAgICAgICAgICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxyXG4gICAgICAgICAgICAvLyBzbWFsbGVyIHRoYW4gdGhlIGFjdHVhbCB2YWx1ZS5cclxuICAgICAgICAgICAgYXBwcm94ID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihyZW0udG9OdW1iZXIoKSAvIGRpdmlzb3IudG9OdW1iZXIoKSkpO1xyXG5cclxuICAgICAgICAgICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxyXG4gICAgICAgICAgICAvLyB0aGUgc21hbGxlc3Qgbm9uLWZyYWN0aW9uYWwgZGlnaXQsIHdoaWNoZXZlciBpcyBsYXJnZXIuXHJcbiAgICAgICAgICAgIHZhciBsb2cyID0gTWF0aC5jZWlsKE1hdGgubG9nKGFwcHJveCkgLyBNYXRoLkxOMiksXHJcbiAgICAgICAgICAgICAgICBkZWx0YSA9IChsb2cyIDw9IDQ4KSA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXHJcblxyXG4gICAgICAgICAgICAvLyBEZWNyZWFzZSB0aGUgYXBwcm94aW1hdGlvbiB1bnRpbCBpdCBpcyBzbWFsbGVyIHRoYW4gdGhlIHJlbWFpbmRlci4gIE5vdGVcclxuICAgICAgICAgICAgLy8gdGhhdCBpZiBpdCBpcyB0b28gbGFyZ2UsIHRoZSBwcm9kdWN0IG92ZXJmbG93cyBhbmQgaXMgbmVnYXRpdmUuXHJcbiAgICAgICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCksXHJcbiAgICAgICAgICAgICAgICBhcHByb3hSZW0gPSBhcHByb3hSZXMubXVsKGRpdmlzb3IpO1xyXG4gICAgICAgICAgICB3aGlsZSAoYXBwcm94UmVtLmlzTmVnYXRpdmUoKSB8fCBhcHByb3hSZW0uZ3QocmVtKSkge1xyXG4gICAgICAgICAgICAgICAgYXBwcm94IC09IGRlbHRhO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gZnJvbU51bWJlcihhcHByb3gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVtID0gYXBwcm94UmVzLm11bChkaXZpc29yKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gV2Uga25vdyB0aGUgYW5zd2VyIGNhbid0IGJlIHplcm8uLi4gYW5kIGFjdHVhbGx5LCB6ZXJvIHdvdWxkIGNhdXNlXHJcbiAgICAgICAgICAgIC8vIGluZmluaXRlIHJlY3Vyc2lvbiBzaW5jZSB3ZSB3b3VsZCBtYWtlIG5vIHByb2dyZXNzLlxyXG4gICAgICAgICAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxyXG4gICAgICAgICAgICAgICAgYXBwcm94UmVzID0gT05FO1xyXG5cclxuICAgICAgICAgICAgcmVzID0gcmVzLmFkZChhcHByb3hSZXMpO1xyXG4gICAgICAgICAgICByZW0gPSByZW0uc3ViKGFwcHJveFJlbSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXM7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgZGl2aWRlZCBieSB0aGUgc3BlY2lmaWVkLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2RpdmlkZX0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuZGl2ID0gTG9uZ1Byb3RvdHlwZS5kaXZpZGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFJlbWFpbmRlclxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLm1vZHVsbyA9IGZ1bmN0aW9uIG1vZHVsbyhkaXZpc29yKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcoZGl2aXNvcikpXHJcbiAgICAgICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViKHRoaXMuZGl2KGRpdmlzb3IpLm11bChkaXZpc29yKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cclxuICAgICAqIEBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubW9kID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIE5PVCBvZiB0aGlzIExvbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUubm90ID0gZnVuY3Rpb24gbm90KCkge1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh+dGhpcy5sb3csIH50aGlzLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGJpdHdpc2UgQU5EIG9mIHRoaXMgTG9uZyBhbmQgdGhlIHNwZWNpZmllZC5cclxuICAgICAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfVxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZChvdGhlcikge1xyXG4gICAgICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyAmIG90aGVyLmxvdywgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5vciA9IGZ1bmN0aW9uIG9yKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IHwgb3RoZXIubG93LCB0aGlzLmhpZ2ggfCBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBiaXR3aXNlIFhPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBnaXZlbiBvbmUuXHJcbiAgICAgKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIExvbmdcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ31cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3Iob3RoZXIpIHtcclxuICAgICAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgXiBvdGhlci5sb3csIHRoaXMuaGlnaCBeIG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgPDwgbnVtQml0cywgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygwLCB0aGlzLmxvdyA8PCAobnVtQml0cyAtIDMyKSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIHNoaWZ0ZWQgdG8gdGhlIGxlZnQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdExlZnR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaGwgPSBMb25nUHJvdG90eXBlLnNoaWZ0TGVmdDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8IUxvbmd9IG51bUJpdHMgTnVtYmVyIG9mIGJpdHNcclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAgICAgKi9cclxuICAgIExvbmdQcm90b3R5cGUuc2hpZnRSaWdodCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHQobnVtQml0cykge1xyXG4gICAgICAgIGlmIChpc0xvbmcobnVtQml0cykpXHJcbiAgICAgICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICAgICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoKHRoaXMubG93ID4+PiBudW1CaXRzKSB8ICh0aGlzLmhpZ2ggPDwgKDMyIC0gbnVtQml0cykpLCB0aGlzLmhpZ2ggPj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXHJcbiAgICAgKiBAZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNociA9IExvbmdQcm90b3R5cGUuc2hpZnRSaWdodDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAgICAgKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZCA9IGZ1bmN0aW9uIHNoaWZ0UmlnaHRVbnNpZ25lZChudW1CaXRzKSB7XHJcbiAgICAgICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICAgICAgbnVtQml0cyA9IG51bUJpdHMudG9JbnQoKTtcclxuICAgICAgICBudW1CaXRzICY9IDYzO1xyXG4gICAgICAgIGlmIChudW1CaXRzID09PSAwKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIGhpZ2ggPSB0aGlzLmhpZ2g7XHJcbiAgICAgICAgICAgIGlmIChudW1CaXRzIDwgMzIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsb3cgPSB0aGlzLmxvdztcclxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygobG93ID4+PiBudW1CaXRzKSB8IChoaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobnVtQml0cyA9PT0gMzIpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbUJpdHMoaGlnaCwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tQml0cyhoaWdoID4+PiAobnVtQml0cyAtIDMyKSwgMCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBsb2dpY2FsbHkgc2hpZnRlZCB0byB0aGUgcmlnaHQgYnkgdGhlIGdpdmVuIGFtb3VudC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzaGlmdFJpZ2h0VW5zaWduZWR9LlxyXG4gICAgICogQGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaGlmdGVkIExvbmdcclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS5zaHJ1ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gc2lnbmVkLlxyXG4gICAgICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvU2lnbmVkID0gZnVuY3Rpb24gdG9TaWduZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byB1bnNpZ25lZC5cclxuICAgICAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvVW5zaWduZWQgPSBmdW5jdGlvbiB0b1Vuc2lnbmVkKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3csIHRoaXMuaGlnaCwgdHJ1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxyXG4gICAgICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQnl0ZSByZXByZXNlbnRhdGlvblxyXG4gICAgICovXHJcbiAgICBMb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbihsZSkge1xyXG4gICAgICAgIHJldHVybiBsZSA/IHRoaXMudG9CeXRlc0xFKCkgOiB0aGlzLnRvQnl0ZXNCRSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBsaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBMaXR0bGUgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzTEUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgIGxvICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+ICA4KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAgaGkgICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgKGhpID4+PiAxNikgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+IDI0KSAmIDB4ZmZcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgdGhpcyBMb25nIHRvIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICAgICAqL1xyXG4gICAgTG9uZ1Byb3RvdHlwZS50b0J5dGVzQkUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgaGkgPSB0aGlzLmhpZ2gsXHJcbiAgICAgICAgICAgIGxvID0gdGhpcy5sb3c7XHJcbiAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgKGhpID4+PiAyNCkgJiAweGZmLFxyXG4gICAgICAgICAgICAoaGkgPj4+IDE2KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChoaSA+Pj4gIDgpICYgMHhmZixcclxuICAgICAgICAgICAgIGhpICAgICAgICAgJiAweGZmLFxyXG4gICAgICAgICAgICAobG8gPj4+IDI0KSAmIDB4ZmYsXHJcbiAgICAgICAgICAgIChsbyA+Pj4gMTYpICYgMHhmZixcclxuICAgICAgICAgICAgKGxvID4+PiAgOCkgJiAweGZmLFxyXG4gICAgICAgICAgICAgbG8gICAgICAgICAmIDB4ZmZcclxuICAgICAgICBdO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBMb25nO1xyXG59KTtcclxuIiwiJ3VzZSBzdHJpY3QnXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaEJhc2UgPSByZXF1aXJlKCdoYXNoLWJhc2UnKVxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxuZnVuY3Rpb24gTUQ1ICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxufVxuXG5pbmhlcml0cyhNRDUsIEhhc2hCYXNlKVxuXG5NRDUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNID0gQVJSQVkxNlxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIE1baV0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShpICogNClcblxuICB2YXIgYSA9IHRoaXMuX2FcbiAgdmFyIGIgPSB0aGlzLl9iXG4gIHZhciBjID0gdGhpcy5fY1xuICB2YXIgZCA9IHRoaXMuX2RcblxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bMF0sIDB4ZDc2YWE0NzgsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxXSwgMHhlOGM3Yjc1NiwgMTIpXG4gIGMgPSBmbkYoYywgZCwgYSwgYiwgTVsyXSwgMHgyNDIwNzBkYiwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVszXSwgMHhjMWJkY2VlZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVs0XSwgMHhmNTdjMGZhZiwgNylcbiAgZCA9IGZuRihkLCBhLCBiLCBjLCBNWzVdLCAweDQ3ODdjNjJhLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzZdLCAweGE4MzA0NjEzLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzddLCAweGZkNDY5NTAxLCAyMilcbiAgYSA9IGZuRihhLCBiLCBjLCBkLCBNWzhdLCAweDY5ODA5OGQ4LCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bOV0sIDB4OGI0NGY3YWYsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTBdLCAweGZmZmY1YmIxLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzExXSwgMHg4OTVjZDdiZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVsxMl0sIDB4NmI5MDExMjIsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxM10sIDB4ZmQ5ODcxOTMsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTRdLCAweGE2Nzk0MzhlLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzE1XSwgMHg0OWI0MDgyMSwgMjIpXG5cbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzFdLCAweGY2MWUyNTYyLCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bNl0sIDB4YzA0MGIzNDAsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxMV0sIDB4MjY1ZTVhNTEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bMF0sIDB4ZTliNmM3YWEsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bNV0sIDB4ZDYyZjEwNWQsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxMF0sIDB4MDI0NDE0NTMsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxNV0sIDB4ZDhhMWU2ODEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bNF0sIDB4ZTdkM2ZiYzgsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bOV0sIDB4MjFlMWNkZTYsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxNF0sIDB4YzMzNzA3ZDYsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVszXSwgMHhmNGQ1MGQ4NywgMTQpXG4gIGIgPSBmbkcoYiwgYywgZCwgYSwgTVs4XSwgMHg0NTVhMTRlZCwgMjApXG4gIGEgPSBmbkcoYSwgYiwgYywgZCwgTVsxM10sIDB4YTllM2U5MDUsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsyXSwgMHhmY2VmYTNmOCwgOSlcbiAgYyA9IGZuRyhjLCBkLCBhLCBiLCBNWzddLCAweDY3NmYwMmQ5LCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzEyXSwgMHg4ZDJhNGM4YSwgMjApXG5cbiAgYSA9IGZuSChhLCBiLCBjLCBkLCBNWzVdLCAweGZmZmEzOTQyLCA0KVxuICBkID0gZm5IKGQsIGEsIGIsIGMsIE1bOF0sIDB4ODc3MWY2ODEsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bMTFdLCAweDZkOWQ2MTIyLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzE0XSwgMHhmZGU1MzgwYywgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxXSwgMHhhNGJlZWE0NCwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzRdLCAweDRiZGVjZmE5LCAxMSlcbiAgYyA9IGZuSChjLCBkLCBhLCBiLCBNWzddLCAweGY2YmI0YjYwLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzEwXSwgMHhiZWJmYmM3MCwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxM10sIDB4Mjg5YjdlYzYsIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVswXSwgMHhlYWExMjdmYSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVszXSwgMHhkNGVmMzA4NSwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVs2XSwgMHgwNDg4MWQwNSwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVs5XSwgMHhkOWQ0ZDAzOSwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzEyXSwgMHhlNmRiOTllNSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVsxNV0sIDB4MWZhMjdjZjgsIDE2KVxuICBiID0gZm5IKGIsIGMsIGQsIGEsIE1bMl0sIDB4YzRhYzU2NjUsIDIzKVxuXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVswXSwgMHhmNDI5MjI0NCwgNilcbiAgZCA9IGZuSShkLCBhLCBiLCBjLCBNWzddLCAweDQzMmFmZjk3LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzE0XSwgMHhhYjk0MjNhNywgMTUpXG4gIGIgPSBmbkkoYiwgYywgZCwgYSwgTVs1XSwgMHhmYzkzYTAzOSwgMjEpXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVsxMl0sIDB4NjU1YjU5YzMsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVszXSwgMHg4ZjBjY2M5MiwgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsxMF0sIDB4ZmZlZmY0N2QsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMV0sIDB4ODU4NDVkZDEsIDIxKVxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bOF0sIDB4NmZhODdlNGYsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVsxNV0sIDB4ZmUyY2U2ZTAsIDEwKVxuICBjID0gZm5JKGMsIGQsIGEsIGIsIE1bNl0sIDB4YTMwMTQzMTQsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMTNdLCAweDRlMDgxMWExLCAyMSlcbiAgYSA9IGZuSShhLCBiLCBjLCBkLCBNWzRdLCAweGY3NTM3ZTgyLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bMTFdLCAweGJkM2FmMjM1LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzJdLCAweDJhZDdkMmJiLCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzldLCAweGViODZkMzkxLCAyMSlcblxuICB0aGlzLl9hID0gKHRoaXMuX2EgKyBhKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9iICsgYikgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fYyArIGMpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2QgKyBkKSB8IDBcbn1cblxuTUQ1LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjcmVhdGUgcGFkZGluZyBhbmQgaGFuZGxlIGJsb2Nrc1xuICB0aGlzLl9ibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IDB4ODBcbiAgaWYgKHRoaXMuX2Jsb2NrT2Zmc2V0ID4gNTYpIHtcbiAgICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA2NClcbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG5cbiAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzBdLCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMV0sIDYwKVxuICB0aGlzLl91cGRhdGUoKVxuXG4gIC8vIHByb2R1Y2UgcmVzdWx0XG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKDE2KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2EsIDApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYiwgNClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9jLCA4KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2QsIDEyKVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIHJvdGwgKHgsIG4pIHtcbiAgcmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKVxufVxuXG5mdW5jdGlvbiBmbkYgKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgYykgfCAoKH5iKSAmIGQpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbmZ1bmN0aW9uIGZuRyAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBkKSB8IChjICYgKH5kKSkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5IIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArIChiIF4gYyBeIGQpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5JIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYyBeIChiIHwgKH5kKSkpKSArIG0gKyBrKSB8IDAsIHMpICsgYikgfCAwXG59XG5cbm1vZHVsZS5leHBvcnRzID0gTUQ1XG4iLCIndXNlIHN0cmljdCdcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiB0aHJvd0lmTm90U3RyaW5nT3JCdWZmZXIgKHZhbCwgcHJlZml4KSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHZhbCkgJiYgdHlwZW9mIHZhbCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHByZWZpeCArICcgbXVzdCBiZSBhIHN0cmluZyBvciBhIGJ1ZmZlcicpXG4gIH1cbn1cblxuZnVuY3Rpb24gSGFzaEJhc2UgKGJsb2NrU2l6ZSkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuXG4gIHRoaXMuX2Jsb2NrID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2NrU2l6ZSlcbiAgdGhpcy5fYmxvY2tTaXplID0gYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB0aGlzLl9sZW5ndGggPSBbMCwgMCwgMCwgMF1cblxuICB0aGlzLl9maW5hbGl6ZWQgPSBmYWxzZVxufVxuXG5pbmhlcml0cyhIYXNoQmFzZSwgVHJhbnNmb3JtKVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIHZhciBlcnJvciA9IG51bGxcbiAgdHJ5IHtcbiAgICB0aGlzLnVwZGF0ZShjaHVuaywgZW5jb2RpbmcpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGVycm9yID0gZXJyXG4gIH1cblxuICBjYWxsYmFjayhlcnJvcilcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB2YXIgZXJyb3IgPSBudWxsXG4gIHRyeSB7XG4gICAgdGhpcy5wdXNoKHRoaXMuZGlnZXN0KCkpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGVycm9yID0gZXJyXG4gIH1cblxuICBjYWxsYmFjayhlcnJvcilcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBlbmNvZGluZykge1xuICB0aHJvd0lmTm90U3RyaW5nT3JCdWZmZXIoZGF0YSwgJ0RhdGEnKVxuICBpZiAodGhpcy5fZmluYWxpemVkKSB0aHJvdyBuZXcgRXJyb3IoJ0RpZ2VzdCBhbHJlYWR5IGNhbGxlZCcpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSBkYXRhID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmcpXG5cbiAgLy8gY29uc3VtZSBkYXRhXG4gIHZhciBibG9jayA9IHRoaXMuX2Jsb2NrXG4gIHZhciBvZmZzZXQgPSAwXG4gIHdoaWxlICh0aGlzLl9ibG9ja09mZnNldCArIGRhdGEubGVuZ3RoIC0gb2Zmc2V0ID49IHRoaXMuX2Jsb2NrU2l6ZSkge1xuICAgIGZvciAodmFyIGkgPSB0aGlzLl9ibG9ja09mZnNldDsgaSA8IHRoaXMuX2Jsb2NrU2l6ZTspIGJsb2NrW2krK10gPSBkYXRhW29mZnNldCsrXVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cbiAgd2hpbGUgKG9mZnNldCA8IGRhdGEubGVuZ3RoKSBibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IGRhdGFbb2Zmc2V0KytdXG5cbiAgLy8gdXBkYXRlIGxlbmd0aFxuICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSBkYXRhLmxlbmd0aCAqIDg7IGNhcnJ5ID4gMDsgKytqKSB7XG4gICAgdGhpcy5fbGVuZ3RoW2pdICs9IGNhcnJ5XG4gICAgY2FycnkgPSAodGhpcy5fbGVuZ3RoW2pdIC8gMHgwMTAwMDAwMDAwKSB8IDBcbiAgICBpZiAoY2FycnkgPiAwKSB0aGlzLl9sZW5ndGhbal0gLT0gMHgwMTAwMDAwMDAwICogY2FycnlcbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ191cGRhdGUgaXMgbm90IGltcGxlbWVudGVkJylcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBpZiAodGhpcy5fZmluYWxpemVkKSB0aHJvdyBuZXcgRXJyb3IoJ0RpZ2VzdCBhbHJlYWR5IGNhbGxlZCcpXG4gIHRoaXMuX2ZpbmFsaXplZCA9IHRydWVcblxuICB2YXIgZGlnZXN0ID0gdGhpcy5fZGlnZXN0KClcbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIGRpZ2VzdCA9IGRpZ2VzdC50b1N0cmluZyhlbmNvZGluZylcblxuICAvLyByZXNldCBzdGF0ZVxuICB0aGlzLl9ibG9jay5maWxsKDApXG4gIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7ICsraSkgdGhpcy5fbGVuZ3RoW2ldID0gMFxuXG4gIHJldHVybiBkaWdlc3Rcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX2RpZ2VzdCBpcyBub3QgaW1wbGVtZW50ZWQnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hCYXNlXG4iLCIndXNlIHN0cmljdCc7XG5cbmlmICghcHJvY2Vzcy52ZXJzaW9uIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YwLicpID09PSAwIHx8XG4gICAgcHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoJ3YxLicpID09PSAwICYmIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS44LicpICE9PSAwKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gbmV4dFRpY2s7XG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IHByb2Nlc3MubmV4dFRpY2s7XG59XG5cbmZ1bmN0aW9uIG5leHRUaWNrKGZuLCBhcmcxLCBhcmcyLCBhcmczKSB7XG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNhbGxiYWNrXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBhcmdzLCBpO1xuICBzd2l0Y2ggKGxlbikge1xuICBjYXNlIDA6XG4gIGNhc2UgMTpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbik7XG4gIGNhc2UgMjpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tPbmUoKSB7XG4gICAgICBmbi5jYWxsKG51bGwsIGFyZzEpO1xuICAgIH0pO1xuICBjYXNlIDM6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrVHdvKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyKTtcbiAgICB9KTtcbiAgY2FzZSA0OlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgICB9KTtcbiAgZGVmYXVsdDpcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYXJncy5sZW5ndGgpIHtcbiAgICAgIGFyZ3NbaSsrXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrKCkge1xuICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cbnByb2Nlc3MubGlzdGVuZXJzID0gZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIFtdIH1cblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fZHVwbGV4LmpzJyk7XG4iLCIvLyBhIGR1cGxleCBzdHJlYW0gaXMganVzdCBhIHN0cmVhbSB0aGF0IGlzIGJvdGggcmVhZGFibGUgYW5kIHdyaXRhYmxlLlxuLy8gU2luY2UgSlMgZG9lc24ndCBoYXZlIG11bHRpcGxlIHByb3RvdHlwYWwgaW5oZXJpdGFuY2UsIHRoaXMgY2xhc3Ncbi8vIHByb3RvdHlwYWxseSBpbmhlcml0cyBmcm9tIFJlYWRhYmxlLCBhbmQgdGhlbiBwYXJhc2l0aWNhbGx5IGZyb21cbi8vIFdyaXRhYmxlLlxuXG4ndXNlIHN0cmljdCc7XG5cbi8qPHJlcGxhY2VtZW50PiovXG5cbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iaikge1xuICB2YXIga2V5cyA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAga2V5cy5wdXNoKGtleSk7XG4gIH1yZXR1cm4ga2V5cztcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgcHJvY2Vzc05leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy1uZXh0aWNrLWFyZ3MnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnLi9fc3RyZWFtX3dyaXRhYmxlJyk7XG5cbnV0aWwuaW5oZXJpdHMoRHVwbGV4LCBSZWFkYWJsZSk7XG5cbnZhciBrZXlzID0gb2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO1xuZm9yICh2YXIgdiA9IDA7IHYgPCBrZXlzLmxlbmd0aDsgdisrKSB7XG4gIHZhciBtZXRob2QgPSBrZXlzW3ZdO1xuICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSkgRHVwbGV4LnByb3RvdHlwZVttZXRob2RdID0gV3JpdGFibGUucHJvdG90eXBlW21ldGhvZF07XG59XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcblxuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVhZGFibGUgPT09IGZhbHNlKSB0aGlzLnJlYWRhYmxlID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy53cml0YWJsZSA9PT0gZmFsc2UpIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKSB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2VuZCcsIG9uZW5kKTtcbn1cblxuLy8gdGhlIG5vLWhhbGYtb3BlbiBlbmZvcmNlclxuZnVuY3Rpb24gb25lbmQoKSB7XG4gIC8vIGlmIHdlIGFsbG93IGhhbGYtb3BlbiBzdGF0ZSwgb3IgaWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsXG4gIC8vIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLmFsbG93SGFsZk9wZW4gfHwgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZCkgcmV0dXJuO1xuXG4gIC8vIG5vIG1vcmUgZGF0YSBjYW4gYmUgd3JpdHRlbi5cbiAgLy8gQnV0IGFsbG93IG1vcmUgd3JpdGVzIHRvIGhhcHBlbiBpbiB0aGlzIHRpY2suXG4gIHByb2Nlc3NOZXh0VGljayhvbkVuZE5ULCB0aGlzKTtcbn1cblxuZnVuY3Rpb24gb25FbmROVChzZWxmKSB7XG4gIHNlbGYuZW5kKCk7XG59XG5cbmZ1bmN0aW9uIGZvckVhY2goeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufSIsIi8vIGEgcGFzc3Rocm91Z2ggc3RyZWFtLlxuLy8gYmFzaWNhbGx5IGp1c3QgdGhlIG1vc3QgbWluaW1hbCBzb3J0IG9mIFRyYW5zZm9ybSBzdHJlYW0uXG4vLyBFdmVyeSB3cml0dGVuIGNodW5rIGdldHMgb3V0cHV0IGFzLWlzLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCcuL19zdHJlYW1fdHJhbnNmb3JtJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gUGFzc1Rocm91Z2gob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFzc1Rocm91Z2gpKSByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRHVwbGV4O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW0gPSByZXF1aXJlKCcuL2ludGVybmFsL3N0cmVhbXMvc3RyZWFtJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYnVmZmVyU2hpbSA9IHJlcXVpcmUoJ2J1ZmZlci1zaGltcycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBkZWJ1Z1V0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgZGVidWcgPSB2b2lkIDA7XG5pZiAoZGVidWdVdGlsICYmIGRlYnVnVXRpbC5kZWJ1Z2xvZykge1xuICBkZWJ1ZyA9IGRlYnVnVXRpbC5kZWJ1Z2xvZygnc3RyZWFtJyk7XG59IGVsc2Uge1xuICBkZWJ1ZyA9IGZ1bmN0aW9uICgpIHt9O1xufVxuLyo8L3JlcGxhY2VtZW50PiovXG5cbnZhciBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3QnKTtcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG52YXIga1Byb3h5RXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuXG5mdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIoZW1pdHRlciwgZXZlbnQsIGZuKSB7XG4gIC8vIFNhZGx5IHRoaXMgaXMgbm90IGNhY2hlYWJsZSBhcyBzb21lIGxpYnJhcmllcyBidW5kbGUgdGhlaXIgb3duXG4gIC8vIGV2ZW50IGVtaXR0ZXIgaW1wbGVtZW50YXRpb24gd2l0aCB0aGVtLlxuICBpZiAodHlwZW9mIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50LCBmbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gVGhpcyBpcyBhIGhhY2sgdG8gbWFrZSBzdXJlIHRoYXQgb3VyIGVycm9yIGhhbmRsZXIgaXMgYXR0YWNoZWQgYmVmb3JlIGFueVxuICAgIC8vIHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLiBUaGlzIGlzIGhlcmUgb25seSBiZWNhdXNlIHRoaXMgY29kZSBuZWVkc1xuICAgIC8vIHRvIGNvbnRpbnVlIHRvIHdvcmsgd2l0aCBvbGRlciB2ZXJzaW9ucyBvZiBOb2RlLmpzIHRoYXQgZG8gbm90IGluY2x1ZGVcbiAgICAvLyB0aGUgcHJlcGVuZExpc3RlbmVyKCkgbWV0aG9kLiBUaGUgZ29hbCBpcyB0byBldmVudHVhbGx5IHJlbW92ZSB0aGlzIGhhY2suXG4gICAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1tldmVudF0pIGVtaXR0ZXIub24oZXZlbnQsIGZuKTtlbHNlIGlmIChpc0FycmF5KGVtaXR0ZXIuX2V2ZW50c1tldmVudF0pKSBlbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XSA9IFtmbiwgZW1pdHRlci5fZXZlbnRzW2V2ZW50XV07XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLnJlYWRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHZhciBkZWZhdWx0SHdtID0gdGhpcy5vYmplY3RNb2RlID8gMTYgOiAxNiAqIDEwMjQ7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IGh3bSB8fCBod20gPT09IDAgPyBod20gOiBkZWZhdWx0SHdtO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfn50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgLy8gQSBsaW5rZWQgbGlzdCBpcyB1c2VkIHRvIHN0b3JlIGRhdGEgY2h1bmtzIGluc3RlYWQgb2YgYW4gYXJyYXkgYmVjYXVzZSB0aGVcbiAgLy8gbGlua2VkIGxpc3QgY2FuIHJlbW92ZSBlbGVtZW50cyBmcm9tIHRoZSBiZWdpbm5pbmcgZmFzdGVyIHRoYW5cbiAgLy8gYXJyYXkuc2hpZnQoKVxuICB0aGlzLmJ1ZmZlciA9IG5ldyBCdWZmZXJMaXN0KCk7XG4gIHRoaXMubGVuZ3RoID0gMDtcbiAgdGhpcy5waXBlcyA9IG51bGw7XG4gIHRoaXMucGlwZXNDb3VudCA9IDA7XG4gIHRoaXMuZmxvd2luZyA9IG51bGw7XG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgdGhpcy5lbmRFbWl0dGVkID0gZmFsc2U7XG4gIHRoaXMucmVhZGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG4gIHRoaXMucmVzdW1lU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gd2hlbiBwaXBpbmcsIHdlIG9ubHkgY2FyZSBhYm91dCAncmVhZGFibGUnIGV2ZW50cyB0aGF0IGhhcHBlblxuICAvLyBhZnRlciByZWFkKClpbmcgYWxsIHRoZSBieXRlcyBhbmQgbm90IGdldHRpbmcgYW55IHB1c2hiYWNrLlxuICB0aGlzLnJhbk91dCA9IGZhbHNlO1xuXG4gIC8vIHRoZSBudW1iZXIgb2Ygd3JpdGVycyB0aGF0IGFyZSBhd2FpdGluZyBhIGRyYWluIGV2ZW50IGluIC5waXBlKClzXG4gIHRoaXMuYXdhaXREcmFpbiA9IDA7XG5cbiAgLy8gaWYgdHJ1ZSwgYSBtYXliZVJlYWRNb3JlIGhhcyBiZWVuIHNjaGVkdWxlZFxuICB0aGlzLnJlYWRpbmdNb3JlID0gZmFsc2U7XG5cbiAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgdGhpcy5lbmNvZGluZyA9IG51bGw7XG4gIGlmIChvcHRpb25zLmVuY29kaW5nKSB7XG4gICAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgICB0aGlzLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTtcbiAgICB0aGlzLmVuY29kaW5nID0gb3B0aW9ucy5lbmNvZGluZztcbiAgfVxufVxuXG5mdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSkgcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTtcblxuICB0aGlzLl9yZWFkYWJsZVN0YXRlID0gbmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLnJlYWQgPT09ICdmdW5jdGlvbicpIHRoaXMuX3JlYWQgPSBvcHRpb25zLnJlYWQ7XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE1hbnVhbGx5IHNob3ZlIHNvbWV0aGluZyBpbnRvIHRoZSByZWFkKCkgYnVmZmVyLlxuLy8gVGhpcyByZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2hXYXRlck1hcmsgaGFzIG5vdCBiZWVuIGhpdCB5ZXQsXG4vLyBzaW1pbGFyIHRvIGhvdyBXcml0YWJsZS53cml0ZSgpIHJldHVybnMgdHJ1ZSBpZiB5b3Ugc2hvdWxkXG4vLyB3cml0ZSgpIHNvbWUgbW9yZS5cblJlYWRhYmxlLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgaWYgKGVuY29kaW5nICE9PSBzdGF0ZS5lbmNvZGluZykge1xuICAgICAgY2h1bmsgPSBidWZmZXJTaGltLmZyb20oY2h1bmssIGVuY29kaW5nKTtcbiAgICAgIGVuY29kaW5nID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgZmFsc2UpO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgJycsIHRydWUpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLmlzUGF1c2VkID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nID09PSBmYWxzZTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBhZGRUb0Zyb250KSB7XG4gIHZhciBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIH0gZWxzZSBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc3RhdGUuZW5kZWQgJiYgIWFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRFbWl0dGVkICYmIGFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBfZSA9IG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIF9lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHNraXBBZGQ7XG4gICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhYWRkVG9Gcm9udCAmJiAhZW5jb2RpbmcpIHtcbiAgICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcbiAgICAgICAgc2tpcEFkZCA9ICFzdGF0ZS5vYmplY3RNb2RlICYmIGNodW5rLmxlbmd0aCA9PT0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFhZGRUb0Zyb250KSBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG5cbiAgICAgIC8vIERvbid0IGFkZCB0byB0aGUgYnVmZmVyIGlmIHdlJ3ZlIGRlY29kZWQgdG8gYW4gZW1wdHkgc3RyaW5nIGNodW5rIGFuZFxuICAgICAgLy8gd2UncmUgbm90IGluIG9iamVjdCBtb2RlXG4gICAgICBpZiAoIXNraXBBZGQpIHtcbiAgICAgICAgLy8gaWYgd2Ugd2FudCB0aGUgZGF0YSBub3csIGp1c3QgZW1pdCBpdC5cbiAgICAgICAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5zeW5jKSB7XG4gICAgICAgICAgc3RyZWFtLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG4gICAgICAgICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICAgICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICAgICAgaWYgKGFkZFRvRnJvbnQpIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcblxuICAgICAgICAgIGlmIChzdGF0ZS5uZWVkUmVhZGFibGUpIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFhZGRUb0Zyb250KSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSk7XG59XG5cbi8vIGlmIGl0J3MgcGFzdCB0aGUgaGlnaCB3YXRlciBtYXJrLCB3ZSBjYW4gcHVzaCBpbiBzb21lIG1vcmUuXG4vLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZVxuLy8gbW9yZSBieXRlcy4gIFRoaXMgaXMgdG8gd29yayBhcm91bmQgY2FzZXMgd2hlcmUgaHdtPTAsXG4vLyBzdWNoIGFzIHRoZSByZXBsLiAgQWxzbywgaWYgdGhlIHB1c2goKSB0cmlnZ2VyZWQgYVxuLy8gcmVhZGFibGUgZXZlbnQsIGFuZCB0aGUgdXNlciBjYWxsZWQgcmVhZChsYXJnZU51bWJlcikgc3VjaCB0aGF0XG4vLyBuZWVkUmVhZGFibGUgd2FzIHNldCwgdGhlbiB3ZSBvdWdodCB0byBwdXNoIG1vcmUsIHNvIHRoYXQgYW5vdGhlclxuLy8gJ3JlYWRhYmxlJyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZC5cbmZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSkge1xuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmIChzdGF0ZS5uZWVkUmVhZGFibGUgfHwgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgaWYgKCFTdHJpbmdEZWNvZGVyKSBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXIvJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBEb24ndCByYWlzZSB0aGUgaHdtID4gOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobikge1xuICBpZiAobiA+PSBNQVhfSFdNKSB7XG4gICAgbiA9IE1BWF9IV007XG4gIH0gZWxzZSB7XG4gICAgLy8gR2V0IHRoZSBuZXh0IGhpZ2hlc3QgcG93ZXIgb2YgMiB0byBwcmV2ZW50IGluY3JlYXNpbmcgaHdtIGV4Y2Vzc2l2ZWx5IGluXG4gICAgLy8gdGlueSBhbW91bnRzXG4gICAgbi0tO1xuICAgIG4gfD0gbiA+Pj4gMTtcbiAgICBuIHw9IG4gPj4+IDI7XG4gICAgbiB8PSBuID4+PiA0O1xuICAgIG4gfD0gbiA+Pj4gODtcbiAgICBuIHw9IG4gPj4+IDE2O1xuICAgIG4rKztcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBkZXNpZ25lZCB0byBiZSBpbmxpbmFibGUsIHNvIHBsZWFzZSB0YWtlIGNhcmUgd2hlbiBtYWtpbmdcbi8vIGNoYW5nZXMgdG8gdGhlIGZ1bmN0aW9uIGJvZHkuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChuIDw9IDAgfHwgc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSByZXR1cm4gMDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldHVybiAxO1xuICBpZiAobiAhPT0gbikge1xuICAgIC8vIE9ubHkgZmxvdyBvbmUgYnVmZmVyIGF0IGEgdGltZVxuICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmxlbmd0aCkgcmV0dXJuIHN0YXRlLmJ1ZmZlci5oZWFkLmRhdGEubGVuZ3RoO2Vsc2UgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgY3VycmVudCBod20sIHRoZW4gcmFpc2UgdGhlIGh3bS5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSBzdGF0ZS5oaWdoV2F0ZXJNYXJrID0gY29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7XG4gIGlmIChuIDw9IHN0YXRlLmxlbmd0aCkgcmV0dXJuIG47XG4gIC8vIERvbid0IGhhdmUgZW5vdWdoXG4gIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIHJldHVybiAwO1xuICB9XG4gIHJldHVybiBzdGF0ZS5sZW5ndGg7XG59XG5cbi8vIHlvdSBjYW4gb3ZlcnJpZGUgZWl0aGVyIHRoaXMgbWV0aG9kLCBvciB0aGUgYXN5bmMgX3JlYWQobikgYmVsb3cuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIGRlYnVnKCdyZWFkJywgbik7XG4gIG4gPSBwYXJzZUludChuLCAxMCk7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBuT3JpZyA9IG47XG5cbiAgaWYgKG4gIT09IDApIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUubmVlZFJlYWRhYmxlICYmIChzdGF0ZS5sZW5ndGggPj0gc3RhdGUuaGlnaFdhdGVyTWFyayB8fCBzdGF0ZS5lbmRlZCkpIHtcbiAgICBkZWJ1ZygncmVhZDogZW1pdFJlYWRhYmxlJywgc3RhdGUubGVuZ3RoLCBzdGF0ZS5lbmRlZCk7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkgZW5kUmVhZGFibGUodGhpcyk7ZWxzZSBlbWl0UmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBuID0gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSk7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQsIGFuZCB3ZSdyZSBub3cgY2xlYXIsIHRoZW4gZmluaXNoIGl0IHVwLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5lbmRlZCkge1xuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG4gIGRlYnVnKCduZWVkIHJlYWRhYmxlJywgZG9SZWFkKTtcblxuICAvLyBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBsZXNzIHRoYW4gdGhlIGhpZ2hXYXRlck1hcmssIHRoZW4gYWxzbyByZWFkIHNvbWVcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCB8fCBzdGF0ZS5sZW5ndGggLSBuIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRvUmVhZCA9IHRydWU7XG4gICAgZGVidWcoJ2xlbmd0aCBsZXNzIHRoYW4gd2F0ZXJtYXJrJywgZG9SZWFkKTtcbiAgfVxuXG4gIC8vIGhvd2V2ZXIsIGlmIHdlJ3ZlIGVuZGVkLCB0aGVuIHRoZXJlJ3Mgbm8gcG9pbnQsIGFuZCBpZiB3ZSdyZSBhbHJlYWR5XG4gIC8vIHJlYWRpbmcsIHRoZW4gaXQncyB1bm5lY2Vzc2FyeS5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpIHtcbiAgICBkb1JlYWQgPSBmYWxzZTtcbiAgICBkZWJ1ZygncmVhZGluZyBvciBlbmRlZCcsIGRvUmVhZCk7XG4gIH0gZWxzZSBpZiAoZG9SZWFkKSB7XG4gICAgZGVidWcoJ2RvIHJlYWQnKTtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICAgIC8vIElmIF9yZWFkIHB1c2hlZCBkYXRhIHN5bmNocm9ub3VzbHksIHRoZW4gYHJlYWRpbmdgIHdpbGwgYmUgZmFsc2UsXG4gICAgLy8gYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICAgIGlmICghc3RhdGUucmVhZGluZykgbiA9IGhvd011Y2hUb1JlYWQobk9yaWcsIHN0YXRlKTtcbiAgfVxuXG4gIHZhciByZXQ7XG4gIGlmIChuID4gMCkgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO2Vsc2UgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfSBlbHNlIHtcbiAgICBzdGF0ZS5sZW5ndGggLT0gbjtcbiAgfVxuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcblxuICAgIC8vIElmIHdlIHRyaWVkIHRvIHJlYWQoKSBwYXN0IHRoZSBFT0YsIHRoZW4gZW1pdCBlbmQgb24gdGhlIG5leHQgdGljay5cbiAgICBpZiAobk9yaWcgIT09IG4gJiYgc3RhdGUuZW5kZWQpIGVuZFJlYWRhYmxlKHRoaXMpO1xuICB9XG5cbiAgaWYgKHJldCAhPT0gbnVsbCkgdGhpcy5lbWl0KCdkYXRhJywgcmV0KTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5mdW5jdGlvbiBvbkVvZkNodW5rKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmVuZGVkKSByZXR1cm47XG4gIGlmIChzdGF0ZS5kZWNvZGVyKSB7XG4gICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSB7XG4gICAgICBzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7XG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgfVxuICB9XG4gIHN0YXRlLmVuZGVkID0gdHJ1ZTtcblxuICAvLyBlbWl0ICdyZWFkYWJsZScgbm93IHRvIG1ha2Ugc3VyZSBpdCBnZXRzIHBpY2tlZCB1cC5cbiAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmICghc3RhdGUuZW1pdHRlZFJlYWRhYmxlKSB7XG4gICAgZGVidWcoJ2VtaXRSZWFkYWJsZScsIHN0YXRlLmZsb3dpbmcpO1xuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgaWYgKHN0YXRlLnN5bmMpIHByb2Nlc3NOZXh0VGljayhlbWl0UmVhZGFibGVfLCBzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIGRlYnVnKCdlbWl0IHJlYWRhYmxlJyk7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICBmbG93KHN0cmVhbSk7XG59XG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlXyhzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIHdoaWxlICghc3RhdGUucmVhZGluZyAmJiAhc3RhdGUuZmxvd2luZyAmJiAhc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIGRlYnVnKCdtYXliZVJlYWRNb3JlIHJlYWQgMCcpO1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztlbHNlIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ19yZWFkKCkgaXMgbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG4gIGRlYnVnKCdwaXBlIGNvdW50PSVkIG9wdHM9JWonLCBzdGF0ZS5waXBlc0NvdW50LCBwaXBlT3B0cyk7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogY2xlYW51cDtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHByb2Nlc3NOZXh0VGljayhlbmRGbik7ZWxzZSBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpIHtcbiAgICBkZWJ1Zygnb251bnBpcGUnKTtcbiAgICBpZiAocmVhZGFibGUgPT09IHNyYykge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGRlYnVnKCdvbmVuZCcpO1xuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuICAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cbiAgdmFyIG9uZHJhaW4gPSBwaXBlT25EcmFpbihzcmMpO1xuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIHZhciBjbGVhbmVkVXAgPSBmYWxzZTtcbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBkZWJ1ZygnY2xlYW51cCcpO1xuICAgIC8vIGNsZWFudXAgZXZlbnQgaGFuZGxlcnMgb25jZSB0aGUgcGlwZSBpcyBicm9rZW5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcigndW5waXBlJywgb251bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuXG4gIC8vIElmIHRoZSB1c2VyIHB1c2hlcyBtb3JlIGRhdGEgd2hpbGUgd2UncmUgd3JpdGluZyB0byBkZXN0IHRoZW4gd2UnbGwgZW5kIHVwXG4gIC8vIGluIG9uZGF0YSBhZ2Fpbi4gSG93ZXZlciwgd2Ugb25seSB3YW50IHRvIGluY3JlYXNlIGF3YWl0RHJhaW4gb25jZSBiZWNhdXNlXG4gIC8vIGRlc3Qgd2lsbCBvbmx5IGVtaXQgb25lICdkcmFpbicgZXZlbnQgZm9yIHRoZSBtdWx0aXBsZSB3cml0ZXMuXG4gIC8vID0+IEludHJvZHVjZSBhIGd1YXJkIG9uIGluY3JlYXNpbmcgYXdhaXREcmFpbi5cbiAgdmFyIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgc3JjLm9uKCdkYXRhJywgb25kYXRhKTtcbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgZGVidWcoJ29uZGF0YScpO1xuICAgIGluY3JlYXNlZEF3YWl0RHJhaW4gPSBmYWxzZTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgaWYgKGZhbHNlID09PSByZXQgJiYgIWluY3JlYXNlZEF3YWl0RHJhaW4pIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHVucGlwZWQgZHVyaW5nIGBkZXN0LndyaXRlKClgLCBpdCBpcyBwb3NzaWJsZVxuICAgICAgLy8gdG8gZ2V0IHN0dWNrIGluIGEgcGVybWFuZW50bHkgcGF1c2VkIHN0YXRlIGlmIHRoYXQgd3JpdGVcbiAgICAgIC8vIGFsc28gcmV0dXJuZWQgZmFsc2UuXG4gICAgICAvLyA9PiBDaGVjayB3aGV0aGVyIGBkZXN0YCBpcyBzdGlsbCBhIHBpcGluZyBkZXN0aW5hdGlvbi5cbiAgICAgIGlmICgoc3RhdGUucGlwZXNDb3VudCA9PT0gMSAmJiBzdGF0ZS5waXBlcyA9PT0gZGVzdCB8fCBzdGF0ZS5waXBlc0NvdW50ID4gMSAmJiBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KSAhPT0gLTEpICYmICFjbGVhbmVkVXApIHtcbiAgICAgICAgZGVidWcoJ2ZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZScsIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgICAgaW5jcmVhc2VkQXdhaXREcmFpbiA9IHRydWU7XG4gICAgICB9XG4gICAgICBzcmMucGF1c2UoKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgZGVidWcoJ29uZXJyb3InLCBlcik7XG4gICAgdW5waXBlKCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBpZiAoRUVsaXN0ZW5lckNvdW50KGRlc3QsICdlcnJvcicpID09PSAwKSBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIG91ciBlcnJvciBoYW5kbGVyIGlzIGF0dGFjaGVkIGJlZm9yZSB1c2VybGFuZCBvbmVzLlxuICBwcmVwZW5kTGlzdGVuZXIoZGVzdCwgJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gQm90aCBjbG9zZSBhbmQgZmluaXNoIHNob3VsZCB0cmlnZ2VyIHVucGlwZSwgYnV0IG9ubHkgb25jZS5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICBmdW5jdGlvbiBvbmZpbmlzaCgpIHtcbiAgICBkZWJ1Zygnb25maW5pc2gnKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnZmluaXNoJywgb25maW5pc2gpO1xuXG4gIGZ1bmN0aW9uIHVucGlwZSgpIHtcbiAgICBkZWJ1ZygndW5waXBlJyk7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGlwZSByZXN1bWUnKTtcbiAgICBzcmMucmVzdW1lKCk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBkZWJ1ZygncGlwZU9uRHJhaW4nLCBzdGF0ZS5hd2FpdERyYWluKTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbikgc3RhdGUuYXdhaXREcmFpbi0tO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluID09PSAwICYmIEVFbGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykpIHtcbiAgICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgICAgZmxvdyhzcmMpO1xuICAgIH1cbiAgfTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uIChkZXN0KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gaWYgd2UncmUgbm90IHBpcGluZyBhbnl3aGVyZSwgdGhlbiBkbyBub3RoaW5nLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKSByZXR1cm4gdGhpcztcblxuICAgIGlmICghZGVzdCkgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdCkgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgZGVzdHNbaV0uZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgfXJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGluZGV4ID0gaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpbmRleCA9PT0gLTEpIHJldHVybiB0aGlzO1xuXG4gIHN0YXRlLnBpcGVzLnNwbGljZShpbmRleCwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHN0YXRlLnBpcGVzID0gc3RhdGUucGlwZXNbMF07XG5cbiAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIHNldCB1cCBkYXRhIGV2ZW50cyBpZiB0aGV5IGFyZSBhc2tlZCBmb3Jcbi8vIEVuc3VyZSByZWFkYWJsZSBsaXN0ZW5lcnMgZXZlbnR1YWxseSBnZXQgc29tZXRoaW5nXG5SZWFkYWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICBpZiAoZXYgPT09ICdkYXRhJykge1xuICAgIC8vIFN0YXJ0IGZsb3dpbmcgb24gbmV4dCB0aWNrIGlmIHN0cmVhbSBpc24ndCBleHBsaWNpdGx5IHBhdXNlZFxuICAgIGlmICh0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgIT09IGZhbHNlKSB0aGlzLnJlc3VtZSgpO1xuICB9IGVsc2UgaWYgKGV2ID09PSAncmVhZGFibGUnKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIGlmICghc3RhdGUucmVhZGluZykge1xuICAgICAgICBwcm9jZXNzTmV4dFRpY2soblJlYWRpbmdOZXh0VGljaywgdGhpcyk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxlbmd0aCkge1xuICAgICAgICBlbWl0UmVhZGFibGUodGhpcywgc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdyZXN1bWUnKTtcbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICByZXN1bWUodGhpcywgc3RhdGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhyZXN1bWVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcbiAgc3RyZWFtLmVtaXQoJ3Jlc3VtZScpO1xuICBmbG93KHN0cmVhbSk7XG4gIGlmIChzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5yZWFkaW5nKSBzdHJlYW0ucmVhZCgwKTtcbn1cblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xuICBkZWJ1ZygnY2FsbCBwYXVzZSBmbG93aW5nPSVqJywgdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKTtcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICBkZWJ1ZygncGF1c2UnKTtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBmbG93KHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIGRlYnVnKCdmbG93Jywgc3RhdGUuZmxvd2luZyk7XG4gIHdoaWxlIChzdGF0ZS5mbG93aW5nICYmIHN0cmVhbS5yZWFkKCkgIT09IG51bGwpIHt9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBzZWxmLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIHNlbGYucHVzaChudWxsKTtcbiAgfSk7XG5cbiAgc3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZGF0YScpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgLy8gZG9uJ3Qgc2tpcCBvdmVyIGZhbHN5IHZhbHVlcyBpbiBvYmplY3RNb2RlXG4gICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgJiYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpKSByZXR1cm47ZWxzZSBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgKCFjaHVuayB8fCAhY2h1bmsubGVuZ3RoKSkgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IHNlbGYucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICB9KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgZm9yICh2YXIgbiA9IDA7IG4gPCBrUHJveHlFdmVudHMubGVuZ3RoOyBuKyspIHtcbiAgICBzdHJlYW0ub24oa1Byb3h5RXZlbnRzW25dLCBzZWxmLmVtaXQuYmluZChzZWxmLCBrUHJveHlFdmVudHNbbl0pKTtcbiAgfVxuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICAgIGRlYnVnKCd3cmFwcGVkIF9yZWFkJywgbik7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuLy8gZXhwb3NlZCBmb3IgdGVzdGluZyBwdXJwb3NlcyBvbmx5LlxuUmVhZGFibGUuX2Zyb21MaXN0ID0gZnJvbUxpc3Q7XG5cbi8vIFBsdWNrIG9mZiBuIGJ5dGVzIGZyb20gYW4gYXJyYXkgb2YgYnVmZmVycy5cbi8vIExlbmd0aCBpcyB0aGUgY29tYmluZWQgbGVuZ3RocyBvZiBhbGwgdGhlIGJ1ZmZlcnMgaW4gdGhlIGxpc3QuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGZyb21MaXN0KG4sIHN0YXRlKSB7XG4gIC8vIG5vdGhpbmcgYnVmZmVyZWRcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHJldDtcbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpIHJldCA9IHN0YXRlLmJ1ZmZlci5zaGlmdCgpO2Vsc2UgaWYgKCFuIHx8IG4gPj0gc3RhdGUubGVuZ3RoKSB7XG4gICAgLy8gcmVhZCBpdCBhbGwsIHRydW5jYXRlIHRoZSBsaXN0XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpIHJldCA9IHN0YXRlLmJ1ZmZlci5qb2luKCcnKTtlbHNlIGlmIChzdGF0ZS5idWZmZXIubGVuZ3RoID09PSAxKSByZXQgPSBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhO2Vsc2UgcmV0ID0gc3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO1xuICAgIHN0YXRlLmJ1ZmZlci5jbGVhcigpO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQgcGFydCBvZiBsaXN0XG4gICAgcmV0ID0gZnJvbUxpc3RQYXJ0aWFsKG4sIHN0YXRlLmJ1ZmZlciwgc3RhdGUuZGVjb2Rlcik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG4vLyBFeHRyYWN0cyBvbmx5IGVub3VnaCBidWZmZXJlZCBkYXRhIHRvIHNhdGlzZnkgdGhlIGFtb3VudCByZXF1ZXN0ZWQuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGZyb21MaXN0UGFydGlhbChuLCBsaXN0LCBoYXNTdHJpbmdzKSB7XG4gIHZhciByZXQ7XG4gIGlmIChuIDwgbGlzdC5oZWFkLmRhdGEubGVuZ3RoKSB7XG4gICAgLy8gc2xpY2UgaXMgdGhlIHNhbWUgZm9yIGJ1ZmZlcnMgYW5kIHN0cmluZ3NcbiAgICByZXQgPSBsaXN0LmhlYWQuZGF0YS5zbGljZSgwLCBuKTtcbiAgICBsaXN0LmhlYWQuZGF0YSA9IGxpc3QuaGVhZC5kYXRhLnNsaWNlKG4pO1xuICB9IGVsc2UgaWYgKG4gPT09IGxpc3QuaGVhZC5kYXRhLmxlbmd0aCkge1xuICAgIC8vIGZpcnN0IGNodW5rIGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgIHJldCA9IGxpc3Quc2hpZnQoKTtcbiAgfSBlbHNlIHtcbiAgICAvLyByZXN1bHQgc3BhbnMgbW9yZSB0aGFuIG9uZSBidWZmZXJcbiAgICByZXQgPSBoYXNTdHJpbmdzID8gY29weUZyb21CdWZmZXJTdHJpbmcobiwgbGlzdCkgOiBjb3B5RnJvbUJ1ZmZlcihuLCBsaXN0KTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG4vLyBDb3BpZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGNoYXJhY3RlcnMgZnJvbSB0aGUgbGlzdCBvZiBidWZmZXJlZCBkYXRhXG4vLyBjaHVua3MuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyU3RyaW5nKG4sIGxpc3QpIHtcbiAgdmFyIHAgPSBsaXN0LmhlYWQ7XG4gIHZhciBjID0gMTtcbiAgdmFyIHJldCA9IHAuZGF0YTtcbiAgbiAtPSByZXQubGVuZ3RoO1xuICB3aGlsZSAocCA9IHAubmV4dCkge1xuICAgIHZhciBzdHIgPSBwLmRhdGE7XG4gICAgdmFyIG5iID0gbiA+IHN0ci5sZW5ndGggPyBzdHIubGVuZ3RoIDogbjtcbiAgICBpZiAobmIgPT09IHN0ci5sZW5ndGgpIHJldCArPSBzdHI7ZWxzZSByZXQgKz0gc3RyLnNsaWNlKDAsIG4pO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gc3RyLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBzdHIuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG4vLyBDb3BpZXMgYSBzcGVjaWZpZWQgYW1vdW50IG9mIGJ5dGVzIGZyb20gdGhlIGxpc3Qgb2YgYnVmZmVyZWQgZGF0YSBjaHVua3MuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGRlc2lnbmVkIHRvIGJlIGlubGluYWJsZSwgc28gcGxlYXNlIHRha2UgY2FyZSB3aGVuIG1ha2luZ1xuLy8gY2hhbmdlcyB0byB0aGUgZnVuY3Rpb24gYm9keS5cbmZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyKG4sIGxpc3QpIHtcbiAgdmFyIHJldCA9IGJ1ZmZlclNoaW0uYWxsb2NVbnNhZmUobik7XG4gIHZhciBwID0gbGlzdC5oZWFkO1xuICB2YXIgYyA9IDE7XG4gIHAuZGF0YS5jb3B5KHJldCk7XG4gIG4gLT0gcC5kYXRhLmxlbmd0aDtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICB2YXIgYnVmID0gcC5kYXRhO1xuICAgIHZhciBuYiA9IG4gPiBidWYubGVuZ3RoID8gYnVmLmxlbmd0aCA6IG47XG4gICAgYnVmLmNvcHkocmV0LCByZXQubGVuZ3RoIC0gbiwgMCwgbmIpO1xuICAgIG4gLT0gbmI7XG4gICAgaWYgKG4gPT09IDApIHtcbiAgICAgIGlmIChuYiA9PT0gYnVmLmxlbmd0aCkge1xuICAgICAgICArK2M7XG4gICAgICAgIGlmIChwLm5leHQpIGxpc3QuaGVhZCA9IHAubmV4dDtlbHNlIGxpc3QuaGVhZCA9IGxpc3QudGFpbCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaXN0LmhlYWQgPSBwO1xuICAgICAgICBwLmRhdGEgPSBidWYuc2xpY2UobmIpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsrYztcbiAgfVxuICBsaXN0Lmxlbmd0aCAtPSBjO1xuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIElmIHdlIGdldCBoZXJlIGJlZm9yZSBjb25zdW1pbmcgYWxsIHRoZSBieXRlcywgdGhlbiB0aGF0IGlzIGFcbiAgLy8gYnVnIGluIG5vZGUuICBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2soZW5kUmVhZGFibGVOVCwgc3RhdGUsIHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGVOVChzdGF0ZSwgc3RyZWFtKSB7XG4gIC8vIENoZWNrIHRoYXQgd2UgZGlkbid0IGdldCBvbmUgbGFzdCB1bnNoaWZ0LlxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgc3RyZWFtLnJlYWRhYmxlID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZvckVhY2goeHMsIGYpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB4cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBmKHhzW2ldLCBpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmRleE9mKHhzLCB4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59IiwiLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG4ndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLCBEdXBsZXgpO1xuXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdGF0ZShzdHJlYW0pIHtcbiAgdGhpcy5hZnRlclRyYW5zZm9ybSA9IGZ1bmN0aW9uIChlciwgZGF0YSkge1xuICAgIHJldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKTtcbiAgfTtcblxuICB0aGlzLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgdGhpcy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcbiAgdGhpcy53cml0ZWNodW5rID0gbnVsbDtcbiAgdGhpcy53cml0ZWVuY29kaW5nID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSkge1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuICB0cy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcblxuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuXG4gIGlmICghY2IpIHJldHVybiBzdHJlYW0uZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vIHdyaXRlY2IgaW4gVHJhbnNmb3JtIGNsYXNzJykpO1xuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcblxuICBpZiAoZGF0YSAhPT0gbnVsbCAmJiBkYXRhICE9PSB1bmRlZmluZWQpIHN0cmVhbS5wdXNoKGRhdGEpO1xuXG4gIGNiKGVyKTtcblxuICB2YXIgcnMgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcbiAgaWYgKHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgc3RyZWFtLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59XG5cbmZ1bmN0aW9uIFRyYW5zZm9ybShvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBUcmFuc2Zvcm0pKSByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcblxuICBEdXBsZXguY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZSA9IG5ldyBUcmFuc2Zvcm1TdGF0ZSh0aGlzKTtcblxuICB2YXIgc3RyZWFtID0gdGhpcztcblxuICAvLyBzdGFydCBvdXQgYXNraW5nIGZvciBhIHJlYWRhYmxlIGV2ZW50IG9uY2UgZGF0YSBpcyB0cmFuc2Zvcm1lZC5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIHdlIGhhdmUgaW1wbGVtZW50ZWQgdGhlIF9yZWFkIG1ldGhvZCwgYW5kIGRvbmUgdGhlIG90aGVyIHRoaW5nc1xuICAvLyB0aGF0IFJlYWRhYmxlIHdhbnRzIGJlZm9yZSB0aGUgZmlyc3QgX3JlYWQgY2FsbCwgc28gdW5zZXQgdGhlXG4gIC8vIHN5bmMgZ3VhcmQgZmxhZy5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtID09PSAnZnVuY3Rpb24nKSB0aGlzLl90cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2ggPSBvcHRpb25zLmZsdXNoO1xuICB9XG5cbiAgLy8gV2hlbiB0aGUgd3JpdGFibGUgc2lkZSBmaW5pc2hlcywgdGhlbiBmbHVzaCBvdXQgYW55dGhpbmcgcmVtYWluaW5nLlxuICB0aGlzLm9uY2UoJ3ByZWZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuX2ZsdXNoID09PSAnZnVuY3Rpb24nKSB0aGlzLl9mbHVzaChmdW5jdGlvbiAoZXIsIGRhdGEpIHtcbiAgICAgIGRvbmUoc3RyZWFtLCBlciwgZGF0YSk7XG4gICAgfSk7ZWxzZSBkb25lKHN0cmVhbSk7XG4gIH0pO1xufVxuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdHJhbnNmb3JtKCkgaXMgbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZCkgc3RyZWFtLnB1c2goZGF0YSk7XG5cbiAgLy8gaWYgdGhlcmUncyBub3RoaW5nIGluIHRoZSB3cml0ZSBidWZmZXIsIHRoZW4gdGhhdCBtZWFuc1xuICAvLyB0aGF0IG5vdGhpbmcgbW9yZSB3aWxsIGV2ZXIgYmUgcHJvdmlkZWRcbiAgdmFyIHdzID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuXG4gIGlmICh3cy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignQ2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHdzLmxlbmd0aCAhPSAwJyk7XG5cbiAgaWYgKHRzLnRyYW5zZm9ybWluZykgdGhyb3cgbmV3IEVycm9yKCdDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nJyk7XG5cbiAgcmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpO1xufSIsIi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBjYiksIGFuZCBpdCdsbCBoYW5kbGUgYWxsXG4vLyB0aGUgZHJhaW4gZXZlbnQgZW1pc3Npb24gYW5kIGJ1ZmZlcmluZy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBhc3luY1dyaXRlID0gIXByb2Nlc3MuYnJvd3NlciAmJiBbJ3YwLjEwJywgJ3YwLjkuJ10uaW5kZXhPZihwcm9jZXNzLnZlcnNpb24uc2xpY2UoMCwgNSkpID4gLTEgPyBzZXRJbW1lZGlhdGUgOiBwcm9jZXNzTmV4dFRpY2s7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBEdXBsZXg7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgdXRpbCA9IHJlcXVpcmUoJ2NvcmUtdXRpbC1pcycpO1xudXRpbC5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBpbnRlcm5hbFV0aWwgPSB7XG4gIGRlcHJlY2F0ZTogcmVxdWlyZSgndXRpbC1kZXByZWNhdGUnKVxufTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJy4vaW50ZXJuYWwvc3RyZWFtcy9zdHJlYW0nKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBidWZmZXJTaGltID0gcmVxdWlyZSgnYnVmZmVyLXNoaW1zJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudXRpbC5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gbm9wKCkge31cblxuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB2YXIgZGVmYXVsdEh3bSA9IHRoaXMub2JqZWN0TW9kZSA/IDE2IDogMTYgKiAxMDI0O1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBod20gfHwgaHdtID09PSAwID8gaHdtIDogZGVmYXVsdEh3bTtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH5+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIC8vIGRyYWluIGV2ZW50IGZsYWcuXG4gIHRoaXMubmVlZERyYWluID0gZmFsc2U7XG4gIC8vIGF0IHRoZSBzdGFydCBvZiBjYWxsaW5nIGVuZCgpXG4gIHRoaXMuZW5kaW5nID0gZmFsc2U7XG4gIC8vIHdoZW4gZW5kKCkgaGFzIGJlZW4gY2FsbGVkLCBhbmQgcmV0dXJuZWRcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAvLyB3aGVuICdmaW5pc2gnIGlzIGVtaXR0ZWRcbiAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIHNob3VsZCB3ZSBkZWNvZGUgc3RyaW5ncyBpbnRvIGJ1ZmZlcnMgYmVmb3JlIHBhc3NpbmcgdG8gX3dyaXRlP1xuICAvLyB0aGlzIGlzIGhlcmUgc28gdGhhdCBzb21lIG5vZGUtY29yZSBzdHJlYW1zIGNhbiBvcHRpbWl6ZSBzdHJpbmdcbiAgLy8gaGFuZGxpbmcgYXQgYSBsb3dlciBsZXZlbC5cbiAgdmFyIG5vRGVjb2RlID0gb3B0aW9ucy5kZWNvZGVTdHJpbmdzID09PSBmYWxzZTtcbiAgdGhpcy5kZWNvZGVTdHJpbmdzID0gIW5vRGVjb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIG5vdCBhbiBhY3R1YWwgYnVmZmVyIHdlIGtlZXAgdHJhY2sgb2YsIGJ1dCBhIG1lYXN1cmVtZW50XG4gIC8vIG9mIGhvdyBtdWNoIHdlJ3JlIHdhaXRpbmcgdG8gZ2V0IHB1c2hlZCB0byBzb21lIHVuZGVybHlpbmdcbiAgLy8gc29ja2V0IG9yIGZpbGUuXG4gIHRoaXMubGVuZ3RoID0gMDtcblxuICAvLyBhIGZsYWcgdG8gc2VlIHdoZW4gd2UncmUgaW4gdGhlIG1pZGRsZSBvZiBhIHdyaXRlLlxuICB0aGlzLndyaXRpbmcgPSBmYWxzZTtcblxuICAvLyB3aGVuIHRydWUgYWxsIHdyaXRlcyB3aWxsIGJlIGJ1ZmZlcmVkIHVudGlsIC51bmNvcmsoKSBjYWxsXG4gIHRoaXMuY29ya2VkID0gMDtcblxuICAvLyBhIGZsYWcgdG8gYmUgYWJsZSB0byB0ZWxsIGlmIHRoZSBvbndyaXRlIGNiIGlzIGNhbGxlZCBpbW1lZGlhdGVseSxcbiAgLy8gb3Igb24gYSBsYXRlciB0aWNrLiAgV2Ugc2V0IHRoaXMgdG8gdHJ1ZSBhdCBmaXJzdCwgYmVjYXVzZSBhbnlcbiAgLy8gYWN0aW9ucyB0aGF0IHNob3VsZG4ndCBoYXBwZW4gdW50aWwgXCJsYXRlclwiIHNob3VsZCBnZW5lcmFsbHkgYWxzb1xuICAvLyBub3QgaGFwcGVuIGJlZm9yZSB0aGUgZmlyc3Qgd3JpdGUgY2FsbC5cbiAgdGhpcy5zeW5jID0gdHJ1ZTtcblxuICAvLyBhIGZsYWcgdG8ga25vdyBpZiB3ZSdyZSBwcm9jZXNzaW5nIHByZXZpb3VzbHkgYnVmZmVyZWQgaXRlbXMsIHdoaWNoXG4gIC8vIG1heSBjYWxsIHRoZSBfd3JpdGUoKSBjYWxsYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyB0aGF0IHdlIGRvbid0XG4gIC8vIGVuZCB1cCBpbiBhbiBvdmVybGFwcGVkIG9ud3JpdGUgc2l0dWF0aW9uLlxuICB0aGlzLmJ1ZmZlclByb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCdzIHBhc3NlZCB0byBfd3JpdGUoY2h1bmssY2IpXG4gIHRoaXMub253cml0ZSA9IGZ1bmN0aW9uIChlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gIHRoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG5cbiAgLy8gbnVtYmVyIG9mIHBlbmRpbmcgdXNlci1zdXBwbGllZCB3cml0ZSBjYWxsYmFja3NcbiAgLy8gdGhpcyBtdXN0IGJlIDAgYmVmb3JlICdmaW5pc2gnIGNhbiBiZSBlbWl0dGVkXG4gIHRoaXMucGVuZGluZ2NiID0gMDtcblxuICAvLyBlbWl0IHByZWZpbmlzaCBpZiB0aGUgb25seSB0aGluZyB3ZSdyZSB3YWl0aW5nIGZvciBpcyBfd3JpdGUgY2JzXG4gIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHN5bmNocm9ub3VzIFRyYW5zZm9ybSBzdHJlYW1zXG4gIHRoaXMucHJlZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBUcnVlIGlmIHRoZSBlcnJvciB3YXMgYWxyZWFkeSBlbWl0dGVkIGFuZCBzaG91bGQgbm90IGJlIHRocm93biBhZ2FpblxuICB0aGlzLmVycm9yRW1pdHRlZCA9IGZhbHNlO1xuXG4gIC8vIGNvdW50IGJ1ZmZlcmVkIHJlcXVlc3RzXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuXG4gIC8vIGFsbG9jYXRlIHRoZSBmaXJzdCBDb3JrZWRSZXF1ZXN0LCB0aGVyZSBpcyBhbHdheXNcbiAgLy8gb25lIGFsbG9jYXRlZCBhbmQgZnJlZSB0byB1c2UsIGFuZCB3ZSBtYWludGFpbiBhdCBtb3N0IHR3b1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xufVxuXG5Xcml0YWJsZVN0YXRlLnByb3RvdHlwZS5nZXRCdWZmZXIgPSBmdW5jdGlvbiBnZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nKVxuICAgIH0pO1xuICB9IGNhdGNoIChfKSB7fVxufSkoKTtcblxuLy8gVGVzdCBfd3JpdGFibGVTdGF0ZSBmb3IgaW5oZXJpdGFuY2UgdG8gYWNjb3VudCBmb3IgRHVwbGV4IHN0cmVhbXMsXG4vLyB3aG9zZSBwcm90b3R5cGUgY2hhaW4gb25seSBwb2ludHMgdG8gUmVhZGFibGUuXG52YXIgcmVhbEhhc0luc3RhbmNlO1xuaWYgKHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgU3ltYm9sLmhhc0luc3RhbmNlICYmIHR5cGVvZiBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXSA9PT0gJ2Z1bmN0aW9uJykge1xuICByZWFsSGFzSW5zdGFuY2UgPSBGdW5jdGlvbi5wcm90b3R5cGVbU3ltYm9sLmhhc0luc3RhbmNlXTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFdyaXRhYmxlLCBTeW1ib2wuaGFzSW5zdGFuY2UsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgaWYgKHJlYWxIYXNJbnN0YW5jZS5jYWxsKHRoaXMsIG9iamVjdCkpIHJldHVybiB0cnVlO1xuXG4gICAgICByZXR1cm4gb2JqZWN0ICYmIG9iamVjdC5fd3JpdGFibGVTdGF0ZSBpbnN0YW5jZW9mIFdyaXRhYmxlU3RhdGU7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIHJlYWxIYXNJbnN0YW5jZSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgdGhpcztcbiAgfTtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIC8vIFdyaXRhYmxlIGN0b3IgaXMgYXBwbGllZCB0byBEdXBsZXhlcywgdG9vLlxuICAvLyBgcmVhbEhhc0luc3RhbmNlYCBpcyBuZWNlc3NhcnkgYmVjYXVzZSB1c2luZyBwbGFpbiBgaW5zdGFuY2VvZmBcbiAgLy8gd291bGQgcmV0dXJuIGZhbHNlLCBhcyBubyBgX3dyaXRhYmxlU3RhdGVgIHByb3BlcnR5IGlzIGF0dGFjaGVkLlxuXG4gIC8vIFRyeWluZyB0byB1c2UgdGhlIGN1c3RvbSBgaW5zdGFuY2VvZmAgZm9yIFdyaXRhYmxlIGhlcmUgd2lsbCBhbHNvIGJyZWFrIHRoZVxuICAvLyBOb2RlLmpzIExhenlUcmFuc2Zvcm0gaW1wbGVtZW50YXRpb24sIHdoaWNoIGhhcyBhIG5vbi10cml2aWFsIGdldHRlciBmb3JcbiAgLy8gYF93cml0YWJsZVN0YXRlYCB0aGF0IHdvdWxkIGxlYWQgdG8gaW5maW5pdGUgcmVjdXJzaW9uLlxuICBpZiAoIXJlYWxIYXNJbnN0YW5jZS5jYWxsKFdyaXRhYmxlLCB0aGlzKSAmJiAhKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKSB7XG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTtcbiAgfVxuXG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSBuZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3kuXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRlID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZSA9IG9wdGlvbnMud3JpdGU7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMud3JpdGV2ID09PSAnZnVuY3Rpb24nKSB0aGlzLl93cml0ZXYgPSBvcHRpb25zLndyaXRldjtcbiAgfVxuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBPdGhlcndpc2UgcGVvcGxlIGNhbiBwaXBlIFdyaXRhYmxlIHN0cmVhbXMsIHdoaWNoIGlzIGp1c3Qgd3JvbmcuXG5Xcml0YWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZScpKTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBhIHVzZXItc3VwcGxpZWQgY2h1bmsgaXMgdmFsaWQsIGVzcGVjaWFsbHkgZm9yIHRoZSBwYXJ0aWN1bGFyXG4vLyBtb2RlIHRoZSBzdHJlYW0gaXMgaW4uIEN1cnJlbnRseSB0aGlzIG1lYW5zIHRoYXQgYG51bGxgIGlzIG5ldmVyIGFjY2VwdGVkXG4vLyBhbmQgdW5kZWZpbmVkL25vbi1zdHJpbmcgdmFsdWVzIGFyZSBvbmx5IGFsbG93ZWQgaW4gb2JqZWN0IG1vZGUuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuICB2YXIgZXIgPSBmYWxzZTtcblxuICBpZiAoY2h1bmsgPT09IG51bGwpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ01heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtJyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgaWYgKGVyKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHByb2Nlc3NOZXh0VGljayhjYiwgZXIpO1xuICAgIHZhbGlkID0gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHZhbGlkO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG4gIHZhciBpc0J1ZiA9IEJ1ZmZlci5pc0J1ZmZlcihjaHVuayk7XG5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKGlzQnVmKSBlbmNvZGluZyA9ICdidWZmZXInO2Vsc2UgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgY2IgPSBub3A7XG5cbiAgaWYgKHN0YXRlLmVuZGVkKSB3cml0ZUFmdGVyRW5kKHRoaXMsIGNiKTtlbHNlIGlmIChpc0J1ZiB8fCB2YWxpZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgY2IpKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgcmV0ID0gd3JpdGVPckJ1ZmZlcih0aGlzLCBzdGF0ZSwgaXNCdWYsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIHN0YXRlLmNvcmtlZCsrO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnVuY29yayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuY29ya2VkKSB7XG4gICAgc3RhdGUuY29ya2VkLS07XG5cbiAgICBpZiAoIXN0YXRlLndyaXRpbmcgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuZmluaXNoZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSBjbGVhckJ1ZmZlcih0aGlzLCBzdGF0ZSk7XG4gIH1cbn07XG5cbldyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2RpbmcgPSBmdW5jdGlvbiBzZXREZWZhdWx0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgLy8gbm9kZTo6UGFyc2VFbmNvZGluZygpIHJlcXVpcmVzIGxvd2VyIGNhc2UuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdzdHJpbmcnKSBlbmNvZGluZyA9IGVuY29kaW5nLnRvTG93ZXJDYXNlKCk7XG4gIGlmICghKFsnaGV4JywgJ3V0ZjgnLCAndXRmLTgnLCAnYXNjaWknLCAnYmluYXJ5JywgJ2Jhc2U2NCcsICd1Y3MyJywgJ3Vjcy0yJywgJ3V0ZjE2bGUnLCAndXRmLTE2bGUnLCAncmF3J10uaW5kZXhPZigoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkgPiAtMSkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nID0gZW5jb2Rpbmc7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gZGVjb2RlQ2h1bmsoc3RhdGUsIGNodW5rLCBlbmNvZGluZykge1xuICBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiYgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gYnVmZmVyU2hpbS5mcm9tKGNodW5rLCBlbmNvZGluZyk7XG4gIH1cbiAgcmV0dXJuIGNodW5rO1xufVxuXG4vLyBpZiB3ZSdyZSBhbHJlYWR5IHdyaXRpbmcgc29tZXRoaW5nLCB0aGVuIGp1c3QgcHV0IHRoaXNcbi8vIGluIHRoZSBxdWV1ZSwgYW5kIHdhaXQgb3VyIHR1cm4uICBPdGhlcndpc2UsIGNhbGwgX3dyaXRlXG4vLyBJZiB3ZSByZXR1cm4gZmFsc2UsIHRoZW4gd2UgbmVlZCBhIGRyYWluIGV2ZW50LCBzbyBzZXQgdGhhdCBmbGFnLlxuZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sIHN0YXRlLCBpc0J1ZiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBpZiAoIWlzQnVmKSB7XG4gICAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgfVxuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgLy8gd2UgbXVzdCBlbnN1cmUgdGhhdCBwcmV2aW91cyBuZWVkRHJhaW4gd2lsbCBub3QgYmUgcmVzZXQgdG8gZmFsc2UuXG4gIGlmICghcmV0KSBzdGF0ZS5uZWVkRHJhaW4gPSB0cnVlO1xuXG4gIGlmIChzdGF0ZS53cml0aW5nIHx8IHN0YXRlLmNvcmtlZCkge1xuICAgIHZhciBsYXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbmV3IFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpO1xuICAgIGlmIChsYXN0KSB7XG4gICAgICBsYXN0Lm5leHQgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0O1xuICAgIH1cbiAgICBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudCArPSAxO1xuICB9IGVsc2Uge1xuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmFsc2UsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHdyaXRldiwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgaWYgKHdyaXRldikgc3RyZWFtLl93cml0ZXYoY2h1bmssIHN0YXRlLm9ud3JpdGUpO2Vsc2Ugc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpIHtcbiAgLS1zdGF0ZS5wZW5kaW5nY2I7XG4gIGlmIChzeW5jKSBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtlbHNlIGNiKGVyKTtcblxuICBzdHJlYW0uX3dyaXRhYmxlU3RhdGUuZXJyb3JFbWl0dGVkID0gdHJ1ZTtcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcikgb253cml0ZUVycm9yKHN0cmVhbSwgc3RhdGUsIHN5bmMsIGVyLCBjYik7ZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0YXRlKTtcblxuICAgIGlmICghZmluaXNoZWQgJiYgIXN0YXRlLmNvcmtlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIHtcbiAgICAgIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cblxuICAgIGlmIChzeW5jKSB7XG4gICAgICAvKjxyZXBsYWNlbWVudD4qL1xuICAgICAgYXN5bmNXcml0ZShhZnRlcldyaXRlLCBzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgLyo8L3JlcGxhY2VtZW50PiovXG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZCkgb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpO1xuICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgY2IoKTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG59XG5cbi8vIE11c3QgZm9yY2UgY2FsbGJhY2sgdG8gYmUgY2FsbGVkIG9uIG5leHRUaWNrLCBzbyB0aGF0IHdlIGRvbid0XG4vLyBlbWl0ICdkcmFpbicgYmVmb3JlIHRoZSB3cml0ZSgpIGNvbnN1bWVyIGdldHMgdGhlICdmYWxzZScgcmV0dXJuXG4vLyB2YWx1ZSwgYW5kIGhhcyBhIGNoYW5jZSB0byBhdHRhY2ggYSAnZHJhaW4nIGxpc3RlbmVyLlxuZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiBzdGF0ZS5uZWVkRHJhaW4pIHtcbiAgICBzdGF0ZS5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgICBzdHJlYW0uZW1pdCgnZHJhaW4nKTtcbiAgfVxufVxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgdmFyIGVudHJ5ID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0O1xuXG4gIGlmIChzdHJlYW0uX3dyaXRldiAmJiBlbnRyeSAmJiBlbnRyeS5uZXh0KSB7XG4gICAgLy8gRmFzdCBjYXNlLCB3cml0ZSBldmVyeXRoaW5nIHVzaW5nIF93cml0ZXYoKVxuICAgIHZhciBsID0gc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQ7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheShsKTtcbiAgICB2YXIgaG9sZGVyID0gc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO1xuICAgIGhvbGRlci5lbnRyeSA9IGVudHJ5O1xuXG4gICAgdmFyIGNvdW50ID0gMDtcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGJ1ZmZlcltjb3VudF0gPSBlbnRyeTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIGNvdW50ICs9IDE7XG4gICAgfVxuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB0cnVlLCBzdGF0ZS5sZW5ndGgsIGJ1ZmZlciwgJycsIGhvbGRlci5maW5pc2gpO1xuXG4gICAgLy8gZG9Xcml0ZSBpcyBhbG1vc3QgYWx3YXlzIGFzeW5jLCBkZWZlciB0aGVzZSB0byBzYXZlIGEgYml0IG9mIHRpbWVcbiAgICAvLyBhcyB0aGUgaG90IHBhdGggZW5kcyB3aXRoIGRvV3JpdGVcbiAgICBzdGF0ZS5wZW5kaW5nY2IrKztcbiAgICBzdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgICBpZiAoaG9sZGVyLm5leHQpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IGhvbGRlci5uZXh0O1xuICAgICAgaG9sZGVyLm5leHQgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUgPSBuZXcgQ29ya2VkUmVxdWVzdChzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIC8vIGlmIHdlIGRpZG4ndCBjYWxsIHRoZSBvbndyaXRlIGltbWVkaWF0ZWx5LCB0aGVuXG4gICAgICAvLyBpdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdCBkb2VzLlxuICAgICAgLy8gYWxzbywgdGhhdCBtZWFucyB0aGF0IHRoZSBjaHVuayBhbmQgY2IgYXJlIGN1cnJlbnRseVxuICAgICAgLy8gYmVpbmcgcHJvY2Vzc2VkLCBzbyBtb3ZlIHRoZSBidWZmZXIgY291bnRlciBwYXN0IHRoZW0uXG4gICAgICBpZiAoc3RhdGUud3JpdGluZykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkgPT09IG51bGwpIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB9XG5cbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBlbnRyeTtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVycm9yKCdfd3JpdGUoKSBpcyBub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRldiA9IG51bGw7XG5cbldyaXRhYmxlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNodW5rO1xuICAgIGNodW5rID0gbnVsbDtcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCkgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIC5lbmQoKSBmdWxseSB1bmNvcmtzXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQgPSAxO1xuICAgIHRoaXMudW5jb3JrKCk7XG4gIH1cblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nICYmICFzdGF0ZS5maW5pc2hlZCkgZW5kV3JpdGFibGUodGhpcywgc3RhdGUsIGNiKTtcbn07XG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLmVuZGluZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID09PSBudWxsICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUud3JpdGluZztcbn1cblxuZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5wcmVmaW5pc2hlZCkge1xuICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgncHJlZmluaXNoJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuICBpZiAobmVlZCkge1xuICAgIGlmIChzdGF0ZS5wZW5kaW5nY2IgPT09IDApIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmVlZDtcbn1cblxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChjYikge1xuICAgIGlmIChzdGF0ZS5maW5pc2hlZCkgcHJvY2Vzc05leHRUaWNrKGNiKTtlbHNlIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICBzdHJlYW0ud3JpdGFibGUgPSBmYWxzZTtcbn1cblxuLy8gSXQgc2VlbXMgYSBsaW5rZWQgbGlzdCBidXQgaXQgaXMgbm90XG4vLyB0aGVyZSB3aWxsIGJlIG9ubHkgMiBvZiB0aGVzZSBmb3IgZWFjaCBzdHJlYW1cbmZ1bmN0aW9uIENvcmtlZFJlcXVlc3Qoc3RhdGUpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB0aGlzLm5leHQgPSBudWxsO1xuICB0aGlzLmVudHJ5ID0gbnVsbDtcbiAgdGhpcy5maW5pc2ggPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgdmFyIGVudHJ5ID0gX3RoaXMuZW50cnk7XG4gICAgX3RoaXMuZW50cnkgPSBudWxsO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgICBzdGF0ZS5wZW5kaW5nY2ItLTtcbiAgICAgIGNiKGVycik7XG4gICAgICBlbnRyeSA9IGVudHJ5Lm5leHQ7XG4gICAgfVxuICAgIGlmIChzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUpIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0ID0gX3RoaXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSA9IF90aGlzO1xuICAgIH1cbiAgfTtcbn0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGJ1ZmZlclNoaW0gPSByZXF1aXJlKCdidWZmZXItc2hpbXMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlckxpc3Q7XG5cbmZ1bmN0aW9uIEJ1ZmZlckxpc3QoKSB7XG4gIHRoaXMuaGVhZCA9IG51bGw7XG4gIHRoaXMudGFpbCA9IG51bGw7XG4gIHRoaXMubGVuZ3RoID0gMDtcbn1cblxuQnVmZmVyTGlzdC5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uICh2KSB7XG4gIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogbnVsbCB9O1xuICBpZiAodGhpcy5sZW5ndGggPiAwKSB0aGlzLnRhaWwubmV4dCA9IGVudHJ5O2Vsc2UgdGhpcy5oZWFkID0gZW50cnk7XG4gIHRoaXMudGFpbCA9IGVudHJ5O1xuICArK3RoaXMubGVuZ3RoO1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uICh2KSB7XG4gIHZhciBlbnRyeSA9IHsgZGF0YTogdiwgbmV4dDogdGhpcy5oZWFkIH07XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgdGhpcy50YWlsID0gZW50cnk7XG4gIHRoaXMuaGVhZCA9IGVudHJ5O1xuICArK3RoaXMubGVuZ3RoO1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuc2hpZnQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICB2YXIgcmV0ID0gdGhpcy5oZWFkLmRhdGE7XG4gIGlmICh0aGlzLmxlbmd0aCA9PT0gMSkgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbnVsbDtlbHNlIHRoaXMuaGVhZCA9IHRoaXMuaGVhZC5uZXh0O1xuICAtLXRoaXMubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTtcblxuQnVmZmVyTGlzdC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gIHRoaXMubGVuZ3RoID0gMDtcbn07XG5cbkJ1ZmZlckxpc3QucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAocykge1xuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgdmFyIHAgPSB0aGlzLmhlYWQ7XG4gIHZhciByZXQgPSAnJyArIHAuZGF0YTtcbiAgd2hpbGUgKHAgPSBwLm5leHQpIHtcbiAgICByZXQgKz0gcyArIHAuZGF0YTtcbiAgfXJldHVybiByZXQ7XG59O1xuXG5CdWZmZXJMaXN0LnByb3RvdHlwZS5jb25jYXQgPSBmdW5jdGlvbiAobikge1xuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiBidWZmZXJTaGltLmFsbG9jKDApO1xuICBpZiAodGhpcy5sZW5ndGggPT09IDEpIHJldHVybiB0aGlzLmhlYWQuZGF0YTtcbiAgdmFyIHJldCA9IGJ1ZmZlclNoaW0uYWxsb2NVbnNhZmUobiA+Pj4gMCk7XG4gIHZhciBwID0gdGhpcy5oZWFkO1xuICB2YXIgaSA9IDA7XG4gIHdoaWxlIChwKSB7XG4gICAgcC5kYXRhLmNvcHkocmV0LCBpKTtcbiAgICBpICs9IHAuZGF0YS5sZW5ndGg7XG4gICAgcCA9IHAubmV4dDtcbiAgfVxuICByZXR1cm4gcmV0O1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9yZWFkYWJsZScpLlBhc3NUaHJvdWdoXG4iLCJleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3JlYWRhYmxlLmpzJyk7XG5leHBvcnRzLlN0cmVhbSA9IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG5leHBvcnRzLkR1cGxleCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fZHVwbGV4LmpzJyk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzJyk7XG5leHBvcnRzLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3JlYWRhYmxlJykuVHJhbnNmb3JtXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fd3JpdGFibGUuanMnKTtcbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2hCYXNlID0gcmVxdWlyZSgnaGFzaC1iYXNlJylcblxuZnVuY3Rpb24gUklQRU1EMTYwICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxufVxuXG5pbmhlcml0cyhSSVBFTUQxNjAsIEhhc2hCYXNlKVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBtID0gbmV3IEFycmF5KDE2KVxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIG1baV0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShpICogNClcblxuICB2YXIgYWwgPSB0aGlzLl9hXG4gIHZhciBibCA9IHRoaXMuX2JcbiAgdmFyIGNsID0gdGhpcy5fY1xuICB2YXIgZGwgPSB0aGlzLl9kXG4gIHZhciBlbCA9IHRoaXMuX2VcblxuICAvLyBNaiA9IDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTVcbiAgLy8gSyA9IDB4MDAwMDAwMDBcbiAgLy8gU2ogPSAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDhcbiAgYWwgPSBmbjEoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzBdLCAweDAwMDAwMDAwLCAxMSk7IGNsID0gcm90bChjbCwgMTApXG4gIGVsID0gZm4xKGVsLCBhbCwgYmwsIGNsLCBkbCwgbVsxXSwgMHgwMDAwMDAwMCwgMTQpOyBibCA9IHJvdGwoYmwsIDEwKVxuICBkbCA9IGZuMShkbCwgZWwsIGFsLCBibCwgY2wsIG1bMl0sIDB4MDAwMDAwMDAsIDE1KTsgYWwgPSByb3RsKGFsLCAxMClcbiAgY2wgPSBmbjEoY2wsIGRsLCBlbCwgYWwsIGJsLCBtWzNdLCAweDAwMDAwMDAwLCAxMik7IGVsID0gcm90bChlbCwgMTApXG4gIGJsID0gZm4xKGJsLCBjbCwgZGwsIGVsLCBhbCwgbVs0XSwgMHgwMDAwMDAwMCwgNSk7IGRsID0gcm90bChkbCwgMTApXG4gIGFsID0gZm4xKGFsLCBibCwgY2wsIGRsLCBlbCwgbVs1XSwgMHgwMDAwMDAwMCwgOCk7IGNsID0gcm90bChjbCwgMTApXG4gIGVsID0gZm4xKGVsLCBhbCwgYmwsIGNsLCBkbCwgbVs2XSwgMHgwMDAwMDAwMCwgNyk7IGJsID0gcm90bChibCwgMTApXG4gIGRsID0gZm4xKGRsLCBlbCwgYWwsIGJsLCBjbCwgbVs3XSwgMHgwMDAwMDAwMCwgOSk7IGFsID0gcm90bChhbCwgMTApXG4gIGNsID0gZm4xKGNsLCBkbCwgZWwsIGFsLCBibCwgbVs4XSwgMHgwMDAwMDAwMCwgMTEpOyBlbCA9IHJvdGwoZWwsIDEwKVxuICBibCA9IGZuMShibCwgY2wsIGRsLCBlbCwgYWwsIG1bOV0sIDB4MDAwMDAwMDAsIDEzKTsgZGwgPSByb3RsKGRsLCAxMClcbiAgYWwgPSBmbjEoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzEwXSwgMHgwMDAwMDAwMCwgMTQpOyBjbCA9IHJvdGwoY2wsIDEwKVxuICBlbCA9IGZuMShlbCwgYWwsIGJsLCBjbCwgZGwsIG1bMTFdLCAweDAwMDAwMDAwLCAxNSk7IGJsID0gcm90bChibCwgMTApXG4gIGRsID0gZm4xKGRsLCBlbCwgYWwsIGJsLCBjbCwgbVsxMl0sIDB4MDAwMDAwMDAsIDYpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuMShjbCwgZGwsIGVsLCBhbCwgYmwsIG1bMTNdLCAweDAwMDAwMDAwLCA3KTsgZWwgPSByb3RsKGVsLCAxMClcbiAgYmwgPSBmbjEoYmwsIGNsLCBkbCwgZWwsIGFsLCBtWzE0XSwgMHgwMDAwMDAwMCwgOSk7IGRsID0gcm90bChkbCwgMTApXG4gIGFsID0gZm4xKGFsLCBibCwgY2wsIGRsLCBlbCwgbVsxNV0sIDB4MDAwMDAwMDAsIDgpOyBjbCA9IHJvdGwoY2wsIDEwKVxuXG4gIC8vIE1qID0gNywgNCwgMTMsIDEsIDEwLCA2LCAxNSwgMywgMTIsIDAsIDksIDUsIDIsIDE0LCAxMSwgOFxuICAvLyBLID0gMHg1YTgyNzk5OVxuICAvLyBTaiA9IDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMlxuICBlbCA9IGZuMihlbCwgYWwsIGJsLCBjbCwgZGwsIG1bN10sIDB4NWE4Mjc5OTksIDcpOyBibCA9IHJvdGwoYmwsIDEwKVxuICBkbCA9IGZuMihkbCwgZWwsIGFsLCBibCwgY2wsIG1bNF0sIDB4NWE4Mjc5OTksIDYpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuMihjbCwgZGwsIGVsLCBhbCwgYmwsIG1bMTNdLCAweDVhODI3OTk5LCA4KTsgZWwgPSByb3RsKGVsLCAxMClcbiAgYmwgPSBmbjIoYmwsIGNsLCBkbCwgZWwsIGFsLCBtWzFdLCAweDVhODI3OTk5LCAxMyk7IGRsID0gcm90bChkbCwgMTApXG4gIGFsID0gZm4yKGFsLCBibCwgY2wsIGRsLCBlbCwgbVsxMF0sIDB4NWE4Mjc5OTksIDExKTsgY2wgPSByb3RsKGNsLCAxMClcbiAgZWwgPSBmbjIoZWwsIGFsLCBibCwgY2wsIGRsLCBtWzZdLCAweDVhODI3OTk5LCA5KTsgYmwgPSByb3RsKGJsLCAxMClcbiAgZGwgPSBmbjIoZGwsIGVsLCBhbCwgYmwsIGNsLCBtWzE1XSwgMHg1YTgyNzk5OSwgNyk7IGFsID0gcm90bChhbCwgMTApXG4gIGNsID0gZm4yKGNsLCBkbCwgZWwsIGFsLCBibCwgbVszXSwgMHg1YTgyNzk5OSwgMTUpOyBlbCA9IHJvdGwoZWwsIDEwKVxuICBibCA9IGZuMihibCwgY2wsIGRsLCBlbCwgYWwsIG1bMTJdLCAweDVhODI3OTk5LCA3KTsgZGwgPSByb3RsKGRsLCAxMClcbiAgYWwgPSBmbjIoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzBdLCAweDVhODI3OTk5LCAxMik7IGNsID0gcm90bChjbCwgMTApXG4gIGVsID0gZm4yKGVsLCBhbCwgYmwsIGNsLCBkbCwgbVs5XSwgMHg1YTgyNzk5OSwgMTUpOyBibCA9IHJvdGwoYmwsIDEwKVxuICBkbCA9IGZuMihkbCwgZWwsIGFsLCBibCwgY2wsIG1bNV0sIDB4NWE4Mjc5OTksIDkpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuMihjbCwgZGwsIGVsLCBhbCwgYmwsIG1bMl0sIDB4NWE4Mjc5OTksIDExKTsgZWwgPSByb3RsKGVsLCAxMClcbiAgYmwgPSBmbjIoYmwsIGNsLCBkbCwgZWwsIGFsLCBtWzE0XSwgMHg1YTgyNzk5OSwgNyk7IGRsID0gcm90bChkbCwgMTApXG4gIGFsID0gZm4yKGFsLCBibCwgY2wsIGRsLCBlbCwgbVsxMV0sIDB4NWE4Mjc5OTksIDEzKTsgY2wgPSByb3RsKGNsLCAxMClcbiAgZWwgPSBmbjIoZWwsIGFsLCBibCwgY2wsIGRsLCBtWzhdLCAweDVhODI3OTk5LCAxMik7IGJsID0gcm90bChibCwgMTApXG5cbiAgLy8gTWogPSAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyXG4gIC8vIEsgPSAweDZlZDllYmExXG4gIC8vIFNqID0gMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1XG4gIGRsID0gZm4zKGRsLCBlbCwgYWwsIGJsLCBjbCwgbVszXSwgMHg2ZWQ5ZWJhMSwgMTEpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuMyhjbCwgZGwsIGVsLCBhbCwgYmwsIG1bMTBdLCAweDZlZDllYmExLCAxMyk7IGVsID0gcm90bChlbCwgMTApXG4gIGJsID0gZm4zKGJsLCBjbCwgZGwsIGVsLCBhbCwgbVsxNF0sIDB4NmVkOWViYTEsIDYpOyBkbCA9IHJvdGwoZGwsIDEwKVxuICBhbCA9IGZuMyhhbCwgYmwsIGNsLCBkbCwgZWwsIG1bNF0sIDB4NmVkOWViYTEsIDcpOyBjbCA9IHJvdGwoY2wsIDEwKVxuICBlbCA9IGZuMyhlbCwgYWwsIGJsLCBjbCwgZGwsIG1bOV0sIDB4NmVkOWViYTEsIDE0KTsgYmwgPSByb3RsKGJsLCAxMClcbiAgZGwgPSBmbjMoZGwsIGVsLCBhbCwgYmwsIGNsLCBtWzE1XSwgMHg2ZWQ5ZWJhMSwgOSk7IGFsID0gcm90bChhbCwgMTApXG4gIGNsID0gZm4zKGNsLCBkbCwgZWwsIGFsLCBibCwgbVs4XSwgMHg2ZWQ5ZWJhMSwgMTMpOyBlbCA9IHJvdGwoZWwsIDEwKVxuICBibCA9IGZuMyhibCwgY2wsIGRsLCBlbCwgYWwsIG1bMV0sIDB4NmVkOWViYTEsIDE1KTsgZGwgPSByb3RsKGRsLCAxMClcbiAgYWwgPSBmbjMoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzJdLCAweDZlZDllYmExLCAxNCk7IGNsID0gcm90bChjbCwgMTApXG4gIGVsID0gZm4zKGVsLCBhbCwgYmwsIGNsLCBkbCwgbVs3XSwgMHg2ZWQ5ZWJhMSwgOCk7IGJsID0gcm90bChibCwgMTApXG4gIGRsID0gZm4zKGRsLCBlbCwgYWwsIGJsLCBjbCwgbVswXSwgMHg2ZWQ5ZWJhMSwgMTMpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuMyhjbCwgZGwsIGVsLCBhbCwgYmwsIG1bNl0sIDB4NmVkOWViYTEsIDYpOyBlbCA9IHJvdGwoZWwsIDEwKVxuICBibCA9IGZuMyhibCwgY2wsIGRsLCBlbCwgYWwsIG1bMTNdLCAweDZlZDllYmExLCA1KTsgZGwgPSByb3RsKGRsLCAxMClcbiAgYWwgPSBmbjMoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzExXSwgMHg2ZWQ5ZWJhMSwgMTIpOyBjbCA9IHJvdGwoY2wsIDEwKVxuICBlbCA9IGZuMyhlbCwgYWwsIGJsLCBjbCwgZGwsIG1bNV0sIDB4NmVkOWViYTEsIDcpOyBibCA9IHJvdGwoYmwsIDEwKVxuICBkbCA9IGZuMyhkbCwgZWwsIGFsLCBibCwgY2wsIG1bMTJdLCAweDZlZDllYmExLCA1KTsgYWwgPSByb3RsKGFsLCAxMClcblxuICAvLyBNaiA9IDEsIDksIDExLCAxMCwgMCwgOCwgMTIsIDQsIDEzLCAzLCA3LCAxNSwgMTQsIDUsIDYsIDJcbiAgLy8gSyA9IDB4OGYxYmJjZGNcbiAgLy8gU2ogPSAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTJcbiAgY2wgPSBmbjQoY2wsIGRsLCBlbCwgYWwsIGJsLCBtWzFdLCAweDhmMWJiY2RjLCAxMSk7IGVsID0gcm90bChlbCwgMTApXG4gIGJsID0gZm40KGJsLCBjbCwgZGwsIGVsLCBhbCwgbVs5XSwgMHg4ZjFiYmNkYywgMTIpOyBkbCA9IHJvdGwoZGwsIDEwKVxuICBhbCA9IGZuNChhbCwgYmwsIGNsLCBkbCwgZWwsIG1bMTFdLCAweDhmMWJiY2RjLCAxNCk7IGNsID0gcm90bChjbCwgMTApXG4gIGVsID0gZm40KGVsLCBhbCwgYmwsIGNsLCBkbCwgbVsxMF0sIDB4OGYxYmJjZGMsIDE1KTsgYmwgPSByb3RsKGJsLCAxMClcbiAgZGwgPSBmbjQoZGwsIGVsLCBhbCwgYmwsIGNsLCBtWzBdLCAweDhmMWJiY2RjLCAxNCk7IGFsID0gcm90bChhbCwgMTApXG4gIGNsID0gZm40KGNsLCBkbCwgZWwsIGFsLCBibCwgbVs4XSwgMHg4ZjFiYmNkYywgMTUpOyBlbCA9IHJvdGwoZWwsIDEwKVxuICBibCA9IGZuNChibCwgY2wsIGRsLCBlbCwgYWwsIG1bMTJdLCAweDhmMWJiY2RjLCA5KTsgZGwgPSByb3RsKGRsLCAxMClcbiAgYWwgPSBmbjQoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzRdLCAweDhmMWJiY2RjLCA4KTsgY2wgPSByb3RsKGNsLCAxMClcbiAgZWwgPSBmbjQoZWwsIGFsLCBibCwgY2wsIGRsLCBtWzEzXSwgMHg4ZjFiYmNkYywgOSk7IGJsID0gcm90bChibCwgMTApXG4gIGRsID0gZm40KGRsLCBlbCwgYWwsIGJsLCBjbCwgbVszXSwgMHg4ZjFiYmNkYywgMTQpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuNChjbCwgZGwsIGVsLCBhbCwgYmwsIG1bN10sIDB4OGYxYmJjZGMsIDUpOyBlbCA9IHJvdGwoZWwsIDEwKVxuICBibCA9IGZuNChibCwgY2wsIGRsLCBlbCwgYWwsIG1bMTVdLCAweDhmMWJiY2RjLCA2KTsgZGwgPSByb3RsKGRsLCAxMClcbiAgYWwgPSBmbjQoYWwsIGJsLCBjbCwgZGwsIGVsLCBtWzE0XSwgMHg4ZjFiYmNkYywgOCk7IGNsID0gcm90bChjbCwgMTApXG4gIGVsID0gZm40KGVsLCBhbCwgYmwsIGNsLCBkbCwgbVs1XSwgMHg4ZjFiYmNkYywgNik7IGJsID0gcm90bChibCwgMTApXG4gIGRsID0gZm40KGRsLCBlbCwgYWwsIGJsLCBjbCwgbVs2XSwgMHg4ZjFiYmNkYywgNSk7IGFsID0gcm90bChhbCwgMTApXG4gIGNsID0gZm40KGNsLCBkbCwgZWwsIGFsLCBibCwgbVsyXSwgMHg4ZjFiYmNkYywgMTIpOyBlbCA9IHJvdGwoZWwsIDEwKVxuXG4gIC8vIE1qID0gNCwgMCwgNSwgOSwgNywgMTIsIDIsIDEwLCAxNCwgMSwgMywgOCwgMTEsIDYsIDE1LCAxM1xuICAvLyBLID0gMHhhOTUzZmQ0ZVxuICAvLyBTaiA9IDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuICBibCA9IGZuNShibCwgY2wsIGRsLCBlbCwgYWwsIG1bNF0sIDB4YTk1M2ZkNGUsIDkpOyBkbCA9IHJvdGwoZGwsIDEwKVxuICBhbCA9IGZuNShhbCwgYmwsIGNsLCBkbCwgZWwsIG1bMF0sIDB4YTk1M2ZkNGUsIDE1KTsgY2wgPSByb3RsKGNsLCAxMClcbiAgZWwgPSBmbjUoZWwsIGFsLCBibCwgY2wsIGRsLCBtWzVdLCAweGE5NTNmZDRlLCA1KTsgYmwgPSByb3RsKGJsLCAxMClcbiAgZGwgPSBmbjUoZGwsIGVsLCBhbCwgYmwsIGNsLCBtWzldLCAweGE5NTNmZDRlLCAxMSk7IGFsID0gcm90bChhbCwgMTApXG4gIGNsID0gZm41KGNsLCBkbCwgZWwsIGFsLCBibCwgbVs3XSwgMHhhOTUzZmQ0ZSwgNik7IGVsID0gcm90bChlbCwgMTApXG4gIGJsID0gZm41KGJsLCBjbCwgZGwsIGVsLCBhbCwgbVsxMl0sIDB4YTk1M2ZkNGUsIDgpOyBkbCA9IHJvdGwoZGwsIDEwKVxuICBhbCA9IGZuNShhbCwgYmwsIGNsLCBkbCwgZWwsIG1bMl0sIDB4YTk1M2ZkNGUsIDEzKTsgY2wgPSByb3RsKGNsLCAxMClcbiAgZWwgPSBmbjUoZWwsIGFsLCBibCwgY2wsIGRsLCBtWzEwXSwgMHhhOTUzZmQ0ZSwgMTIpOyBibCA9IHJvdGwoYmwsIDEwKVxuICBkbCA9IGZuNShkbCwgZWwsIGFsLCBibCwgY2wsIG1bMTRdLCAweGE5NTNmZDRlLCA1KTsgYWwgPSByb3RsKGFsLCAxMClcbiAgY2wgPSBmbjUoY2wsIGRsLCBlbCwgYWwsIGJsLCBtWzFdLCAweGE5NTNmZDRlLCAxMik7IGVsID0gcm90bChlbCwgMTApXG4gIGJsID0gZm41KGJsLCBjbCwgZGwsIGVsLCBhbCwgbVszXSwgMHhhOTUzZmQ0ZSwgMTMpOyBkbCA9IHJvdGwoZGwsIDEwKVxuICBhbCA9IGZuNShhbCwgYmwsIGNsLCBkbCwgZWwsIG1bOF0sIDB4YTk1M2ZkNGUsIDE0KTsgY2wgPSByb3RsKGNsLCAxMClcbiAgZWwgPSBmbjUoZWwsIGFsLCBibCwgY2wsIGRsLCBtWzExXSwgMHhhOTUzZmQ0ZSwgMTEpOyBibCA9IHJvdGwoYmwsIDEwKVxuICBkbCA9IGZuNShkbCwgZWwsIGFsLCBibCwgY2wsIG1bNl0sIDB4YTk1M2ZkNGUsIDgpOyBhbCA9IHJvdGwoYWwsIDEwKVxuICBjbCA9IGZuNShjbCwgZGwsIGVsLCBhbCwgYmwsIG1bMTVdLCAweGE5NTNmZDRlLCA1KTsgZWwgPSByb3RsKGVsLCAxMClcbiAgYmwgPSBmbjUoYmwsIGNsLCBkbCwgZWwsIGFsLCBtWzEzXSwgMHhhOTUzZmQ0ZSwgNik7IGRsID0gcm90bChkbCwgMTApXG5cbiAgdmFyIGFyID0gdGhpcy5fYVxuICB2YXIgYnIgPSB0aGlzLl9iXG4gIHZhciBjciA9IHRoaXMuX2NcbiAgdmFyIGRyID0gdGhpcy5fZFxuICB2YXIgZXIgPSB0aGlzLl9lXG5cbiAgLy8gTSdqID0gNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMlxuICAvLyBLJyA9IDB4NTBhMjhiZTZcbiAgLy8gUydqID0gOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2XG4gIGFyID0gZm41KGFyLCBiciwgY3IsIGRyLCBlciwgbVs1XSwgMHg1MGEyOGJlNiwgOCk7IGNyID0gcm90bChjciwgMTApXG4gIGVyID0gZm41KGVyLCBhciwgYnIsIGNyLCBkciwgbVsxNF0sIDB4NTBhMjhiZTYsIDkpOyBiciA9IHJvdGwoYnIsIDEwKVxuICBkciA9IGZuNShkciwgZXIsIGFyLCBiciwgY3IsIG1bN10sIDB4NTBhMjhiZTYsIDkpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuNShjciwgZHIsIGVyLCBhciwgYnIsIG1bMF0sIDB4NTBhMjhiZTYsIDExKTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjUoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzldLCAweDUwYTI4YmU2LCAxMyk7IGRyID0gcm90bChkciwgMTApXG4gIGFyID0gZm41KGFyLCBiciwgY3IsIGRyLCBlciwgbVsyXSwgMHg1MGEyOGJlNiwgMTUpOyBjciA9IHJvdGwoY3IsIDEwKVxuICBlciA9IGZuNShlciwgYXIsIGJyLCBjciwgZHIsIG1bMTFdLCAweDUwYTI4YmU2LCAxNSk7IGJyID0gcm90bChiciwgMTApXG4gIGRyID0gZm41KGRyLCBlciwgYXIsIGJyLCBjciwgbVs0XSwgMHg1MGEyOGJlNiwgNSk7IGFyID0gcm90bChhciwgMTApXG4gIGNyID0gZm41KGNyLCBkciwgZXIsIGFyLCBiciwgbVsxM10sIDB4NTBhMjhiZTYsIDcpOyBlciA9IHJvdGwoZXIsIDEwKVxuICBiciA9IGZuNShiciwgY3IsIGRyLCBlciwgYXIsIG1bNl0sIDB4NTBhMjhiZTYsIDcpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuNShhciwgYnIsIGNyLCBkciwgZXIsIG1bMTVdLCAweDUwYTI4YmU2LCA4KTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjUoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzhdLCAweDUwYTI4YmU2LCAxMSk7IGJyID0gcm90bChiciwgMTApXG4gIGRyID0gZm41KGRyLCBlciwgYXIsIGJyLCBjciwgbVsxXSwgMHg1MGEyOGJlNiwgMTQpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuNShjciwgZHIsIGVyLCBhciwgYnIsIG1bMTBdLCAweDUwYTI4YmU2LCAxNCk7IGVyID0gcm90bChlciwgMTApXG4gIGJyID0gZm41KGJyLCBjciwgZHIsIGVyLCBhciwgbVszXSwgMHg1MGEyOGJlNiwgMTIpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuNShhciwgYnIsIGNyLCBkciwgZXIsIG1bMTJdLCAweDUwYTI4YmU2LCA2KTsgY3IgPSByb3RsKGNyLCAxMClcblxuICAvLyBNJ2ogPSA2LCAxMSwgMywgNywgMCwgMTMsIDUsIDEwLCAxNCwgMTUsIDgsIDEyLCA0LCA5LCAxLCAyXG4gIC8vIEsnID0gMHg1YzRkZDEyNFxuICAvLyBTJ2ogPSA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTFcbiAgZXIgPSBmbjQoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzZdLCAweDVjNGRkMTI0LCA5KTsgYnIgPSByb3RsKGJyLCAxMClcbiAgZHIgPSBmbjQoZHIsIGVyLCBhciwgYnIsIGNyLCBtWzExXSwgMHg1YzRkZDEyNCwgMTMpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuNChjciwgZHIsIGVyLCBhciwgYnIsIG1bM10sIDB4NWM0ZGQxMjQsIDE1KTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjQoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzddLCAweDVjNGRkMTI0LCA3KTsgZHIgPSByb3RsKGRyLCAxMClcbiAgYXIgPSBmbjQoYXIsIGJyLCBjciwgZHIsIGVyLCBtWzBdLCAweDVjNGRkMTI0LCAxMik7IGNyID0gcm90bChjciwgMTApXG4gIGVyID0gZm40KGVyLCBhciwgYnIsIGNyLCBkciwgbVsxM10sIDB4NWM0ZGQxMjQsIDgpOyBiciA9IHJvdGwoYnIsIDEwKVxuICBkciA9IGZuNChkciwgZXIsIGFyLCBiciwgY3IsIG1bNV0sIDB4NWM0ZGQxMjQsIDkpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuNChjciwgZHIsIGVyLCBhciwgYnIsIG1bMTBdLCAweDVjNGRkMTI0LCAxMSk7IGVyID0gcm90bChlciwgMTApXG4gIGJyID0gZm40KGJyLCBjciwgZHIsIGVyLCBhciwgbVsxNF0sIDB4NWM0ZGQxMjQsIDcpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuNChhciwgYnIsIGNyLCBkciwgZXIsIG1bMTVdLCAweDVjNGRkMTI0LCA3KTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjQoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzhdLCAweDVjNGRkMTI0LCAxMik7IGJyID0gcm90bChiciwgMTApXG4gIGRyID0gZm40KGRyLCBlciwgYXIsIGJyLCBjciwgbVsxMl0sIDB4NWM0ZGQxMjQsIDcpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuNChjciwgZHIsIGVyLCBhciwgYnIsIG1bNF0sIDB4NWM0ZGQxMjQsIDYpOyBlciA9IHJvdGwoZXIsIDEwKVxuICBiciA9IGZuNChiciwgY3IsIGRyLCBlciwgYXIsIG1bOV0sIDB4NWM0ZGQxMjQsIDE1KTsgZHIgPSByb3RsKGRyLCAxMClcbiAgYXIgPSBmbjQoYXIsIGJyLCBjciwgZHIsIGVyLCBtWzFdLCAweDVjNGRkMTI0LCAxMyk7IGNyID0gcm90bChjciwgMTApXG4gIGVyID0gZm40KGVyLCBhciwgYnIsIGNyLCBkciwgbVsyXSwgMHg1YzRkZDEyNCwgMTEpOyBiciA9IHJvdGwoYnIsIDEwKVxuXG4gIC8vIE0naiA9IDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTNcbiAgLy8gSycgPSAweDZkNzAzZWYzXG4gIC8vIFMnaiA9IDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNVxuICBkciA9IGZuMyhkciwgZXIsIGFyLCBiciwgY3IsIG1bMTVdLCAweDZkNzAzZWYzLCA5KTsgYXIgPSByb3RsKGFyLCAxMClcbiAgY3IgPSBmbjMoY3IsIGRyLCBlciwgYXIsIGJyLCBtWzVdLCAweDZkNzAzZWYzLCA3KTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjMoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzFdLCAweDZkNzAzZWYzLCAxNSk7IGRyID0gcm90bChkciwgMTApXG4gIGFyID0gZm4zKGFyLCBiciwgY3IsIGRyLCBlciwgbVszXSwgMHg2ZDcwM2VmMywgMTEpOyBjciA9IHJvdGwoY3IsIDEwKVxuICBlciA9IGZuMyhlciwgYXIsIGJyLCBjciwgZHIsIG1bN10sIDB4NmQ3MDNlZjMsIDgpOyBiciA9IHJvdGwoYnIsIDEwKVxuICBkciA9IGZuMyhkciwgZXIsIGFyLCBiciwgY3IsIG1bMTRdLCAweDZkNzAzZWYzLCA2KTsgYXIgPSByb3RsKGFyLCAxMClcbiAgY3IgPSBmbjMoY3IsIGRyLCBlciwgYXIsIGJyLCBtWzZdLCAweDZkNzAzZWYzLCA2KTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjMoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzldLCAweDZkNzAzZWYzLCAxNCk7IGRyID0gcm90bChkciwgMTApXG4gIGFyID0gZm4zKGFyLCBiciwgY3IsIGRyLCBlciwgbVsxMV0sIDB4NmQ3MDNlZjMsIDEyKTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjMoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzhdLCAweDZkNzAzZWYzLCAxMyk7IGJyID0gcm90bChiciwgMTApXG4gIGRyID0gZm4zKGRyLCBlciwgYXIsIGJyLCBjciwgbVsxMl0sIDB4NmQ3MDNlZjMsIDUpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuMyhjciwgZHIsIGVyLCBhciwgYnIsIG1bMl0sIDB4NmQ3MDNlZjMsIDE0KTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjMoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzEwXSwgMHg2ZDcwM2VmMywgMTMpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuMyhhciwgYnIsIGNyLCBkciwgZXIsIG1bMF0sIDB4NmQ3MDNlZjMsIDEzKTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjMoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzRdLCAweDZkNzAzZWYzLCA3KTsgYnIgPSByb3RsKGJyLCAxMClcbiAgZHIgPSBmbjMoZHIsIGVyLCBhciwgYnIsIGNyLCBtWzEzXSwgMHg2ZDcwM2VmMywgNSk7IGFyID0gcm90bChhciwgMTApXG5cbiAgLy8gTSdqID0gOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNFxuICAvLyBLJyA9IDB4N2E2ZDc2ZTlcbiAgLy8gUydqID0gMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4XG4gIGNyID0gZm4yKGNyLCBkciwgZXIsIGFyLCBiciwgbVs4XSwgMHg3YTZkNzZlOSwgMTUpOyBlciA9IHJvdGwoZXIsIDEwKVxuICBiciA9IGZuMihiciwgY3IsIGRyLCBlciwgYXIsIG1bNl0sIDB4N2E2ZDc2ZTksIDUpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuMihhciwgYnIsIGNyLCBkciwgZXIsIG1bNF0sIDB4N2E2ZDc2ZTksIDgpOyBjciA9IHJvdGwoY3IsIDEwKVxuICBlciA9IGZuMihlciwgYXIsIGJyLCBjciwgZHIsIG1bMV0sIDB4N2E2ZDc2ZTksIDExKTsgYnIgPSByb3RsKGJyLCAxMClcbiAgZHIgPSBmbjIoZHIsIGVyLCBhciwgYnIsIGNyLCBtWzNdLCAweDdhNmQ3NmU5LCAxNCk7IGFyID0gcm90bChhciwgMTApXG4gIGNyID0gZm4yKGNyLCBkciwgZXIsIGFyLCBiciwgbVsxMV0sIDB4N2E2ZDc2ZTksIDE0KTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjIoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzE1XSwgMHg3YTZkNzZlOSwgNik7IGRyID0gcm90bChkciwgMTApXG4gIGFyID0gZm4yKGFyLCBiciwgY3IsIGRyLCBlciwgbVswXSwgMHg3YTZkNzZlOSwgMTQpOyBjciA9IHJvdGwoY3IsIDEwKVxuICBlciA9IGZuMihlciwgYXIsIGJyLCBjciwgZHIsIG1bNV0sIDB4N2E2ZDc2ZTksIDYpOyBiciA9IHJvdGwoYnIsIDEwKVxuICBkciA9IGZuMihkciwgZXIsIGFyLCBiciwgY3IsIG1bMTJdLCAweDdhNmQ3NmU5LCA5KTsgYXIgPSByb3RsKGFyLCAxMClcbiAgY3IgPSBmbjIoY3IsIGRyLCBlciwgYXIsIGJyLCBtWzJdLCAweDdhNmQ3NmU5LCAxMik7IGVyID0gcm90bChlciwgMTApXG4gIGJyID0gZm4yKGJyLCBjciwgZHIsIGVyLCBhciwgbVsxM10sIDB4N2E2ZDc2ZTksIDkpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuMihhciwgYnIsIGNyLCBkciwgZXIsIG1bOV0sIDB4N2E2ZDc2ZTksIDEyKTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjIoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzddLCAweDdhNmQ3NmU5LCA1KTsgYnIgPSByb3RsKGJyLCAxMClcbiAgZHIgPSBmbjIoZHIsIGVyLCBhciwgYnIsIGNyLCBtWzEwXSwgMHg3YTZkNzZlOSwgMTUpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuMihjciwgZHIsIGVyLCBhciwgYnIsIG1bMTRdLCAweDdhNmQ3NmU5LCA4KTsgZXIgPSByb3RsKGVyLCAxMClcblxuICAvLyBNJ2ogPSAxMiwgMTUsIDEwLCA0LCAxLCA1LCA4LCA3LCA2LCAyLCAxMywgMTQsIDAsIDMsIDksIDExXG4gIC8vIEsnID0gMHgwMDAwMDAwMFxuICAvLyBTJ2ogPSA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbiAgYnIgPSBmbjEoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzEyXSwgMHgwMDAwMDAwMCwgOCk7IGRyID0gcm90bChkciwgMTApXG4gIGFyID0gZm4xKGFyLCBiciwgY3IsIGRyLCBlciwgbVsxNV0sIDB4MDAwMDAwMDAsIDUpOyBjciA9IHJvdGwoY3IsIDEwKVxuICBlciA9IGZuMShlciwgYXIsIGJyLCBjciwgZHIsIG1bMTBdLCAweDAwMDAwMDAwLCAxMik7IGJyID0gcm90bChiciwgMTApXG4gIGRyID0gZm4xKGRyLCBlciwgYXIsIGJyLCBjciwgbVs0XSwgMHgwMDAwMDAwMCwgOSk7IGFyID0gcm90bChhciwgMTApXG4gIGNyID0gZm4xKGNyLCBkciwgZXIsIGFyLCBiciwgbVsxXSwgMHgwMDAwMDAwMCwgMTIpOyBlciA9IHJvdGwoZXIsIDEwKVxuICBiciA9IGZuMShiciwgY3IsIGRyLCBlciwgYXIsIG1bNV0sIDB4MDAwMDAwMDAsIDUpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuMShhciwgYnIsIGNyLCBkciwgZXIsIG1bOF0sIDB4MDAwMDAwMDAsIDE0KTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjEoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzddLCAweDAwMDAwMDAwLCA2KTsgYnIgPSByb3RsKGJyLCAxMClcbiAgZHIgPSBmbjEoZHIsIGVyLCBhciwgYnIsIGNyLCBtWzZdLCAweDAwMDAwMDAwLCA4KTsgYXIgPSByb3RsKGFyLCAxMClcbiAgY3IgPSBmbjEoY3IsIGRyLCBlciwgYXIsIGJyLCBtWzJdLCAweDAwMDAwMDAwLCAxMyk7IGVyID0gcm90bChlciwgMTApXG4gIGJyID0gZm4xKGJyLCBjciwgZHIsIGVyLCBhciwgbVsxM10sIDB4MDAwMDAwMDAsIDYpOyBkciA9IHJvdGwoZHIsIDEwKVxuICBhciA9IGZuMShhciwgYnIsIGNyLCBkciwgZXIsIG1bMTRdLCAweDAwMDAwMDAwLCA1KTsgY3IgPSByb3RsKGNyLCAxMClcbiAgZXIgPSBmbjEoZXIsIGFyLCBiciwgY3IsIGRyLCBtWzBdLCAweDAwMDAwMDAwLCAxNSk7IGJyID0gcm90bChiciwgMTApXG4gIGRyID0gZm4xKGRyLCBlciwgYXIsIGJyLCBjciwgbVszXSwgMHgwMDAwMDAwMCwgMTMpOyBhciA9IHJvdGwoYXIsIDEwKVxuICBjciA9IGZuMShjciwgZHIsIGVyLCBhciwgYnIsIG1bOV0sIDB4MDAwMDAwMDAsIDExKTsgZXIgPSByb3RsKGVyLCAxMClcbiAgYnIgPSBmbjEoYnIsIGNyLCBkciwgZXIsIGFyLCBtWzExXSwgMHgwMDAwMDAwMCwgMTEpOyBkciA9IHJvdGwoZHIsIDEwKVxuXG4gIC8vIGNoYW5nZSBzdGF0ZVxuICB2YXIgdCA9ICh0aGlzLl9iICsgY2wgKyBkcikgfCAwXG4gIHRoaXMuX2IgPSAodGhpcy5fYyArIGRsICsgZXIpIHwgMFxuICB0aGlzLl9jID0gKHRoaXMuX2QgKyBlbCArIGFyKSB8IDBcbiAgdGhpcy5fZCA9ICh0aGlzLl9lICsgYWwgKyBicikgfCAwXG4gIHRoaXMuX2UgPSAodGhpcy5fYSArIGJsICsgY3IpIHwgMFxuICB0aGlzLl9hID0gdFxufVxuXG5SSVBFTUQxNjAucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGNyZWF0ZSBwYWRkaW5nIGFuZCBoYW5kbGUgYmxvY2tzXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2Jsb2NrT2Zmc2V0KytdID0gMHg4MFxuICBpZiAodGhpcy5fYmxvY2tPZmZzZXQgPiA1Nikge1xuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fYmxvY2tPZmZzZXQsIDY0KVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cblxuICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMF0sIDU2KVxuICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkxFKHRoaXMuX2xlbmd0aFsxXSwgNjApXG4gIHRoaXMuX3VwZGF0ZSgpXG5cbiAgLy8gcHJvZHVjZSByZXN1bHRcbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIoMjApXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYSwgMClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9iLCA0KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2MsIDgpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fZCwgMTIpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fZSwgMTYpXG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gcm90bCAoeCwgbikge1xuICByZXR1cm4gKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpXG59XG5cbmZ1bmN0aW9uIGZuMSAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoYiBeIGMgXiBkKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuMiAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBjKSB8ICgofmIpICYgZCkpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm4zIChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiB8ICh+YykpIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjQgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiICYgZCkgfCAoYyAmICh+ZCkpKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuNSAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoYiBeIChjIHwgKH5kKSkpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSSVBFTUQxNjBcbiIsIiFmdW5jdGlvbihnbG9iYWxzKXtcbid1c2Ugc3RyaWN0J1xuXG4vLyoqKiBVTUQgQkVHSU5cbmlmICh0eXBlb2YgZGVmaW5lICE9PSAndW5kZWZpbmVkJyAmJiBkZWZpbmUuYW1kKSB7IC8vcmVxdWlyZS5qcyAvIEFNRFxuICBkZWZpbmUoW10sIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzZWN1cmVSYW5kb21cbiAgfSlcbn0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsgLy9Db21tb25KU1xuICBtb2R1bGUuZXhwb3J0cyA9IHNlY3VyZVJhbmRvbVxufSBlbHNlIHsgLy9zY3JpcHQgLyBicm93c2VyXG4gIGdsb2JhbHMuc2VjdXJlUmFuZG9tID0gc2VjdXJlUmFuZG9tXG59XG4vLyoqKiBVTUQgRU5EXG5cbi8vb3B0aW9ucy50eXBlIGlzIHRoZSBvbmx5IHZhbGlkIG9wdGlvblxuZnVuY3Rpb24gc2VjdXJlUmFuZG9tKGNvdW50LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt0eXBlOiAnQXJyYXknfVxuICAvL3dlIGNoZWNrIGZvciBwcm9jZXNzLnBpZCB0byBwcmV2ZW50IGJyb3dzZXJpZnkgZnJvbSB0cmlja2luZyB1c1xuICBpZiAodHlwZW9mIHByb2Nlc3MgIT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHByb2Nlc3MucGlkID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIG5vZGVSYW5kb20oY291bnQsIG9wdGlvbnMpXG4gIH0gZWxzZSB7XG4gICAgdmFyIGNyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvXG4gICAgaWYgKCFjcnlwdG8pIHRocm93IG5ldyBFcnJvcihcIllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHdpbmRvdy5jcnlwdG8uXCIpXG4gICAgcmV0dXJuIGJyb3dzZXJSYW5kb20oY291bnQsIG9wdGlvbnMpXG4gIH1cbn1cblxuZnVuY3Rpb24gbm9kZVJhbmRvbShjb3VudCwgb3B0aW9ucykge1xuICB2YXIgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJylcbiAgdmFyIGJ1ZiA9IGNyeXB0by5yYW5kb21CeXRlcyhjb3VudClcblxuICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkge1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiBbXS5zbGljZS5jYWxsKGJ1ZilcbiAgICBjYXNlICdCdWZmZXInOlxuICAgICAgcmV0dXJuIGJ1ZlxuICAgIGNhc2UgJ1VpbnQ4QXJyYXknOlxuICAgICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGNvdW50KVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7IGFycltpXSA9IGJ1Zi5yZWFkVUludDgoaSkgfVxuICAgICAgcmV0dXJuIGFyclxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3Iob3B0aW9ucy50eXBlICsgXCIgaXMgdW5zdXBwb3J0ZWQuXCIpXG4gIH1cbn1cblxuZnVuY3Rpb24gYnJvd3NlclJhbmRvbShjb3VudCwgb3B0aW9ucykge1xuICB2YXIgbmF0aXZlQXJyID0gbmV3IFVpbnQ4QXJyYXkoY291bnQpXG4gIHZhciBjcnlwdG8gPSB3aW5kb3cuY3J5cHRvIHx8IHdpbmRvdy5tc0NyeXB0b1xuICBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKG5hdGl2ZUFycilcblxuICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkge1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiBbXS5zbGljZS5jYWxsKG5hdGl2ZUFycilcbiAgICBjYXNlICdCdWZmZXInOlxuICAgICAgdHJ5IHsgdmFyIGIgPSBuZXcgQnVmZmVyKDEpIH0gY2F0Y2goZSkgeyB0aHJvdyBuZXcgRXJyb3IoJ0J1ZmZlciBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQuIFVzZSBOb2RlLmpzIG9yIEJyb3dzZXJpZnkgZm9yIGJyb3dzZXIgc3VwcG9ydC4nKX1cbiAgICAgIHJldHVybiBuZXcgQnVmZmVyKG5hdGl2ZUFycilcbiAgICBjYXNlICdVaW50OEFycmF5JzpcbiAgICAgIHJldHVybiBuYXRpdmVBcnJcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKG9wdGlvbnMudHlwZSArIFwiIGlzIHVuc3VwcG9ydGVkLlwiKVxuICB9XG59XG5cbnNlY3VyZVJhbmRvbS5yYW5kb21BcnJheSA9IGZ1bmN0aW9uKGJ5dGVDb3VudCkge1xuICByZXR1cm4gc2VjdXJlUmFuZG9tKGJ5dGVDb3VudCwge3R5cGU6ICdBcnJheSd9KVxufVxuXG5zZWN1cmVSYW5kb20ucmFuZG9tVWludDhBcnJheSA9IGZ1bmN0aW9uKGJ5dGVDb3VudCkge1xuICByZXR1cm4gc2VjdXJlUmFuZG9tKGJ5dGVDb3VudCwge3R5cGU6ICdVaW50OEFycmF5J30pXG59XG5cbnNlY3VyZVJhbmRvbS5yYW5kb21CdWZmZXIgPSBmdW5jdGlvbihieXRlQ291bnQpIHtcbiAgcmV0dXJuIHNlY3VyZVJhbmRvbShieXRlQ291bnQsIHt0eXBlOiAnQnVmZmVyJ30pXG59XG5cblxufSh0aGlzKTtcbiIsIi8vIHByb3RvdHlwZSBjbGFzcyBmb3IgaGFzaCBmdW5jdGlvbnNcbmZ1bmN0aW9uIEhhc2ggKGJsb2NrU2l6ZSwgZmluYWxTaXplKSB7XG4gIHRoaXMuX2Jsb2NrID0gbmV3IEJ1ZmZlcihibG9ja1NpemUpXG4gIHRoaXMuX2ZpbmFsU2l6ZSA9IGZpbmFsU2l6ZVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fbGVuID0gMFxuICB0aGlzLl9zID0gMFxufVxuXG5IYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBlbmMgfHwgJ3V0ZjgnXG4gICAgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSwgZW5jKVxuICB9XG5cbiAgdmFyIGwgPSB0aGlzLl9sZW4gKz0gZGF0YS5sZW5ndGhcbiAgdmFyIHMgPSB0aGlzLl9zIHx8IDBcbiAgdmFyIGYgPSAwXG4gIHZhciBidWZmZXIgPSB0aGlzLl9ibG9ja1xuXG4gIHdoaWxlIChzIDwgbCkge1xuICAgIHZhciB0ID0gTWF0aC5taW4oZGF0YS5sZW5ndGgsIGYgKyB0aGlzLl9ibG9ja1NpemUgLSAocyAlIHRoaXMuX2Jsb2NrU2l6ZSkpXG4gICAgdmFyIGNoID0gKHQgLSBmKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaDsgaSsrKSB7XG4gICAgICBidWZmZXJbKHMgJSB0aGlzLl9ibG9ja1NpemUpICsgaV0gPSBkYXRhW2kgKyBmXVxuICAgIH1cblxuICAgIHMgKz0gY2hcbiAgICBmICs9IGNoXG5cbiAgICBpZiAoKHMgJSB0aGlzLl9ibG9ja1NpemUpID09PSAwKSB7XG4gICAgICB0aGlzLl91cGRhdGUoYnVmZmVyKVxuICAgIH1cbiAgfVxuICB0aGlzLl9zID0gc1xuXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2gucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgLy8gU3VwcG9zZSB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIE0sIGluIGJpdHMsIGlzIGxcbiAgdmFyIGwgPSB0aGlzLl9sZW4gKiA4XG5cbiAgLy8gQXBwZW5kIHRoZSBiaXQgMSB0byB0aGUgZW5kIG9mIHRoZSBtZXNzYWdlXG4gIHRoaXMuX2Jsb2NrW3RoaXMuX2xlbiAlIHRoaXMuX2Jsb2NrU2l6ZV0gPSAweDgwXG5cbiAgLy8gYW5kIHRoZW4gayB6ZXJvIGJpdHMsIHdoZXJlIGsgaXMgdGhlIHNtYWxsZXN0IG5vbi1uZWdhdGl2ZSBzb2x1dGlvbiB0byB0aGUgZXF1YXRpb24gKGwgKyAxICsgaykgPT09IGZpbmFsU2l6ZSBtb2QgYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrLmZpbGwoMCwgdGhpcy5fbGVuICUgdGhpcy5fYmxvY2tTaXplICsgMSlcblxuICBpZiAobCAlICh0aGlzLl9ibG9ja1NpemUgKiA4KSA+PSB0aGlzLl9maW5hbFNpemUgKiA4KSB7XG4gICAgdGhpcy5fdXBkYXRlKHRoaXMuX2Jsb2NrKVxuICAgIHRoaXMuX2Jsb2NrLmZpbGwoMClcbiAgfVxuXG4gIC8vIHRvIHRoaXMgYXBwZW5kIHRoZSBibG9jayB3aGljaCBpcyBlcXVhbCB0byB0aGUgbnVtYmVyIGwgd3JpdHRlbiBpbiBiaW5hcnlcbiAgLy8gVE9ETzogaGFuZGxlIGNhc2Ugd2hlcmUgbCBpcyA+IE1hdGgucG93KDIsIDI5KVxuICB0aGlzLl9ibG9jay53cml0ZUludDMyQkUobCwgdGhpcy5fYmxvY2tTaXplIC0gNClcblxuICB2YXIgaGFzaCA9IHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaykgfHwgdGhpcy5faGFzaCgpXG5cbiAgcmV0dXJuIGVuYyA/IGhhc2gudG9TdHJpbmcoZW5jKSA6IGhhc2hcbn1cblxuSGFzaC5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdfdXBkYXRlIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3MnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hcbiIsInZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBTSEEgKGFsZ29yaXRobSkge1xuICBhbGdvcml0aG0gPSBhbGdvcml0aG0udG9Mb3dlckNhc2UoKVxuXG4gIHZhciBBbGdvcml0aG0gPSBleHBvcnRzW2FsZ29yaXRobV1cbiAgaWYgKCFBbGdvcml0aG0pIHRocm93IG5ldyBFcnJvcihhbGdvcml0aG0gKyAnIGlzIG5vdCBzdXBwb3J0ZWQgKHdlIGFjY2VwdCBwdWxsIHJlcXVlc3RzKScpXG5cbiAgcmV0dXJuIG5ldyBBbGdvcml0aG0oKVxufVxuXG5leHBvcnRzLnNoYSA9IHJlcXVpcmUoJy4vc2hhJylcbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoJy4vc2hhMScpXG5leHBvcnRzLnNoYTIyNCA9IHJlcXVpcmUoJy4vc2hhMjI0JylcbmV4cG9ydHMuc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKCcuL3NoYTM4NCcpXG5leHBvcnRzLnNoYTUxMiA9IHJlcXVpcmUoJy4vc2hhNTEyJylcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTAsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGRlcml2ZWQgZnJvbSBzaGExLmpzIG9mIHRoZSBzYW1lIHJlcG9zaXRvcnkuXG4gKiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIFNIQS0wIGFuZCBTSEEtMSBpcyBqdXN0IGEgYml0d2lzZSByb3RhdGUgbGVmdFxuICogb3BlcmF0aW9uIHdhcyBhZGRlZC5cbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBLID0gW1xuICAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjIHwgMCwgMHhjYTYyYzFkNiB8IDBcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYSAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhLCBIYXNoKVxuXG5TaGEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gcm90bDUgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCA1KSB8IChudW0gPj4+IDI3KVxufVxuXG5mdW5jdGlvbiByb3RsMzAgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAzMCkgfCAobnVtID4+PiAyKVxufVxuXG5mdW5jdGlvbiBmdCAocywgYiwgYywgZCkge1xuICBpZiAocyA9PT0gMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpXG4gIGlmIChzID09PSAyKSByZXR1cm4gKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpXG4gIHJldHVybiBiIF4gYyBeIGRcbn1cblxuU2hhLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA4MDsgKytpKSBXW2ldID0gV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XVxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgODA7ICsraikge1xuICAgIHZhciBzID0gfn4oaiAvIDIwKVxuICAgIHZhciB0ID0gKHJvdGw1KGEpICsgZnQocywgYiwgYywgZCkgKyBlICsgV1tqXSArIEtbc10pIHwgMFxuXG4gICAgZSA9IGRcbiAgICBkID0gY1xuICAgIGMgPSByb3RsMzAoYilcbiAgICBiID0gYVxuICAgIGEgPSB0XG4gIH1cblxuICB0aGlzLl9hID0gKGEgKyB0aGlzLl9hKSB8IDBcbiAgdGhpcy5fYiA9IChiICsgdGhpcy5fYikgfCAwXG4gIHRoaXMuX2MgPSAoYyArIHRoaXMuX2MpIHwgMFxuICB0aGlzLl9kID0gKGQgKyB0aGlzLl9kKSB8IDBcbiAgdGhpcy5fZSA9IChlICsgdGhpcy5fZSkgfCAwXG59XG5cblNoYS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYVxuIiwiLypcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMSwgYXMgZGVmaW5lZFxuICogaW4gRklQUyBQVUIgMTgwLTFcbiAqIFZlcnNpb24gMi4xYSBDb3B5cmlnaHQgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwMi5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIGRldGFpbHMuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgSyA9IFtcbiAgMHg1YTgyNzk5OSwgMHg2ZWQ5ZWJhMSwgMHg4ZjFiYmNkYyB8IDAsIDB4Y2E2MmMxZDYgfCAwXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDgwKVxuXG5mdW5jdGlvbiBTaGExICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGExLCBIYXNoKVxuXG5TaGExLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIHJvdGwxIChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgMSkgfCAobnVtID4+PiAzMSlcbn1cblxuZnVuY3Rpb24gcm90bDUgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCA1KSB8IChudW0gPj4+IDI3KVxufVxuXG5mdW5jdGlvbiByb3RsMzAgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAzMCkgfCAobnVtID4+PiAyKVxufVxuXG5mdW5jdGlvbiBmdCAocywgYiwgYywgZCkge1xuICBpZiAocyA9PT0gMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpXG4gIGlmIChzID09PSAyKSByZXR1cm4gKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpXG4gIHJldHVybiBiIF4gYyBeIGRcbn1cblxuU2hhMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgODA7ICsraSkgV1tpXSA9IHJvdGwxKFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl0pXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA4MDsgKytqKSB7XG4gICAgdmFyIHMgPSB+fihqIC8gMjApXG4gICAgdmFyIHQgPSAocm90bDUoYSkgKyBmdChzLCBiLCBjLCBkKSArIGUgKyBXW2pdICsgS1tzXSkgfCAwXG5cbiAgICBlID0gZFxuICAgIGQgPSBjXG4gICAgYyA9IHJvdGwzMChiKVxuICAgIGIgPSBhXG4gICAgYSA9IHRcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbn1cblxuU2hhMS5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcigyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTFcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjI0ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjI0LCBTaGEyNTYpXG5cblNoYTIyNC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4YzEwNTllZDhcbiAgdGhpcy5fYiA9IDB4MzY3Y2Q1MDdcbiAgdGhpcy5fYyA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZCA9IDB4ZjcwZTU5MzlcbiAgdGhpcy5fZSA9IDB4ZmZjMDBiMzFcbiAgdGhpcy5fZiA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZyA9IDB4NjRmOThmYTdcbiAgdGhpcy5faCA9IDB4YmVmYTRmYTRcblxuICByZXR1cm4gdGhpc1xufVxuXG5TaGEyMjQucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IG5ldyBCdWZmZXIoMjgpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEyMjRcbiIsIi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG5cbnZhciBLID0gW1xuICAweDQyOEEyRjk4LCAweDcxMzc0NDkxLCAweEI1QzBGQkNGLCAweEU5QjVEQkE1LFxuICAweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuICAweEQ4MDdBQTk4LCAweDEyODM1QjAxLCAweDI0MzE4NUJFLCAweDU1MEM3REMzLFxuICAweDcyQkU1RDc0LCAweDgwREVCMUZFLCAweDlCREMwNkE3LCAweEMxOUJGMTc0LFxuICAweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuICAweDJERTkyQzZGLCAweDRBNzQ4NEFBLCAweDVDQjBBOURDLCAweDc2Rjk4OERBLFxuICAweDk4M0U1MTUyLCAweEE4MzFDNjZELCAweEIwMDMyN0M4LCAweEJGNTk3RkM3LFxuICAweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuICAweDI3QjcwQTg1LCAweDJFMUIyMTM4LCAweDREMkM2REZDLCAweDUzMzgwRDEzLFxuICAweDY1MEE3MzU0LCAweDc2NkEwQUJCLCAweDgxQzJDOTJFLCAweDkyNzIyQzg1LFxuICAweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuICAweEQxOTJFODE5LCAweEQ2OTkwNjI0LCAweEY0MEUzNTg1LCAweDEwNkFBMDcwLFxuICAweDE5QTRDMTE2LCAweDFFMzc2QzA4LCAweDI3NDg3NzRDLCAweDM0QjBCQ0I1LFxuICAweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuICAweDc0OEY4MkVFLCAweDc4QTU2MzZGLCAweDg0Qzg3ODE0LCAweDhDQzcwMjA4LFxuICAweDkwQkVGRkZBLCAweEE0NTA2Q0VCLCAweEJFRjlBM0Y3LCAweEM2NzE3OEYyXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDY0KVxuXG5mdW5jdGlvbiBTaGEyNTYgKCkge1xuICB0aGlzLmluaXQoKVxuXG4gIHRoaXMuX3cgPSBXIC8vIG5ldyBBcnJheSg2NClcblxuICBIYXNoLmNhbGwodGhpcywgNjQsIDU2KVxufVxuXG5pbmhlcml0cyhTaGEyNTYsIEhhc2gpXG5cblNoYTI1Ni5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4NmEwOWU2NjdcbiAgdGhpcy5fYiA9IDB4YmI2N2FlODVcbiAgdGhpcy5fYyA9IDB4M2M2ZWYzNzJcbiAgdGhpcy5fZCA9IDB4YTU0ZmY1M2FcbiAgdGhpcy5fZSA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZiA9IDB4OWIwNTY4OGNcbiAgdGhpcy5fZyA9IDB4MWY4M2Q5YWJcbiAgdGhpcy5faCA9IDB4NWJlMGNkMTlcblxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBjaCAoeCwgeSwgeikge1xuICByZXR1cm4geiBeICh4ICYgKHkgXiB6KSlcbn1cblxuZnVuY3Rpb24gbWFqICh4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIHwgKHogJiAoeCB8IHkpKVxufVxuXG5mdW5jdGlvbiBzaWdtYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAyIHwgeCA8PCAzMCkgXiAoeCA+Pj4gMTMgfCB4IDw8IDE5KSBeICh4ID4+PiAyMiB8IHggPDwgMTApXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCkge1xuICByZXR1cm4gKHggPj4+IDYgfCB4IDw8IDI2KSBeICh4ID4+PiAxMSB8IHggPDwgMjEpIF4gKHggPj4+IDI1IHwgeCA8PCA3KVxufVxuXG5mdW5jdGlvbiBnYW1tYTAgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA3IHwgeCA8PCAyNSkgXiAoeCA+Pj4gMTggfCB4IDw8IDE0KSBeICh4ID4+PiAzKVxufVxuXG5mdW5jdGlvbiBnYW1tYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiAxNyB8IHggPDwgMTUpIF4gKHggPj4+IDE5IHwgeCA8PCAxMykgXiAoeCA+Pj4gMTApXG59XG5cblNoYTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuICB2YXIgZiA9IHRoaXMuX2YgfCAwXG4gIHZhciBnID0gdGhpcy5fZyB8IDBcbiAgdmFyIGggPSB0aGlzLl9oIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgNjQ7ICsraSkgV1tpXSA9IChnYW1tYTEoV1tpIC0gMl0pICsgV1tpIC0gN10gKyBnYW1tYTAoV1tpIC0gMTVdKSArIFdbaSAtIDE2XSkgfCAwXG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCA2NDsgKytqKSB7XG4gICAgdmFyIFQxID0gKGggKyBzaWdtYTEoZSkgKyBjaChlLCBmLCBnKSArIEtbal0gKyBXW2pdKSB8IDBcbiAgICB2YXIgVDIgPSAoc2lnbWEwKGEpICsgbWFqKGEsIGIsIGMpKSB8IDBcblxuICAgIGggPSBnXG4gICAgZyA9IGZcbiAgICBmID0gZVxuICAgIGUgPSAoZCArIFQxKSB8IDBcbiAgICBkID0gY1xuICAgIGMgPSBiXG4gICAgYiA9IGFcbiAgICBhID0gKFQxICsgVDIpIHwgMFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxuICB0aGlzLl9mID0gKGYgKyB0aGlzLl9mKSB8IDBcbiAgdGhpcy5fZyA9IChnICsgdGhpcy5fZykgfCAwXG4gIHRoaXMuX2ggPSAoaCArIHRoaXMuX2gpIHwgMFxufVxuXG5TaGEyNTYucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IG5ldyBCdWZmZXIoMzIpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2gsIDI4KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjU2XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi9zaGE1MTInKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxuXG52YXIgVyA9IG5ldyBBcnJheSgxNjApXG5cbmZ1bmN0aW9uIFNoYTM4NCAoKSB7XG4gIHRoaXMuaW5pdCgpXG4gIHRoaXMuX3cgPSBXXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDEyOCwgMTEyKVxufVxuXG5pbmhlcml0cyhTaGEzODQsIFNIQTUxMilcblxuU2hhMzg0LnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9haCA9IDB4Y2JiYjlkNWRcbiAgdGhpcy5fYmggPSAweDYyOWEyOTJhXG4gIHRoaXMuX2NoID0gMHg5MTU5MDE1YVxuICB0aGlzLl9kaCA9IDB4MTUyZmVjZDhcbiAgdGhpcy5fZWggPSAweDY3MzMyNjY3XG4gIHRoaXMuX2ZoID0gMHg4ZWI0NGE4N1xuICB0aGlzLl9naCA9IDB4ZGIwYzJlMGRcbiAgdGhpcy5faGggPSAweDQ3YjU0ODFkXG5cbiAgdGhpcy5fYWwgPSAweGMxMDU5ZWQ4XG4gIHRoaXMuX2JsID0gMHgzNjdjZDUwN1xuICB0aGlzLl9jbCA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZGwgPSAweGY3MGU1OTM5XG4gIHRoaXMuX2VsID0gMHhmZmMwMGIzMVxuICB0aGlzLl9mbCA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZ2wgPSAweDY0Zjk4ZmE3XG4gIHRoaXMuX2hsID0gMHhiZWZhNGZhNFxuXG4gIHJldHVybiB0aGlzXG59XG5cblNoYTM4NC5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcig0OClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2FoLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2JoLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2NoLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kaCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZWgsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2ZoLCB0aGlzLl9mbCwgNDApXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGEzODRcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcblxudmFyIEsgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoMTYwKVxuXG5mdW5jdGlvbiBTaGE1MTIgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCAxMjgsIDExMilcbn1cblxuaW5oZXJpdHMoU2hhNTEyLCBIYXNoKVxuXG5TaGE1MTIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2FoID0gMHg2YTA5ZTY2N1xuICB0aGlzLl9iaCA9IDB4YmI2N2FlODVcbiAgdGhpcy5fY2ggPSAweDNjNmVmMzcyXG4gIHRoaXMuX2RoID0gMHhhNTRmZjUzYVxuICB0aGlzLl9laCA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZmggPSAweDliMDU2ODhjXG4gIHRoaXMuX2doID0gMHgxZjgzZDlhYlxuICB0aGlzLl9oaCA9IDB4NWJlMGNkMTlcblxuICB0aGlzLl9hbCA9IDB4ZjNiY2M5MDhcbiAgdGhpcy5fYmwgPSAweDg0Y2FhNzNiXG4gIHRoaXMuX2NsID0gMHhmZTk0ZjgyYlxuICB0aGlzLl9kbCA9IDB4NWYxZDM2ZjFcbiAgdGhpcy5fZWwgPSAweGFkZTY4MmQxXG4gIHRoaXMuX2ZsID0gMHgyYjNlNmMxZlxuICB0aGlzLl9nbCA9IDB4ZmI0MWJkNmJcbiAgdGhpcy5faGwgPSAweDEzN2UyMTc5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDI4IHwgeGwgPDwgNCkgXiAoeGwgPj4+IDIgfCB4IDw8IDMwKSBeICh4bCA+Pj4gNyB8IHggPDwgMjUpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxNCB8IHhsIDw8IDE4KSBeICh4ID4+PiAxOCB8IHhsIDw8IDE0KSBeICh4bCA+Pj4gOSB8IHggPDwgMjMpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNyB8IHhsIDw8IDI1KVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2KVxufVxuXG5mdW5jdGlvbiBHYW1tYTFsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNiB8IHhsIDw8IDI2KVxufVxuXG5mdW5jdGlvbiBnZXRDYXJyeSAoYSwgYikge1xuICByZXR1cm4gKGEgPj4+IDApIDwgKGIgPj4+IDApID8gMSA6IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGFoID0gdGhpcy5fYWggfCAwXG4gIHZhciBiaCA9IHRoaXMuX2JoIHwgMFxuICB2YXIgY2ggPSB0aGlzLl9jaCB8IDBcbiAgdmFyIGRoID0gdGhpcy5fZGggfCAwXG4gIHZhciBlaCA9IHRoaXMuX2VoIHwgMFxuICB2YXIgZmggPSB0aGlzLl9maCB8IDBcbiAgdmFyIGdoID0gdGhpcy5fZ2ggfCAwXG4gIHZhciBoaCA9IHRoaXMuX2hoIHwgMFxuXG4gIHZhciBhbCA9IHRoaXMuX2FsIHwgMFxuICB2YXIgYmwgPSB0aGlzLl9ibCB8IDBcbiAgdmFyIGNsID0gdGhpcy5fY2wgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2RsIHwgMFxuICB2YXIgZWwgPSB0aGlzLl9lbCB8IDBcbiAgdmFyIGZsID0gdGhpcy5fZmwgfCAwXG4gIHZhciBnbCA9IHRoaXMuX2dsIHwgMFxuICB2YXIgaGwgPSB0aGlzLl9obCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpICs9IDIpIHtcbiAgICBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgICBXW2kgKyAxXSA9IE0ucmVhZEludDMyQkUoaSAqIDQgKyA0KVxuICB9XG4gIGZvciAoOyBpIDwgMTYwOyBpICs9IDIpIHtcbiAgICB2YXIgeGggPSBXW2kgLSAxNSAqIDJdXG4gICAgdmFyIHhsID0gV1tpIC0gMTUgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWEwID0gR2FtbWEwKHhoLCB4bClcbiAgICB2YXIgZ2FtbWEwbCA9IEdhbW1hMGwoeGwsIHhoKVxuXG4gICAgeGggPSBXW2kgLSAyICogMl1cbiAgICB4bCA9IFdbaSAtIDIgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWExID0gR2FtbWExKHhoLCB4bClcbiAgICB2YXIgZ2FtbWExbCA9IEdhbW1hMWwoeGwsIHhoKVxuXG4gICAgLy8gV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdXG4gICAgdmFyIFdpN2ggPSBXW2kgLSA3ICogMl1cbiAgICB2YXIgV2k3bCA9IFdbaSAtIDcgKiAyICsgMV1cblxuICAgIHZhciBXaTE2aCA9IFdbaSAtIDE2ICogMl1cbiAgICB2YXIgV2kxNmwgPSBXW2kgLSAxNiAqIDIgKyAxXVxuXG4gICAgdmFyIFdpbCA9IChnYW1tYTBsICsgV2k3bCkgfCAwXG4gICAgdmFyIFdpaCA9IChnYW1tYTAgKyBXaTdoICsgZ2V0Q2FycnkoV2lsLCBnYW1tYTBsKSkgfCAwXG4gICAgV2lsID0gKFdpbCArIGdhbW1hMWwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBnYW1tYTEgKyBnZXRDYXJyeShXaWwsIGdhbW1hMWwpKSB8IDBcbiAgICBXaWwgPSAoV2lsICsgV2kxNmwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBXaTE2aCArIGdldENhcnJ5KFdpbCwgV2kxNmwpKSB8IDBcblxuICAgIFdbaV0gPSBXaWhcbiAgICBXW2kgKyAxXSA9IFdpbFxuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjA7IGogKz0gMikge1xuICAgIFdpaCA9IFdbal1cbiAgICBXaWwgPSBXW2ogKyAxXVxuXG4gICAgdmFyIG1hamggPSBtYWooYWgsIGJoLCBjaClcbiAgICB2YXIgbWFqbCA9IG1haihhbCwgYmwsIGNsKVxuXG4gICAgdmFyIHNpZ21hMGggPSBzaWdtYTAoYWgsIGFsKVxuICAgIHZhciBzaWdtYTBsID0gc2lnbWEwKGFsLCBhaClcbiAgICB2YXIgc2lnbWExaCA9IHNpZ21hMShlaCwgZWwpXG4gICAgdmFyIHNpZ21hMWwgPSBzaWdtYTEoZWwsIGVoKVxuXG4gICAgLy8gdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2pdICsgV1tqXVxuICAgIHZhciBLaWggPSBLW2pdXG4gICAgdmFyIEtpbCA9IEtbaiArIDFdXG5cbiAgICB2YXIgY2hoID0gQ2goZWgsIGZoLCBnaClcbiAgICB2YXIgY2hsID0gQ2goZWwsIGZsLCBnbClcblxuICAgIHZhciB0MWwgPSAoaGwgKyBzaWdtYTFsKSB8IDBcbiAgICB2YXIgdDFoID0gKGhoICsgc2lnbWExaCArIGdldENhcnJ5KHQxbCwgaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgY2hsKSB8IDBcbiAgICB0MWggPSAodDFoICsgY2hoICsgZ2V0Q2FycnkodDFsLCBjaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgS2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgS2loICsgZ2V0Q2FycnkodDFsLCBLaWwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgV2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgV2loICsgZ2V0Q2FycnkodDFsLCBXaWwpKSB8IDBcblxuICAgIC8vIHQyID0gc2lnbWEwICsgbWFqXG4gICAgdmFyIHQybCA9IChzaWdtYTBsICsgbWFqbCkgfCAwXG4gICAgdmFyIHQyaCA9IChzaWdtYTBoICsgbWFqaCArIGdldENhcnJ5KHQybCwgc2lnbWEwbCkpIHwgMFxuXG4gICAgaGggPSBnaFxuICAgIGhsID0gZ2xcbiAgICBnaCA9IGZoXG4gICAgZ2wgPSBmbFxuICAgIGZoID0gZWhcbiAgICBmbCA9IGVsXG4gICAgZWwgPSAoZGwgKyB0MWwpIHwgMFxuICAgIGVoID0gKGRoICsgdDFoICsgZ2V0Q2FycnkoZWwsIGRsKSkgfCAwXG4gICAgZGggPSBjaFxuICAgIGRsID0gY2xcbiAgICBjaCA9IGJoXG4gICAgY2wgPSBibFxuICAgIGJoID0gYWhcbiAgICBibCA9IGFsXG4gICAgYWwgPSAodDFsICsgdDJsKSB8IDBcbiAgICBhaCA9ICh0MWggKyB0MmggKyBnZXRDYXJyeShhbCwgdDFsKSkgfCAwXG4gIH1cblxuICB0aGlzLl9hbCA9ICh0aGlzLl9hbCArIGFsKSB8IDBcbiAgdGhpcy5fYmwgPSAodGhpcy5fYmwgKyBibCkgfCAwXG4gIHRoaXMuX2NsID0gKHRoaXMuX2NsICsgY2wpIHwgMFxuICB0aGlzLl9kbCA9ICh0aGlzLl9kbCArIGRsKSB8IDBcbiAgdGhpcy5fZWwgPSAodGhpcy5fZWwgKyBlbCkgfCAwXG4gIHRoaXMuX2ZsID0gKHRoaXMuX2ZsICsgZmwpIHwgMFxuICB0aGlzLl9nbCA9ICh0aGlzLl9nbCArIGdsKSB8IDBcbiAgdGhpcy5faGwgPSAodGhpcy5faGwgKyBobCkgfCAwXG5cbiAgdGhpcy5fYWggPSAodGhpcy5fYWggKyBhaCArIGdldENhcnJ5KHRoaXMuX2FsLCBhbCkpIHwgMFxuICB0aGlzLl9iaCA9ICh0aGlzLl9iaCArIGJoICsgZ2V0Q2FycnkodGhpcy5fYmwsIGJsKSkgfCAwXG4gIHRoaXMuX2NoID0gKHRoaXMuX2NoICsgY2ggKyBnZXRDYXJyeSh0aGlzLl9jbCwgY2wpKSB8IDBcbiAgdGhpcy5fZGggPSAodGhpcy5fZGggKyBkaCArIGdldENhcnJ5KHRoaXMuX2RsLCBkbCkpIHwgMFxuICB0aGlzLl9laCA9ICh0aGlzLl9laCArIGVoICsgZ2V0Q2FycnkodGhpcy5fZWwsIGVsKSkgfCAwXG4gIHRoaXMuX2ZoID0gKHRoaXMuX2ZoICsgZmggKyBnZXRDYXJyeSh0aGlzLl9mbCwgZmwpKSB8IDBcbiAgdGhpcy5fZ2ggPSAodGhpcy5fZ2ggKyBnaCArIGdldENhcnJ5KHRoaXMuX2dsLCBnbCkpIHwgMFxuICB0aGlzLl9oaCA9ICh0aGlzLl9oaCArIGhoICsgZ2V0Q2FycnkodGhpcy5faGwsIGhsKSkgfCAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gbmV3IEJ1ZmZlcig2NClcblxuICBmdW5jdGlvbiB3cml0ZUludDY0QkUgKGgsIGwsIG9mZnNldCkge1xuICAgIEgud3JpdGVJbnQzMkJFKGgsIG9mZnNldClcbiAgICBILndyaXRlSW50MzJCRShsLCBvZmZzZXQgKyA0KVxuICB9XG5cbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2FoLCB0aGlzLl9hbCwgMClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2JoLCB0aGlzLl9ibCwgOClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2NoLCB0aGlzLl9jbCwgMTYpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9kaCwgdGhpcy5fZGwsIDI0KVxuICB3cml0ZUludDY0QkUodGhpcy5fZWgsIHRoaXMuX2VsLCAzMilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2ZoLCB0aGlzLl9mbCwgNDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9naCwgdGhpcy5fZ2wsIDQ4KVxuICB3cml0ZUludDY0QkUodGhpcy5faGgsIHRoaXMuX2hsLCA1NilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTUxMlxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG5pbmhlcml0cyhTdHJlYW0sIEVFKTtcblN0cmVhbS5SZWFkYWJsZSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9yZWFkYWJsZS5qcycpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL2R1cGxleC5qcycpO1xuU3RyZWFtLlRyYW5zZm9ybSA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMnKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qcycpO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjQueFxuU3RyZWFtLlN0cmVhbSA9IFN0cmVhbTtcblxuXG5cbi8vIG9sZC1zdHlsZSBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoZSBwaXBlIG1ldGhvZCAodGhlIG9ubHkgcmVsZXZhbnRcbi8vIHBhcnQgb2YgdGhpcyBjbGFzcykgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgUmVhZGFibGUgY2xhc3MuXG5cbmZ1bmN0aW9uIFN0cmVhbSgpIHtcbiAgRUUuY2FsbCh0aGlzKTtcbn1cblxuU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICB2YXIgc291cmNlID0gdGhpcztcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBpZiAoZGVzdC53cml0YWJsZSkge1xuICAgICAgaWYgKGZhbHNlID09PSBkZXN0LndyaXRlKGNodW5rKSAmJiBzb3VyY2UucGF1c2UpIHtcbiAgICAgICAgc291cmNlLnBhdXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIGlmIChzb3VyY2UucmVhZGFibGUgJiYgc291cmNlLnJlc3VtZSkge1xuICAgICAgc291cmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgLy8gSWYgdGhlICdlbmQnIG9wdGlvbiBpcyBub3Qgc3VwcGxpZWQsIGRlc3QuZW5kKCkgd2lsbCBiZSBjYWxsZWQgd2hlblxuICAvLyBzb3VyY2UgZ2V0cyB0aGUgJ2VuZCcgb3IgJ2Nsb3NlJyBldmVudHMuICBPbmx5IGRlc3QuZW5kKCkgb25jZS5cbiAgaWYgKCFkZXN0Ll9pc1N0ZGlvICYmICghb3B0aW9ucyB8fCBvcHRpb25zLmVuZCAhPT0gZmFsc2UpKSB7XG4gICAgc291cmNlLm9uKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICB9XG5cbiAgdmFyIGRpZE9uRW5kID0gZmFsc2U7XG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgaWYgKHR5cGVvZiBkZXN0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIGRlc3QuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gZG9uJ3QgbGVhdmUgZGFuZ2xpbmcgcGlwZXMgd2hlbiB0aGVyZSBhcmUgZXJyb3JzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgY2xlYW51cCgpO1xuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHRoaXMsICdlcnJvcicpID09PSAwKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkIHN0cmVhbSBlcnJvciBpbiBwaXBlLlxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyByZW1vdmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkLlxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuICB9XG5cbiAgc291cmNlLm9uKCdlbmQnLCBjbGVhbnVwKTtcbiAgc291cmNlLm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3Qub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc291cmNlKTtcblxuICAvLyBBbGxvdyBmb3IgdW5peC1saWtlIHVzYWdlOiBBLnBpcGUoQikucGlwZShDKVxuICByZXR1cm4gZGVzdDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG52YXIgYnVmZmVyU2hpbSA9IHJlcXVpcmUoJ2J1ZmZlci1zaGltcycpO1xuXG52YXIgaXNFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nIHx8IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBlbmNvZGluZyA9ICcnICsgZW5jb2Rpbmc7XG4gIHN3aXRjaCAoZW5jb2RpbmcgJiYgZW5jb2RpbmcudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6Y2FzZSAndXRmOCc6Y2FzZSAndXRmLTgnOmNhc2UgJ2FzY2lpJzpjYXNlICdiaW5hcnknOmNhc2UgJ2Jhc2U2NCc6Y2FzZSAndWNzMic6Y2FzZSAndWNzLTInOmNhc2UgJ3V0ZjE2bGUnOmNhc2UgJ3V0Zi0xNmxlJzpjYXNlICdyYXcnOlxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX25vcm1hbGl6ZUVuY29kaW5nKGVuYykge1xuICBpZiAoIWVuYykgcmV0dXJuICd1dGY4JztcbiAgdmFyIHJldHJpZWQ7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmMpIHtcbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gJ3V0ZjgnO1xuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuICd1dGYxNmxlJztcbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gJ2xhdGluMSc7XG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGVuYztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChyZXRyaWVkKSByZXR1cm47IC8vIHVuZGVmaW5lZFxuICAgICAgICBlbmMgPSAoJycgKyBlbmMpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHJpZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxufTtcblxuLy8gRG8gbm90IGNhY2hlIGBCdWZmZXIuaXNFbmNvZGluZ2Agd2hlbiBjaGVja2luZyBlbmNvZGluZyBuYW1lcyBhcyBzb21lXG4vLyBtb2R1bGVzIG1vbmtleS1wYXRjaCBpdCB0byBzdXBwb3J0IGFkZGl0aW9uYWwgZW5jb2RpbmdzXG5mdW5jdGlvbiBub3JtYWxpemVFbmNvZGluZyhlbmMpIHtcbiAgdmFyIG5lbmMgPSBfbm9ybWFsaXplRW5jb2RpbmcoZW5jKTtcbiAgaWYgKHR5cGVvZiBuZW5jICE9PSAnc3RyaW5nJyAmJiAoQnVmZmVyLmlzRW5jb2RpbmcgPT09IGlzRW5jb2RpbmcgfHwgIWlzRW5jb2RpbmcoZW5jKSkpIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuYyk7XG4gIHJldHVybiBuZW5jIHx8IGVuYztcbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLlxuZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gU3RyaW5nRGVjb2RlcjtcbmZ1bmN0aW9uIFN0cmluZ0RlY29kZXIoZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IG5vcm1hbGl6ZUVuY29kaW5nKGVuY29kaW5nKTtcbiAgdmFyIG5iO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIHRoaXMudGV4dCA9IHV0ZjE2VGV4dDtcbiAgICAgIHRoaXMuZW5kID0gdXRmMTZFbmQ7XG4gICAgICBuYiA9IDQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIHRoaXMuZmlsbExhc3QgPSB1dGY4RmlsbExhc3Q7XG4gICAgICBuYiA9IDQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgdGhpcy50ZXh0ID0gYmFzZTY0VGV4dDtcbiAgICAgIHRoaXMuZW5kID0gYmFzZTY0RW5kO1xuICAgICAgbmIgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBzaW1wbGVXcml0ZTtcbiAgICAgIHRoaXMuZW5kID0gc2ltcGxlRW5kO1xuICAgICAgcmV0dXJuO1xuICB9XG4gIHRoaXMubGFzdE5lZWQgPSAwO1xuICB0aGlzLmxhc3RUb3RhbCA9IDA7XG4gIHRoaXMubGFzdENoYXIgPSBidWZmZXJTaGltLmFsbG9jVW5zYWZlKG5iKTtcbn1cblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmIChidWYubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gIHZhciByO1xuICB2YXIgaTtcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICByID0gdGhpcy5maWxsTGFzdChidWYpO1xuICAgIGlmIChyID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBpID0gdGhpcy5sYXN0TmVlZDtcbiAgICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgfSBlbHNlIHtcbiAgICBpID0gMDtcbiAgfVxuICBpZiAoaSA8IGJ1Zi5sZW5ndGgpIHJldHVybiByID8gciArIHRoaXMudGV4dChidWYsIGkpIDogdGhpcy50ZXh0KGJ1ZiwgaSk7XG4gIHJldHVybiByIHx8ICcnO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gdXRmOEVuZDtcblxuLy8gUmV0dXJucyBvbmx5IGNvbXBsZXRlIGNoYXJhY3RlcnMgaW4gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLnRleHQgPSB1dGY4VGV4dDtcblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBwYXJ0aWFsIG5vbi1VVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlclxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZmlsbExhc3QgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59O1xuXG4vLyBDaGVja3MgdGhlIHR5cGUgb2YgYSBVVEYtOCBieXRlLCB3aGV0aGVyIGl0J3MgQVNDSUksIGEgbGVhZGluZyBieXRlLCBvciBhXG4vLyBjb250aW51YXRpb24gYnl0ZS5cbmZ1bmN0aW9uIHV0ZjhDaGVja0J5dGUoYnl0ZSkge1xuICBpZiAoYnl0ZSA8PSAweDdGKSByZXR1cm4gMDtlbHNlIGlmIChieXRlID4+IDUgPT09IDB4MDYpIHJldHVybiAyO2Vsc2UgaWYgKGJ5dGUgPj4gNCA9PT0gMHgwRSkgcmV0dXJuIDM7ZWxzZSBpZiAoYnl0ZSA+PiAzID09PSAweDFFKSByZXR1cm4gNDtcbiAgcmV0dXJuIC0xO1xufVxuXG4vLyBDaGVja3MgYXQgbW9zdCAzIGJ5dGVzIGF0IHRoZSBlbmQgb2YgYSBCdWZmZXIgaW4gb3JkZXIgdG8gZGV0ZWN0IGFuXG4vLyBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyLiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzICgyLCAzLCBvciA0KVxuLy8gbmVlZGVkIHRvIGNvbXBsZXRlIHRoZSBVVEYtOCBjaGFyYWN0ZXIgKGlmIGFwcGxpY2FibGUpIGFyZSByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0luY29tcGxldGUoc2VsZiwgYnVmLCBpKSB7XG4gIHZhciBqID0gYnVmLmxlbmd0aCAtIDE7XG4gIGlmIChqIDwgaSkgcmV0dXJuIDA7XG4gIHZhciBuYiA9IHV0ZjhDaGVja0J5dGUoYnVmW2pdKTtcbiAgaWYgKG5iID49IDApIHtcbiAgICBpZiAobmIgPiAwKSBzZWxmLmxhc3ROZWVkID0gbmIgLSAxO1xuICAgIHJldHVybiBuYjtcbiAgfVxuICBpZiAoLS1qIDwgaSkgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDI7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpKSByZXR1cm4gMDtcbiAgbmIgPSB1dGY4Q2hlY2tCeXRlKGJ1ZltqXSk7XG4gIGlmIChuYiA+PSAwKSB7XG4gICAgaWYgKG5iID4gMCkge1xuICAgICAgaWYgKG5iID09PSAyKSBuYiA9IDA7ZWxzZSBzZWxmLmxhc3ROZWVkID0gbmIgLSAzO1xuICAgIH1cbiAgICByZXR1cm4gbmI7XG4gIH1cbiAgcmV0dXJuIDA7XG59XG5cbi8vIFZhbGlkYXRlcyBhcyBtYW55IGNvbnRpbnVhdGlvbiBieXRlcyBmb3IgYSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3RlciBhc1xuLy8gbmVlZGVkIG9yIGFyZSBhdmFpbGFibGUuIElmIHdlIHNlZSBhIG5vbi1jb250aW51YXRpb24gYnl0ZSB3aGVyZSB3ZSBleHBlY3Rcbi8vIG9uZSwgd2UgXCJyZXBsYWNlXCIgdGhlIHZhbGlkYXRlZCBjb250aW51YXRpb24gYnl0ZXMgd2UndmUgc2VlbiBzbyBmYXIgd2l0aFxuLy8gVVRGLTggcmVwbGFjZW1lbnQgY2hhcmFjdGVycyAoJ1xcdWZmZmQnKSwgdG8gbWF0Y2ggdjgncyBVVEYtOCBkZWNvZGluZ1xuLy8gYmVoYXZpb3IuIFRoZSBjb250aW51YXRpb24gYnl0ZSBjaGVjayBpcyBpbmNsdWRlZCB0aHJlZSB0aW1lcyBpbiB0aGUgY2FzZVxuLy8gd2hlcmUgYWxsIG9mIHRoZSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgY2hhcmFjdGVyIGV4aXN0IGluIHRoZSBzYW1lIGJ1ZmZlci5cbi8vIEl0IGlzIGFsc28gZG9uZSB0aGlzIHdheSBhcyBhIHNsaWdodCBwZXJmb3JtYW5jZSBpbmNyZWFzZSBpbnN0ZWFkIG9mIHVzaW5nIGFcbi8vIGxvb3AuXG5mdW5jdGlvbiB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHNlbGYsIGJ1ZiwgcCkge1xuICBpZiAoKGJ1ZlswXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgc2VsZi5sYXN0TmVlZCA9IDA7XG4gICAgcmV0dXJuICdcXHVmZmZkJy5yZXBlYXQocCk7XG4gIH1cbiAgaWYgKHNlbGYubGFzdE5lZWQgPiAxICYmIGJ1Zi5sZW5ndGggPiAxKSB7XG4gICAgaWYgKChidWZbMV0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgc2VsZi5sYXN0TmVlZCA9IDE7XG4gICAgICByZXR1cm4gJ1xcdWZmZmQnLnJlcGVhdChwICsgMSk7XG4gICAgfVxuICAgIGlmIChzZWxmLmxhc3ROZWVkID4gMiAmJiBidWYubGVuZ3RoID4gMikge1xuICAgICAgaWYgKChidWZbMl0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgICBzZWxmLmxhc3ROZWVkID0gMjtcbiAgICAgICAgcmV0dXJuICdcXHVmZmZkJy5yZXBlYXQocCArIDIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBBdHRlbXB0cyB0byBjb21wbGV0ZSBhIG11bHRpLWJ5dGUgVVRGLTggY2hhcmFjdGVyIHVzaW5nIGJ5dGVzIGZyb20gYSBCdWZmZXIuXG5mdW5jdGlvbiB1dGY4RmlsbExhc3QoYnVmKSB7XG4gIHZhciBwID0gdGhpcy5sYXN0VG90YWwgLSB0aGlzLmxhc3ROZWVkO1xuICB2YXIgciA9IHV0ZjhDaGVja0V4dHJhQnl0ZXModGhpcywgYnVmLCBwKTtcbiAgaWYgKHIgIT09IHVuZGVmaW5lZCkgcmV0dXJuIHI7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCBwLCAwLCB0aGlzLmxhc3ROZWVkKTtcbiAgICByZXR1cm4gdGhpcy5sYXN0Q2hhci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCB0aGlzLmxhc3RUb3RhbCk7XG4gIH1cbiAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgcCwgMCwgYnVmLmxlbmd0aCk7XG4gIHRoaXMubGFzdE5lZWQgLT0gYnVmLmxlbmd0aDtcbn1cblxuLy8gUmV0dXJucyBhbGwgY29tcGxldGUgVVRGLTggY2hhcmFjdGVycyBpbiBhIEJ1ZmZlci4gSWYgdGhlIEJ1ZmZlciBlbmRlZCBvbiBhXG4vLyBwYXJ0aWFsIGNoYXJhY3RlciwgdGhlIGNoYXJhY3RlcidzIGJ5dGVzIGFyZSBidWZmZXJlZCB1bnRpbCB0aGUgcmVxdWlyZWRcbi8vIG51bWJlciBvZiBieXRlcyBhcmUgYXZhaWxhYmxlLlxuZnVuY3Rpb24gdXRmOFRleHQoYnVmLCBpKSB7XG4gIHZhciB0b3RhbCA9IHV0ZjhDaGVja0luY29tcGxldGUodGhpcywgYnVmLCBpKTtcbiAgaWYgKCF0aGlzLmxhc3ROZWVkKSByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGY4JywgaSk7XG4gIHRoaXMubGFzdFRvdGFsID0gdG90YWw7XG4gIHZhciBlbmQgPSBidWYubGVuZ3RoIC0gKHRvdGFsIC0gdGhpcy5sYXN0TmVlZCk7XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIDAsIGVuZCk7XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjgnLCBpLCBlbmQpO1xufVxuXG4vLyBGb3IgVVRGLTgsIGEgcmVwbGFjZW1lbnQgY2hhcmFjdGVyIGZvciBlYWNoIGJ1ZmZlcmVkIGJ5dGUgb2YgYSAocGFydGlhbClcbi8vIGNoYXJhY3RlciBuZWVkcyB0byBiZSBhZGRlZCB0byB0aGUgb3V0cHV0LlxuZnVuY3Rpb24gdXRmOEVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkgcmV0dXJuIHIgKyAnXFx1ZmZmZCcucmVwZWF0KHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZCk7XG4gIHJldHVybiByO1xufVxuXG4vLyBVVEYtMTZMRSB0eXBpY2FsbHkgbmVlZHMgdHdvIGJ5dGVzIHBlciBjaGFyYWN0ZXIsIGJ1dCBldmVuIGlmIHdlIGhhdmUgYW4gZXZlblxuLy8gbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSwgd2UgbmVlZCB0byBjaGVjayBpZiB3ZSBlbmQgb24gYSBsZWFkaW5nL2hpZ2hcbi8vIHN1cnJvZ2F0ZS4gSW4gdGhhdCBjYXNlLCB3ZSBuZWVkIHRvIHdhaXQgZm9yIHRoZSBuZXh0IHR3byBieXRlcyBpbiBvcmRlciB0b1xuLy8gZGVjb2RlIHRoZSBsYXN0IGNoYXJhY3RlciBwcm9wZXJseS5cbmZ1bmN0aW9uIHV0ZjE2VGV4dChidWYsIGkpIHtcbiAgaWYgKChidWYubGVuZ3RoIC0gaSkgJSAyID09PSAwKSB7XG4gICAgdmFyIHIgPSBidWYudG9TdHJpbmcoJ3V0ZjE2bGUnLCBpKTtcbiAgICBpZiAocikge1xuICAgICAgdmFyIGMgPSByLmNoYXJDb2RlQXQoci5sZW5ndGggLSAxKTtcbiAgICAgIGlmIChjID49IDB4RDgwMCAmJiBjIDw9IDB4REJGRikge1xuICAgICAgICB0aGlzLmxhc3ROZWVkID0gMjtcbiAgICAgICAgdGhpcy5sYXN0VG90YWwgPSA0O1xuICAgICAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAyXTtcbiAgICAgICAgdGhpcy5sYXN0Q2hhclsxXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gICAgICAgIHJldHVybiByLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHI7XG4gIH1cbiAgdGhpcy5sYXN0TmVlZCA9IDE7XG4gIHRoaXMubGFzdFRvdGFsID0gMjtcbiAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMV07XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ3V0ZjE2bGUnLCBpLCBidWYubGVuZ3RoIC0gMSk7XG59XG5cbi8vIEZvciBVVEYtMTZMRSB3ZSBkbyBub3QgZXhwbGljaXRseSBhcHBlbmQgc3BlY2lhbCByZXBsYWNlbWVudCBjaGFyYWN0ZXJzIGlmIHdlXG4vLyBlbmQgb24gYSBwYXJ0aWFsIGNoYXJhY3Rlciwgd2Ugc2ltcGx5IGxldCB2OCBoYW5kbGUgdGhhdC5cbmZ1bmN0aW9uIHV0ZjE2RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSB7XG4gICAgdmFyIGVuZCA9IHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZDtcbiAgICByZXR1cm4gciArIHRoaXMubGFzdENoYXIudG9TdHJpbmcoJ3V0ZjE2bGUnLCAwLCBlbmQpO1xuICB9XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBiYXNlNjRUZXh0KGJ1ZiwgaSkge1xuICB2YXIgbiA9IChidWYubGVuZ3RoIC0gaSkgJSAzO1xuICBpZiAobiA9PT0gMCkgcmV0dXJuIGJ1Zi50b1N0cmluZygnYmFzZTY0JywgaSk7XG4gIHRoaXMubGFzdE5lZWQgPSAzIC0gbjtcbiAgdGhpcy5sYXN0VG90YWwgPSAzO1xuICBpZiAobiA9PT0gMSkge1xuICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDJdO1xuICAgIHRoaXMubGFzdENoYXJbMV0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICB9XG4gIHJldHVybiBidWYudG9TdHJpbmcoJ2Jhc2U2NCcsIGksIGJ1Zi5sZW5ndGggLSBuKTtcbn1cblxuZnVuY3Rpb24gYmFzZTY0RW5kKGJ1Zikge1xuICB2YXIgciA9IGJ1ZiAmJiBidWYubGVuZ3RoID8gdGhpcy53cml0ZShidWYpIDogJyc7XG4gIGlmICh0aGlzLmxhc3ROZWVkKSByZXR1cm4gciArIHRoaXMubGFzdENoYXIudG9TdHJpbmcoJ2Jhc2U2NCcsIDAsIDMgLSB0aGlzLmxhc3ROZWVkKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIFBhc3MgYnl0ZXMgb24gdGhyb3VnaCBmb3Igc2luZ2xlLWJ5dGUgZW5jb2RpbmdzIChlLmcuIGFzY2lpLCBsYXRpbjEsIGhleClcbmZ1bmN0aW9uIHNpbXBsZVdyaXRlKGJ1Zikge1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiBzaW1wbGVFbmQoYnVmKSB7XG4gIHJldHVybiBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xufSIsInZhciBuZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MvYnJvd3Nlci5qcycpLm5leHRUaWNrO1xudmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xudmFyIHNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xudmFyIGltbWVkaWF0ZUlkcyA9IHt9O1xudmFyIG5leHRJbW1lZGlhdGVJZCA9IDA7XG5cbi8vIERPTSBBUElzLCBmb3IgY29tcGxldGVuZXNzXG5cbmV4cG9ydHMuc2V0VGltZW91dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRUaW1lb3V0LCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgd2luZG93LCBhcmd1bWVudHMpLCBjbGVhckludGVydmFsKTtcbn07XG5leHBvcnRzLmNsZWFyVGltZW91dCA9XG5leHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBmdW5jdGlvbih0aW1lb3V0KSB7IHRpbWVvdXQuY2xvc2UoKTsgfTtcblxuZnVuY3Rpb24gVGltZW91dChpZCwgY2xlYXJGbikge1xuICB0aGlzLl9pZCA9IGlkO1xuICB0aGlzLl9jbGVhckZuID0gY2xlYXJGbjtcbn1cblRpbWVvdXQucHJvdG90eXBlLnVucmVmID0gVGltZW91dC5wcm90b3R5cGUucmVmID0gZnVuY3Rpb24oKSB7fTtcblRpbWVvdXQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2NsZWFyRm4uY2FsbCh3aW5kb3csIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBUaGF0J3Mgbm90IGhvdyBub2RlLmpzIGltcGxlbWVudHMgaXQgYnV0IHRoZSBleHBvc2VkIGFwaSBpcyB0aGUgc2FtZS5cbmV4cG9ydHMuc2V0SW1tZWRpYXRlID0gdHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiID8gc2V0SW1tZWRpYXRlIDogZnVuY3Rpb24oZm4pIHtcbiAgdmFyIGlkID0gbmV4dEltbWVkaWF0ZUlkKys7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzLmxlbmd0aCA8IDIgPyBmYWxzZSA6IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuICBpbW1lZGlhdGVJZHNbaWRdID0gdHJ1ZTtcblxuICBuZXh0VGljayhmdW5jdGlvbiBvbk5leHRUaWNrKCkge1xuICAgIGlmIChpbW1lZGlhdGVJZHNbaWRdKSB7XG4gICAgICAvLyBmbi5jYWxsKCkgaXMgZmFzdGVyIHNvIHdlIG9wdGltaXplIGZvciB0aGUgY29tbW9uIHVzZS1jYXNlXG4gICAgICAvLyBAc2VlIGh0dHA6Ly9qc3BlcmYuY29tL2NhbGwtYXBwbHktc2VndVxuICAgICAgaWYgKGFyZ3MpIHtcbiAgICAgICAgZm4uYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmbi5jYWxsKG51bGwpO1xuICAgICAgfVxuICAgICAgLy8gUHJldmVudCBpZHMgZnJvbSBsZWFraW5nXG4gICAgICBleHBvcnRzLmNsZWFySW1tZWRpYXRlKGlkKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpZDtcbn07XG5cbmV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSB0eXBlb2YgY2xlYXJJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIiA/IGNsZWFySW1tZWRpYXRlIDogZnVuY3Rpb24oaWQpIHtcbiAgZGVsZXRlIGltbWVkaWF0ZUlkc1tpZF07XG59OyIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlcHJlY2F0ZTtcblxuLyoqXG4gKiBNYXJrIHRoYXQgYSBtZXRob2Qgc2hvdWxkIG5vdCBiZSB1c2VkLlxuICogUmV0dXJucyBhIG1vZGlmaWVkIGZ1bmN0aW9uIHdoaWNoIHdhcm5zIG9uY2UgYnkgZGVmYXVsdC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLm5vRGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbiAqXG4gKiBJZiBgbG9jYWxTdG9yYWdlLnRocm93RGVwcmVjYXRpb24gPSB0cnVlYCBpcyBzZXQsIHRoZW4gZGVwcmVjYXRlZCBmdW5jdGlvbnNcbiAqIHdpbGwgdGhyb3cgYW4gRXJyb3Igd2hlbiBpbnZva2VkLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudHJhY2VEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCBpbnZva2UgYGNvbnNvbGUudHJhY2UoKWAgaW5zdGVhZCBvZiBgY29uc29sZS5lcnJvcigpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiAtIHRoZSBmdW5jdGlvbiB0byBkZXByZWNhdGVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtc2cgLSB0aGUgc3RyaW5nIHRvIHByaW50IHRvIHRoZSBjb25zb2xlIHdoZW4gYGZuYCBpcyBpbnZva2VkXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgbmV3IFwiZGVwcmVjYXRlZFwiIHZlcnNpb24gb2YgYGZuYFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZXByZWNhdGUgKGZuLCBtc2cpIHtcbiAgaWYgKGNvbmZpZygnbm9EZXByZWNhdGlvbicpKSB7XG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgdmFyIHdhcm5lZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBkZXByZWNhdGVkKCkge1xuICAgIGlmICghd2FybmVkKSB7XG4gICAgICBpZiAoY29uZmlnKCd0aHJvd0RlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKGNvbmZpZygndHJhY2VEZXByZWNhdGlvbicpKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUud2Fybihtc2cpO1xuICAgICAgfVxuICAgICAgd2FybmVkID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICByZXR1cm4gZGVwcmVjYXRlZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgYGxvY2FsU3RvcmFnZWAgZm9yIGJvb2xlYW4gdmFsdWVzIGZvciB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvbmZpZyAobmFtZSkge1xuICAvLyBhY2Nlc3NpbmcgZ2xvYmFsLmxvY2FsU3RvcmFnZSBjYW4gdHJpZ2dlciBhIERPTUV4Y2VwdGlvbiBpbiBzYW5kYm94ZWQgaWZyYW1lc1xuICB0cnkge1xuICAgIGlmICghZ2xvYmFsLmxvY2FsU3RvcmFnZSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChfKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWwgPSBnbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO1xuICBpZiAobnVsbCA9PSB2YWwpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJztcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cblxuLy8gTWFyayB0aGF0IGEgbWV0aG9kIHNob3VsZCBub3QgYmUgdXNlZC5cbi8vIFJldHVybnMgYSBtb2RpZmllZCBmdW5jdGlvbiB3aGljaCB3YXJucyBvbmNlIGJ5IGRlZmF1bHQuXG4vLyBJZiAtLW5vLWRlcHJlY2F0aW9uIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuZXhwb3J0cy5kZXByZWNhdGUgPSBmdW5jdGlvbihmbiwgbXNnKSB7XG4gIC8vIEFsbG93IGZvciBkZXByZWNhdGluZyB0aGluZ3MgaW4gdGhlIHByb2Nlc3Mgb2Ygc3RhcnRpbmcgdXAuXG4gIGlmIChpc1VuZGVmaW5lZChnbG9iYWwucHJvY2VzcykpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5kZXByZWNhdGUoZm4sIG1zZykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3Mubm9EZXByZWNhdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBmbjtcbiAgfVxuXG4gIHZhciB3YXJuZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZGVwcmVjYXRlZCgpIHtcbiAgICBpZiAoIXdhcm5lZCkge1xuICAgICAgaWYgKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uKSB7XG4gICAgICAgIGNvbnNvbGUudHJhY2UobXNnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICAgIHdhcm5lZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgcmV0dXJuIGRlcHJlY2F0ZWQ7XG59O1xuXG5cbnZhciBkZWJ1Z3MgPSB7fTtcbnZhciBkZWJ1Z0Vudmlyb247XG5leHBvcnRzLmRlYnVnbG9nID0gZnVuY3Rpb24oc2V0KSB7XG4gIGlmIChpc1VuZGVmaW5lZChkZWJ1Z0Vudmlyb24pKVxuICAgIGRlYnVnRW52aXJvbiA9IHByb2Nlc3MuZW52Lk5PREVfREVCVUcgfHwgJyc7XG4gIHNldCA9IHNldC50b1VwcGVyQ2FzZSgpO1xuICBpZiAoIWRlYnVnc1tzZXRdKSB7XG4gICAgaWYgKG5ldyBSZWdFeHAoJ1xcXFxiJyArIHNldCArICdcXFxcYicsICdpJykudGVzdChkZWJ1Z0Vudmlyb24pKSB7XG4gICAgICB2YXIgcGlkID0gcHJvY2Vzcy5waWQ7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbXNnID0gZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignJXMgJWQ6ICVzJywgc2V0LCBwaWQsIG1zZyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1Z3Nbc2V0XSA9IGZ1bmN0aW9uKCkge307XG4gICAgfVxuICB9XG4gIHJldHVybiBkZWJ1Z3Nbc2V0XTtcbn07XG5cblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIGFycmF5LmZvckVhY2goZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChrZXlzLmluZGV4T2YoJ21lc3NhZ2UnKSA+PSAwIHx8IGtleXMuaW5kZXhPZignZGVzY3JpcHRpb24nKSA+PSAwKSkge1xuICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGN0eC5zZWVuLmluZGV4T2YoZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IG91dHB1dC5yZWR1Y2UoZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmV4cG9ydHMuaXNCdWZmZXIgPSByZXF1aXJlKCcuL3N1cHBvcnQvaXNCdWZmZXInKTtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG4iXX0= diff --git a/build/bitsharesjs.min.js b/build/bitsharesjs.min.js deleted file mode 100644 index 0a755b7c..00000000 --- a/build/bitsharesjs.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).bitshares_js=e()}}(function(){return function n(o,a,f){function u(t,e){if(!a[t]){if(!o[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(h)return h(t,!0);var i=new Error("Cannot find module '"+t+"'");throw i.code="MODULE_NOT_FOUND",i}var s=a[t]={exports:{}};o[t][0].call(s.exports,function(e){return u(o[t][1][e]||e)},s,s.exports,n,o,a,f)}return a[t].exports}for(var h="function"==typeof require&&require,e=0;e=t.length)break;s=t[i++]}else{if((i=t.next()).done)break;s=i.value}var n=s,o=f.getPrivateKey(n);u.add_signer(o,n),a[n]=!0}}return u.get_potential_signatures().then(function(e){var t=e.pubkeys,r=e.addys,i=f.getPubkeys_having_PrivateKey(t,r);return u.get_required_signatures(i).then(function(e){var t=e,r=Array.isArray(t),i=0;for(t=r?t:t[Symbol.iterator]();;){var s;if(r){if(i>=t.length)break;s=t[i++]}else{if((i=t.next()).done)break;s=i.value}var n=s;if(!a[n]){var o=f.getPrivateKey(n);if(!o)throw new Error("Missing signing key for "+n);u.add_signer(o,n)}}})}).then(function(){return c?u.broadcast():u.serialize()})})},e.prototype.finalize=function(){var s=this;return new Promise(function(e,t){if(s.tr_buffer)throw new Error("already finalized");e(l.Apis.instance().db_api().exec("get_objects",[["2.1.0"]]).then(function(e){n=e[0].time,0===s.expiration&&(s.expiration=c()+l.ChainConfig.expire_in_secs),s.ref_block_num=65535&e[0].head_block_number,s.ref_block_prefix=new h(e[0].head_block_id,"hex").readUInt32LE(4);for(var t,r=s.operations,i=0;ie?i[r].ops.forEach(function(t){2===n[t].length&&"propIdx"in i[r]?i[r].propIdx.forEach(function(e){s[e]=n[t][1][e]}):2===n[t].length?s[t]=n[t][0]:s[t]=n[t]}):i[r].ops.forEach(function(e){2===n[e].length&&"propIdx"in i[r]?i[r].propIdx.forEach(function(e){s[e]=a[r][e]}):s[e]=o[r][e]})};for(var t in i)e(t);return s}var d=l(s),p={};for(var _ in u)p[_]=l(u[_]);for(var g=function(e,t){if(!e.fee||0===e.fee.amount||e.fee.amount.toString&&"0"===e.fee.amount.toString())if(v){var r=function(e,t){var r=B(e),i=j[r];if(i){if(i.original===t)return t;if(-1!==i.duplicates.indexOf(t))return i.original}}(E.ops.operation.toObject(b.operations[t]),t);e.fee=0<=r?d[r]:d[t]}else e.fee=d[t];if(e.proposed_ops){for(var i=0;i=i.length)break;o=i[n++]}else{if((n=i.next()).done)break;o=n.value}if(o[0].toHex()===r)return}this.signer_private_keys.push([e,t])},e.prototype.sign=function(){var e=0>1?o.add(s):o,h=e.pointFromX(f,u),c=h.multiply(s);(0,_.default)(e.isInfinity(c),"nR is not a valid curve point");var l=t.negate().mod(s),d=o.modInverse(s),p=h.multiplyTwo(a,n,l).multiply(d);return e.validate(p),p}r.calcPubKeyRecoveryParam=function(e,t,r,i){for(var s=0;s<4;s++)if(n(e,t,r,s).equals(i))return s;throw new Error("Unable to find valid recovery factor")},r.deterministicGenerateK=p,r.recoverPubKey=n,r.sign=function(r,e,i,t){var s=c.default.fromBuffer(e),n=r.n,o=r.G,a=void 0,f=void 0;p(r,e,i,function(e){var t=o.multiply(e);return!r.isInfinity(t)&&0!==(a=t.affineX.mod(n)).signum()&&0!==(f=e.modInverse(n).multiply(s.add(i.multiply(a))).mod(n)).signum()},t);var u=n.shiftRight(1);return 0s.length;)e.writeUint8(0)}},i.public_key=function(e,t){if(e){if(!t)return r=i.fixed_data(e,33),n.default.fromBuffer(r);var r=t.toBuffer();e.append(r.toString("binary"),"binary")}},i.ripemd160=function(e,t){if(e)return t?void i.fixed_data(e,20,t):i.fixed_data(e,20)},i.time_point_sec=function(e,t){return t?(t=Math.ceil(t/1e3),void e.writeInt32(t)):(t=e.readInt32(),new Date(1e3*t))},i}();r.default=a,t.exports=r.default},{"../../ecc/src/PublicKey":"/home/sigve/Dev/Bitshares/bitsharesjs/dist/ecc/src/PublicKey.js","safe-buffer":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/safe-buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/dist/serializer/src/SerializerValidation.js":[function(e,t,r){"use strict";r.__esModule=!0;var i,s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n=e("bytebuffer"),o=e("../../chain/src/ChainTypes"),a=(i=o)&&i.__esModule?i:{default:i};var f=9007199254740991,u=-9007199254740991,h={is_empty:function(e){return null==e},required:function(e){var t=1n.length)throw new Error("two many fields");for(;0=n.length)throw new Error("index out of range");var s=n[i];r[s.name]=s.type.fromByteBuffer(e),t--}return r}},appendByteBuffer:function(e,r){var i=new o.default(o.default.DEFAULT_CAPACITY,o.default.LITTLE_ENDIAN),s=0;r&&n.forEach(function(e,t){void 0!==r[e.name]&&null!==r[e.name]&&(i.writeVarint32(t),e.type.appendByteBuffer(i,r[e.name]),s++)}),e.writeVarint32(s),i.flip(),e.append(i)},fromObject:function(t){if(void 0!==t){var r={};return n.forEach(function(e){void 0!==t[e.name]&&null!==t[e.name]&&(r[e.name]=e.type.fromObject(t[e.name]))}),r}},toObject:function(r){var i=1>=8;for(;0>=8}for(var o=0;e[o]===h&&o>16&255,n[o++]=t>>8&255,n[o++]=255&t;var u,h;2===s&&(t=c[e.charCodeAt(f)]<<2|c[e.charCodeAt(f+1)]>>4,n[o++]=255&t);1===s&&(t=c[e.charCodeAt(f)]<<10|c[e.charCodeAt(f+1)]<<4|c[e.charCodeAt(f+2)]>>2,n[o++]=t>>8&255,n[o++]=255&t);return n},r.fromByteArray=function(e){for(var t,r=e.length,i=r%3,s=[],n=0,o=r-i;n>2]+a[t<<4&63]+"==")):2===i&&(t=(e[r-2]<<8)+e[r-1],s.push(a[t>>10]+a[t>>4&63]+a[t<<2&63]+"="));return s.join("")};for(var a=[],c=[],l="undefined"!=typeof Uint8Array?Uint8Array:Array,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,n=i.length;s>18&63]+a[s>>12&63]+a[s>>6&63]+a[63&s]);return n.join("")}c["-".charCodeAt(0)]=62,c["_".charCodeAt(0)]=63},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bigi/lib/bigi.js":[function(e,t,r){function y(e,t,r){if(!(this instanceof y))return new y(e,t,r);null!=e&&("number"==typeof e?this.fromNumber(e,t,r):null==t&&"string"!=typeof e?this.fromString(e,256):this.fromString(e,t))}var i=y.prototype;i.__bigi=e("../package.json").version,y.isBigInteger=function(e,t){return e&&e.__bigi&&(!t||e.__bigi===i.__bigi)},y.prototype.am=function(e,t,r,i,s,n){for(;0<=--n;){var o=t*this[e++]+r[i]+s;s=Math.floor(o/67108864),r[i++]=67108863&o}return s},y.prototype.DB=26,y.prototype.DM=67108863;var s=y.prototype.DV=1<<26;y.prototype.FV=Math.pow(2,52),y.prototype.F1=26,y.prototype.F2=0;var n,o,a="0123456789abcdefghijklmnopqrstuvwxyz",f=new Array;for(n="0".charCodeAt(0),o=0;o<=9;++o)f[n++]=o;for(n="a".charCodeAt(0),o=10;o<36;++o)f[n++]=o;for(n="A".charCodeAt(0),o=10;o<36;++o)f[n++]=o;function u(e){return a.charAt(e)}function h(e,t){var r=f[e.charCodeAt(t)];return null==r?-1:r}function g(e){var t=new y;return t.fromInt(e),t}function w(e){var t,r=1;return 0!=(t=e>>>16)&&(e=t,r+=16),0!=(t=e>>8)&&(e=t,r+=8),0!=(t=e>>4)&&(e=t,r+=4),0!=(t=e>>2)&&(e=t,r+=2),0!=(t=e>>1)&&(e=t,r+=1),r}function m(e){this.m=e}function v(e){this.m=e,this.mp=e.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<>=16,t+=16),0==(255&e)&&(e>>=8,t+=8),0==(15&e)&&(e>>=4,t+=4),0==(3&e)&&(e>>=2,t+=2),0==(1&e)&&++t,t}function b(e){for(var t=0;0!=e;)e&=e-1,++t;return t}function j(){}function B(e){return e}function E(e){this.r2=new y,this.q3=new y,y.ONE.dlShiftTo(2*e.t,this.r2),this.mu=this.r2.divide(e),this.m=e}m.prototype.convert=function(e){return e.s<0||0<=e.compareTo(this.m)?e.mod(this.m):e},m.prototype.revert=function(e){return e},m.prototype.reduce=function(e){e.divRemTo(this.m,null,e)},m.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},m.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},v.prototype.convert=function(e){var t=new y;return e.abs().dlShiftTo(this.m.t,t),t.divRemTo(this.m,null,t),e.s<0&&0>15)*this.mpl&this.um)<<15)&e.DM;for(e[r=t+this.m.t]+=this.m.am(0,i,e,t,0,this.m.t);e[r]>=e.DV;)e[r]-=e.DV,e[++r]++}e.clamp(),e.drShiftTo(this.m.t,e),0<=e.compareTo(this.m)&&e.subTo(this.m,e)},v.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},v.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)},i.copyTo=function(e){for(var t=this.t-1;0<=t;--t)e[t]=this[t];e.t=this.t,e.s=this.s},i.fromInt=function(e){this.t=1,this.s=e<0?-1:0,0i.DB?(i[i.t-1]|=(a&(1<>i.DB-o):i[i.t-1]|=a<=i.DB&&(o-=i.DB))}8==r&&0!=(128&e[0])&&(i.s=-1,0>n|f,f=(i[r]&o)<=r.t)t.t=0;else{var s=e%r.DB,n=r.DB-s,o=(1<>s;for(var a=i+1;a>s;0>=r.DB;if(e.t>=r.DB;s+=r.s}else{for(s+=r.s;i>=r.DB;s-=e.s}t.s=s<0?-1:0,s<-1?t[i++]=r.DV+s:0=t.DV&&(e[r+t.t]-=t.DV,e[r+t.t+1]=1)}0>i.F2:0),d=i.FV/l,p=(1<>f)&&(n=!0,o=u(i));0<=a;)f>(f+=r.DB-t)):(i=r[a]>>(f-=t)&s,f<=0&&(f+=r.DB,--a)),0>3},i.mod=function(e){var t=new y;return this.abs().divRemTo(e,null,t),this.s<0&&02*this.m.t)return e.mod(this.m);if(e.compareTo(this.m)<0)return e;var t=new y;return e.copyTo(t),this.reduce(t),t},E.prototype.revert=function(e){return e},E.prototype.reduce=function(e){var t=this;for(e.drShiftTo(t.m.t-1,t.r2),e.t>t.m.t+1&&(e.t=t.m.t+1,e.clamp()),t.mu.multiplyUpperTo(t.r2,t.m.t+1,t.q3),t.m.multiplyLowerTo(t.q3,t.m.t+1,t.r2);e.compareTo(t.r2)<0;)e.dAddOffset(1,t.m.t+1);for(e.subTo(t.r2,e);0<=e.compareTo(t.m);)e.subTo(t.m,e)},E.prototype.mulTo=function(e,t,r){e.multiplyTo(t,r),this.reduce(r)},E.prototype.sqrTo=function(e,t){e.squareTo(t),this.reduce(t)};var x=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],D=(1<<26)/x[x.length-1];i.chunkSize=function(e){return Math.floor(Math.LN2*this.DB/Math.log(e))},i.toRadix=function(e){if(null==e&&(e=10),0==this.signum()||e<2||36=i&&(r.dMultiply(s),r.dAddOffset(a,0),a=o=0))}0e&&i.subTo(y.ONE.shiftLeft(e-1),i);else{var s=new Array,n=7&e;s.length=1+(e>>3),t.nextBytes(s),0>=r.DB;if(e.t>=r.DB;s+=r.s}else{for(s+=r.s;i>=r.DB;s+=e.s}t.s=s<0?-1:0,0=this.DV;)this[t]-=this.DV,++t>=this.t&&(this[this.t++]=0),++this[t]}},i.multiplyLowerTo=function(e,t,r){var i,s=Math.min(this.t+e.t,t);for(r.s=0,r.t=s;0>1)>x.length&&(e=x.length);for(var s=new y(null),n=[],o=0;o>24},i.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},i.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},i.toByteArray=function(){var e=this,t=e.t,r=new Array;r[0]=e.s;var i,s=e.DB-t*e.DB%8,n=0;if(0>s)!=(e.s&e.DM)>>s&&(r[n++]=i|e.s<>(s+=e.DB-8)):(i=e[t]>>(s-=8)&255,s<=0&&(s+=e.DB,--t)),0!=(128&i)&&(i|=-256),0===n&&(128&e.s)!=(128&i)&&++n,(0=this.t?0!=this.s:0!=(this[t]&1<>s-f&u:(c=(e[d]&(1<>this.DB+s-f)),a=r;0==(1&c);)c>>=1,--a;if((s-=a)<0&&(s+=this.DB,--d),p)o[c].copyTo(n),p=!1;else{for(;1this.urls.length)return r(new Error("Tried "+s+" connections, none of which worked: "+JSON.stringify(this.urls.concat(this.url))));var o=function(e,t,r){return n.urlChangeCallback&&n.urlChangeCallback(n.urls[s]),n.connectWithFallback(i,n.urls[s],s+1,t,r)};return t&&r?this.connect(i,e).then(t).catch(function(e){o(0,t,r)}):new Promise(function(t,r){n.connect(i,void 0).then(t).catch(function(e){o(0,t,r)})})},a.prototype.checkConnections=function(){var o=0>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function a(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(1=e.byteLength)throw new RangeError("'offset' is out of bounds");if(s>e.byteLength-i)throw new RangeError("'length' is out of bounds");return new u(e.slice(i,i+s))}if(u.isBuffer(e)){var n=new u(e.length);return e.copy(n,0,0,e.length),n}if(e){if(Array.isArray(e)||"undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return new u(e);if("Buffer"===e.type&&Array.isArray(e.data))return new u(e.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")},i.allocUnsafeSlow=function(e){if("function"==typeof u.allocUnsafeSlow)return u.allocUnsafeSlow(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(h<=e)throw new RangeError("size is too large");return new t(e)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js":[function(e,t,r){"use strict";var i=e("base64-js"),n=e("ieee754");r.Buffer=c,r.SlowBuffer=function(e){+e!=e&&(e=0);return c.alloc(+e)},r.INSPECT_MAX_BYTES=50;var s=2147483647;function o(e){if(s>>1;case"base64":return O(e).length;default:if(i)return C(e).length;t=(""+t).toLowerCase(),i=!0}}function p(e,t,r){var i=e[t];e[t]=e[r],e[r]=i}function _(e,t,r,i,s){if(0===e.length)return-1;if("string"==typeof r?(i=r,r=0):2147483647=e.length){if(s)return-1;r=e.length-1}else if(r<0){if(!s)return-1;r=0}if("string"==typeof t&&(t=c.from(t,i)),c.isBuffer(t))return 0===t.length?-1:g(e,t,r,i,s);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?s?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):g(e,[t],r,i,s);throw new TypeError("val must be string, number or Buffer")}function g(e,t,r,i,s){var n,o=1,a=e.length,f=t.length;if(void 0!==i&&("ucs2"===(i=String(i).toLowerCase())||"ucs-2"===i||"utf16le"===i||"utf-16le"===i)){if(e.length<2||t.length<2)return-1;a/=o=2,f/=2,r/=2}function u(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(s){var h=-1;for(n=r;n>>10&1023|55296),h=56320|1023&h),i.push(h),s+=c}return function(e){var t=e.length;if(t<=w)return String.fromCharCode.apply(String,e);var r="",i=0;for(;ithis.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return E(this,t,r);case"utf8":case"utf-8":return y(this,t,r);case"ascii":return j(this,t,r);case"latin1":case"binary":return B(this,t,r);case"base64":return b(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return x(this,t,r);default:if(i)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),i=!0}}.apply(this,arguments)},c.prototype.equals=function(e){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===c.compare(this,e)},c.prototype.inspect=function(){var e="",t=r.INSPECT_MAX_BYTES;return 0t&&(e+=" ... ")),""},c.prototype.compare=function(e,t,r,i,s){if(!c.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===i&&(i=0),void 0===s&&(s=this.length),t<0||r>e.length||i<0||s>this.length)throw new RangeError("out of range index");if(s<=i&&r<=t)return 0;if(s<=i)return-1;if(r<=t)return 1;if(this===e)return 0;for(var n=(s>>>=0)-(i>>>=0),o=(r>>>=0)-(t>>>=0),a=Math.min(n,o),f=this.slice(i,s),u=e.slice(t,r),h=0;h>>=0,isFinite(r)?(r>>>=0,void 0===i&&(i="utf8")):(i=r,r=void 0)}var s=this.length-t;if((void 0===r||sthis.length)throw new RangeError("Attempt to write outside buffer bounds");i||(i="utf8");for(var n,o,a,f,u,h,c,l,d,p=!1;;)switch(i){case"hex":return m(this,e,t,r);case"utf8":case"utf-8":return l=t,d=r,U(C(e,(c=this).length-l),c,l,d);case"ascii":return v(this,e,t,r);case"latin1":case"binary":return v(this,e,t,r);case"base64":return f=this,u=t,h=r,U(O(e),f,u,h);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return o=t,a=r,U(function(e,t){for(var r,i,s,n=[],o=0;o>8,s=r%256,n.push(s),n.push(i);return n}(e,(n=this).length-o),n,o,a);default:if(p)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),p=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var w=4096;function j(e,t,r){var i="";r=Math.min(e.length,r);for(var s=t;se.length)throw new RangeError("Index out of range")}function S(e,t,r,i,s,n){if(r+i>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function k(e,t,r,i,s){return t=+t,r>>>=0,s||S(e,0,r,4),n.write(e,t,r,i,23,4),r+4}function I(e,t,r,i,s){return t=+t,r>>>=0,s||S(e,0,r,8),n.write(e,t,r,i,52,8),r+8}c.prototype.slice=function(e,t){var r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):r>>=0,t>>>=0,r||D(e,t,this.length);for(var i=this[e],s=1,n=0;++n>>=0,t>>>=0,r||D(e,t,this.length);for(var i=this[e+--t],s=1;0>>=0,t||D(e,1,this.length),this[e]},c.prototype.readUInt16LE=function(e,t){return e>>>=0,t||D(e,2,this.length),this[e]|this[e+1]<<8},c.prototype.readUInt16BE=function(e,t){return e>>>=0,t||D(e,2,this.length),this[e]<<8|this[e+1]},c.prototype.readUInt32LE=function(e,t){return e>>>=0,t||D(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},c.prototype.readUInt32BE=function(e,t){return e>>>=0,t||D(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},c.prototype.readIntLE=function(e,t,r){e>>>=0,t>>>=0,r||D(e,t,this.length);for(var i=this[e],s=1,n=0;++n>>=0,t>>>=0,r||D(e,t,this.length);for(var i=t,s=1,n=this[e+--i];0>>=0,t||D(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},c.prototype.readInt16LE=function(e,t){e>>>=0,t||D(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},c.prototype.readInt16BE=function(e,t){e>>>=0,t||D(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},c.prototype.readInt32LE=function(e,t){return e>>>=0,t||D(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},c.prototype.readInt32BE=function(e,t){return e>>>=0,t||D(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},c.prototype.readFloatLE=function(e,t){return e>>>=0,t||D(e,4,this.length),n.read(this,e,!0,23,4)},c.prototype.readFloatBE=function(e,t){return e>>>=0,t||D(e,4,this.length),n.read(this,e,!1,23,4)},c.prototype.readDoubleLE=function(e,t){return e>>>=0,t||D(e,8,this.length),n.read(this,e,!0,52,8)},c.prototype.readDoubleBE=function(e,t){return e>>>=0,t||D(e,8,this.length),n.read(this,e,!1,52,8)},c.prototype.writeUIntLE=function(e,t,r,i){(e=+e,t>>>=0,r>>>=0,i)||T(this,e,t,r,Math.pow(2,8*r)-1,0);var s=1,n=0;for(this[t]=255&e;++n>>=0,r>>>=0,i)||T(this,e,t,r,Math.pow(2,8*r)-1,0);var s=r-1,n=1;for(this[t+s]=255&e;0<=--s&&(n*=256);)this[t+s]=e/n&255;return t+r},c.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,1,255,0),this[t]=255&e,t+1},c.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},c.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},c.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},c.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},c.prototype.writeIntLE=function(e,t,r,i){if(e=+e,t>>>=0,!i){var s=Math.pow(2,8*r-1);T(this,e,t,r,s-1,-s)}var n=0,o=1,a=0;for(this[t]=255&e;++n>0)-a&255;return t+r},c.prototype.writeIntBE=function(e,t,r,i){if(e=+e,t>>>=0,!i){var s=Math.pow(2,8*r-1);T(this,e,t,r,s-1,-s)}var n=r-1,o=1,a=0;for(this[t+n]=255&e;0<=--n&&(o*=256);)e<0&&0===a&&0!==this[t+n+1]&&(a=1),this[t+n]=(e/o>>0)-a&255;return t+r},c.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},c.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},c.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},c.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},c.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},c.prototype.writeFloatLE=function(e,t,r){return k(this,e,t,!0,r)},c.prototype.writeFloatBE=function(e,t,r){return k(this,e,t,!1,r)},c.prototype.writeDoubleLE=function(e,t,r){return I(this,e,t,!0,r)},c.prototype.writeDoubleBE=function(e,t,r){return I(this,e,t,!1,r)},c.prototype.copy=function(e,t,r,i){if(!c.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r||(r=0),i||0===i||(i=this.length),t>=e.length&&(t=e.length),t||(t=0),0=this.length)throw new RangeError("Index out of range");if(i<0)throw new RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,e||(e=0),"number"==typeof e)for(n=t;n>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;n.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;n.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return n}function O(e){return i.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(A,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function U(e,t,r,i){for(var s=0;s=t.length||s>=e.length);++s)t[s+r]=e[s];return s}function M(e){return e instanceof ArrayBuffer||null!=e&&null!=e.constructor&&"ArrayBuffer"===e.constructor.name&&"number"==typeof e.byteLength}function q(e){return e!=e}},{"base64-js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/base64-js/index.js",ieee754:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ieee754/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/bytebuffer/dist/bytebuffer.js":[function(t,e,r){var i,s;i=this,s=function(f){"use strict";var p=function(e,t,r){if(void 0===e&&(e=p.DEFAULT_CAPACITY),void 0===t&&(t=p.DEFAULT_ENDIAN),void 0===r&&(r=p.DEFAULT_NOASSERT),!r){if((e|=0)<0)throw RangeError("Illegal capacity");t=!!t,r=!!r}this.buffer=0===e?n:new ArrayBuffer(e),this.view=0===e?null:new Uint8Array(this.buffer),this.offset=0,this.markedOffset=-1,this.limit=e,this.littleEndian=t,this.noAssert=r};p.VERSION="5.0.1",p.LITTLE_ENDIAN=!0,p.BIG_ENDIAN=!1,p.DEFAULT_CAPACITY=16,p.DEFAULT_ENDIAN=p.BIG_ENDIAN,p.DEFAULT_NOASSERT=!1,p.Long=f||null;var o=p.prototype;o.__isByteBuffer__,Object.defineProperty(o,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var n=new ArrayBuffer(0),r=String.fromCharCode;function a(e){var t=0;return function(){return t>1,h=-7,c=r?s-1:0,l=r?-1:1,d=e[t+c];for(c+=l,n=d&(1<<-h)-1,d>>=-h,h+=a;0>=-h,h+=i;0>1,l=23===s?Math.pow(2,-24)-Math.pow(2,-77):0,d=i?0:n-1,p=i?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=h):(o=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-o))<1&&(o--,f*=2),2<=(t+=1<=o+c?l/f:l*Math.pow(2,1-c))*f&&(o++,f/=2),h<=o+c?(a=0,o=h):1<=o+c?(a=(t*f-1)*Math.pow(2,s),o+=c):(a=t*Math.pow(2,c-1)*Math.pow(2,s),o=0));8<=s;e[r+d]=255&a,d+=p,a/=256,s-=8);for(o=o<>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i,s=t,n=e.length,o=n>>3,a=0;for(t+=this.writeVarint32(n,t);o--;)i=1&!!e[a++]|(1&!!e[a++])<<1|(1&!!e[a++])<<2|(1&!!e[a++])<<3|(1&!!e[a++])<<4|(1&!!e[a++])<<5|(1&!!e[a++])<<6|(1&!!e[a++])<<7,this.writeByte(i,t++);if(a>3,o=0,a=[];for(e+=i.length;n--;)r=this.readByte(e++),a[o++]=!!(1&r),a[o++]=!!(2&r),a[o++]=!!(4&r),a[o++]=!!(8&r),a[o++]=!!(16&r),a[o++]=!!(32&r),a[o++]=!!(64&r),a[o++]=!!(128&r);if(o>f++&1)}return t&&(this.offset=e),a},o.readBytes=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+"+e+") <= "+this.buffer.byteLength)}var i=this.slice(t,t+e);return r&&(this.offset+=e),i},o.writeBytes=o.append,o.writeInt8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var i=this.buffer.byteLength;return it?i:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},o.writeByte=o.writeInt8,o.readInt8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return 128==(128&r)&&(r=-(255-r+1)),t&&(this.offset+=1),r},o.readByte=o.readInt8,o.writeUint8=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=1;var i=this.buffer.byteLength;return it?i:t),t-=1,this.view[t]=e,r&&(this.offset+=1),this},o.writeUInt8=o.writeUint8,o.readUint8=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=this.view[e];return t&&(this.offset+=1),r},o.readUInt8=o.readUint8,o.writeInt16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var i=this.buffer.byteLength;return it?i:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},o.writeShort=o.writeInt16,o.readInt16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),32768==(32768&r)&&(r=-(65535-r+1)),t&&(this.offset+=2),r},o.readShort=o.readInt16,o.writeUint16=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=2;var i=this.buffer.byteLength;return it?i:t),t-=2,this.littleEndian?(this.view[t+1]=(65280&e)>>>8,this.view[t]=255&e):(this.view[t]=(65280&e)>>>8,this.view[t+1]=255&e),r&&(this.offset+=2),this},o.writeUInt16=o.writeUint16,o.readUint16=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e],r|=this.view[e+1]<<8):(r=this.view[e]<<8,r|=this.view[e+1]),t&&(this.offset+=2),r},o.readUInt16=o.readUint16,o.writeInt32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var i=this.buffer.byteLength;return it?i:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},o.writeInt=o.writeInt32,o.readInt32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),r|=0,t&&(this.offset+=4),r},o.readInt=o.readInt32,o.writeUint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var i=this.buffer.byteLength;return it?i:t),t-=4,this.littleEndian?(this.view[t+3]=e>>>24&255,this.view[t+2]=e>>>16&255,this.view[t+1]=e>>>8&255,this.view[t]=255&e):(this.view[t]=e>>>24&255,this.view[t+1]=e>>>16&255,this.view[t+2]=e>>>8&255,this.view[t+3]=255&e),r&&(this.offset+=4),this},o.writeUInt32=o.writeUint32,o.readUint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0):(r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0),t&&(this.offset+=4),r},o.readUInt32=o.readUint32,f&&(o.writeInt64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var i=this.buffer.byteLength;it?i:t),t-=8;var s=e.low,n=e.high;return this.littleEndian?(this.view[t+3]=s>>>24&255,this.view[t+2]=s>>>16&255,this.view[t+1]=s>>>8&255,this.view[t]=255&s,t+=4,this.view[t+3]=n>>>24&255,this.view[t+2]=n>>>16&255,this.view[t+1]=n>>>8&255,this.view[t]=255&n):(this.view[t]=n>>>24&255,this.view[t+1]=n>>>16&255,this.view[t+2]=n>>>8&255,this.view[t+3]=255&n,t+=4,this.view[t]=s>>>24&255,this.view[t+1]=s>>>16&255,this.view[t+2]=s>>>8&255,this.view[t+3]=255&s),r&&(this.offset+=8),this},o.writeLong=o.writeInt64,o.readInt64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,i=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,i=this.view[e+2]<<16,i|=this.view[e+1]<<8,i|=this.view[e],i+=this.view[e+3]<<24>>>0):(i=this.view[e+1]<<16,i|=this.view[e+2]<<8,i|=this.view[e+3],i+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var s=new f(r,i,!1);return t&&(this.offset+=8),s},o.readLong=o.readInt64,o.writeUint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e)),t+=8;var i=this.buffer.byteLength;it?i:t),t-=8;var s=e.low,n=e.high;return this.littleEndian?(this.view[t+3]=s>>>24&255,this.view[t+2]=s>>>16&255,this.view[t+1]=s>>>8&255,this.view[t]=255&s,t+=4,this.view[t+3]=n>>>24&255,this.view[t+2]=n>>>16&255,this.view[t+1]=n>>>8&255,this.view[t]=255&n):(this.view[t]=n>>>24&255,this.view[t+1]=n>>>16&255,this.view[t+2]=n>>>8&255,this.view[t+3]=255&n,t+=4,this.view[t]=s>>>24&255,this.view[t+1]=s>>>16&255,this.view[t+2]=s>>>8&255,this.view[t+3]=255&s),r&&(this.offset+=8),this},o.writeUInt64=o.writeUint64,o.readUint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=0,i=0;this.littleEndian?(r=this.view[e+2]<<16,r|=this.view[e+1]<<8,r|=this.view[e],r+=this.view[e+3]<<24>>>0,e+=4,i=this.view[e+2]<<16,i|=this.view[e+1]<<8,i|=this.view[e],i+=this.view[e+3]<<24>>>0):(i=this.view[e+1]<<16,i|=this.view[e+2]<<8,i|=this.view[e+3],i+=this.view[e]<<24>>>0,e+=4,r=this.view[e+1]<<16,r|=this.view[e+2]<<8,r|=this.view[e+3],r+=this.view[e]<<24>>>0);var s=new f(r,i,!0);return t&&(this.offset+=8),s},o.readUInt64=o.readUint64),o.writeFloat32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=4;var i=this.buffer.byteLength;return it?i:t),t-=4,s(this.view,e,t,this.littleEndian,23,4),r&&(this.offset+=4),this},o.writeFloat=o.writeFloat32,o.readFloat32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=i(this.view,e,this.littleEndian,23,4);return t&&(this.offset+=4),r},o.readFloat=o.readFloat32,o.writeFloat64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e)throw TypeError("Illegal value: "+e+" (not a number)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}t+=8;var i=this.buffer.byteLength;return it?i:t),t-=8,s(this.view,e,t,this.littleEndian,52,8),r&&(this.offset+=8),this},o.writeDouble=o.writeFloat64,o.readFloat64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var r=i(this.view,e,this.littleEndian,52,8);return t&&(this.offset+=8),r},o.readDouble=o.readFloat64,p.MAX_VARINT32_BYTES=5,p.calculateVarint32=function(e){return(e>>>=0)<128?1:e<16384?2:e<1<<21?3:e<1<<28?4:5},p.zigZagEncode32=function(e){return((e|=0)<<1^e>>31)>>>0},p.zigZagDecode32=function(e){return e>>>1^-(1&e)|0},o.writeVarint32=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal value: "+e+" (not an integer)");if(e|=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i,s=p.calculateVarint32(e);t+=s;var n=this.buffer.byteLength;for(nt?n:t),t-=s,e>>>=0;128<=e;)i=127&e|128,this.view[t++]=i,e>>>=7;return this.view[t++]=e,r?(this.offset=t,this):s},o.writeVarint32ZigZag=function(e,t){return this.writeVarint32(p.zigZagEncode32(e),t)},o.readVarint32=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,i=0,s=0;do{if(!this.noAssert&&e>this.limit){var n=Error("Truncated");throw n.truncated=!0,n}r=this.view[e++],i<5&&(s|=(127&r)<<7*i),++i}while(0!=(128&r));return s|=0,t?(this.offset=e,s):{value:s,length:i}},o.readVarint32ZigZag=function(e){var t=this.readVarint32(e);return"object"==typeof t?t.value=p.zigZagDecode32(t.value):t=p.zigZagDecode32(t),t},f&&(p.MAX_VARINT64_BYTES=10,p.calculateVarint64=function(e){"number"==typeof e?e=f.fromNumber(e):"string"==typeof e&&(e=f.fromString(e));var t=e.toInt()>>>0,r=e.shiftRightUnsigned(28).toInt()>>>0,i=e.shiftRightUnsigned(56).toInt()>>>0;return 0==i?0==r?t<16384?t<128?1:2:t<1<<21?3:4:r<16384?r<128?5:6:r<1<<21?7:8:i<128?9:10},p.zigZagEncode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftLeft(1).xor(e.shiftRight(63)).toUnsigned()},p.zigZagDecode64=function(e){return"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftRightUnsigned(1).xor(e.and(f.ONE).toSigned().negate()).toSigned()},o.writeVarint64=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("number"==typeof e)e=f.fromNumber(e);else if("string"==typeof e)e=f.fromString(e);else if(!(e&&e instanceof f))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=f.fromNumber(e,!1):"string"==typeof e?e=f.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned());var i=p.calculateVarint64(e),s=e.toInt()>>>0,n=e.shiftRightUnsigned(28).toInt()>>>0,o=e.shiftRightUnsigned(56).toInt()>>>0;t+=i;var a=this.buffer.byteLength;switch(at?a:t),t-=i,i){case 10:this.view[t+9]=o>>>7&1;case 9:this.view[t+8]=9!==i?128|o:127&o;case 8:this.view[t+7]=8!==i?n>>>21|128:n>>>21&127;case 7:this.view[t+6]=7!==i?n>>>14|128:n>>>14&127;case 6:this.view[t+5]=6!==i?n>>>7|128:n>>>7&127;case 5:this.view[t+4]=5!==i?128|n:127&n;case 4:this.view[t+3]=4!==i?s>>>21|128:s>>>21&127;case 3:this.view[t+2]=3!==i?s>>>14|128:s>>>14&127;case 2:this.view[t+1]=2!==i?s>>>7|128:s>>>7&127;case 1:this.view[t]=1!==i?128|s:127&s}return r?(this.offset+=i,this):i},o.writeVarint64ZigZag=function(e,t){return this.writeVarint64(p.zigZagEncode64(e),t)},o.readVarint64=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,i=0,s=0,n=0,o=0;if(i=127&(o=this.view[e++]),128&o&&(i|=(127&(o=this.view[e++]))<<7,(128&o||this.noAssert&&void 0===o)&&(i|=(127&(o=this.view[e++]))<<14,(128&o||this.noAssert&&void 0===o)&&(i|=(127&(o=this.view[e++]))<<21,(128&o||this.noAssert&&void 0===o)&&(s=127&(o=this.view[e++]),(128&o||this.noAssert&&void 0===o)&&(s|=(127&(o=this.view[e++]))<<7,(128&o||this.noAssert&&void 0===o)&&(s|=(127&(o=this.view[e++]))<<14,(128&o||this.noAssert&&void 0===o)&&(s|=(127&(o=this.view[e++]))<<21,(128&o||this.noAssert&&void 0===o)&&(n=127&(o=this.view[e++]),(128&o||this.noAssert&&void 0===o)&&(n|=(127&(o=this.view[e++]))<<7,128&o||this.noAssert&&void 0===o))))))))))throw Error("Buffer overrun");var a=f.fromBits(i|s<<28,s>>>4|n<<24,!1);return t?(this.offset=e,a):{value:a,length:e-r}},o.readVarint64ZigZag=function(e){var t=this.readVarint64(e);return t&&t.value instanceof f?t.value=p.zigZagDecode64(t.value):t=p.zigZagDecode64(t),t}),o.writeCString=function(e,t){var r=void 0===t;r&&(t=this.offset);var i,s=e.length;if(!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");for(i=0;i>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}s=l.calculateUTF16asUTF8(a(e))[1],t+=s+1;var n=this.buffer.byteLength;return nt?n:t),t-=s+1,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),this.view[t++]=0,r?(this.offset=t,this):s},o.readCString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r,i=e,s=-1;return l.decodeUTF8toUTF16(function(){if(0===s)return null;if(e>=this.limit)throw RangeError("Illegal range: Truncated data, "+e+" < "+this.limit);return 0===(s=this.view[e++])?null:s}.bind(this),r=u(),!0),t?(this.offset=e,r()):{string:r(),length:e-i}},o.writeIString=function(e,t){var r=void 0===t;if(r&&(t=this.offset),!this.noAssert){if("string"!=typeof e)throw TypeError("Illegal str: Not a string");if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i,s=t;i=l.calculateUTF16asUTF8(a(e),this.noAssert)[1],t+=4+i;var n=this.buffer.byteLength;if(nt?n:t),t-=4+i,this.littleEndian?(this.view[t+3]=i>>>24&255,this.view[t+2]=i>>>16&255,this.view[t+1]=i>>>8&255,this.view[t]=255&i):(this.view[t]=i>>>24&255,this.view[t+1]=i>>>16&255,this.view[t+2]=i>>>8&255,this.view[t+3]=255&i),t+=4,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==s+4+i)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+4+i));return r?(this.offset=t,this):t-s},o.readIString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+4) <= "+this.buffer.byteLength)}var r=e,i=this.readUint32(e),s=this.readUTF8String(i,p.METRICS_BYTES,e+=4);return e+=s.length,t?(this.offset=e,s.string):{string:s.string,length:e-r}},p.METRICS_CHARS="c",p.METRICS_BYTES="b",o.writeUTF8String=function(e,t){var r,i=void 0===t;if(i&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var s=t;r=l.calculateUTF16asUTF8(a(e))[1],t+=r;var n=this.buffer.byteLength;return nt?n:t),t-=r,l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),i?(this.offset=t,this):t-s},o.writeString=o.writeUTF8String,p.calculateUTF8Chars=function(e){return l.calculateUTF16asUTF8(a(e))[0]},p.calculateUTF8Bytes=function(e){return l.calculateUTF16asUTF8(a(e))[1]},p.calculateString=p.calculateUTF8Bytes,o.readUTF8String=function(e,t,r){"number"==typeof t&&(r=t,t=void 0);var i=void 0===r;if(i&&(r=this.offset),void 0===t&&(t=p.METRICS_CHARS),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");if(e|=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}var s,n=0,o=r;if(t===p.METRICS_CHARS){if(s=u(),l.decodeUTF8(function(){return n>>=0)<0||r+e>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+"+e+") <= "+this.buffer.byteLength)}var a=r+e;if(l.decodeUTF8toUTF16(function(){return r>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}var i,s,n=t;i=l.calculateUTF16asUTF8(a(e),this.noAssert)[1],s=p.calculateVarint32(i),t+=s+i;var o=this.buffer.byteLength;if(ot?o:t),t-=s+i,t+=this.writeVarint32(i,t),l.encodeUTF16toUTF8(a(e),function(e){this.view[t++]=e}.bind(this)),t!==n+i+s)throw RangeError("Illegal range: Truncated data, "+t+" == "+(t+i+s));return r?(this.offset=t,this):t-n},o.readVString=function(e){var t=void 0===e;if(t&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var r=e,i=this.readVarint32(e),s=this.readUTF8String(i.value,p.METRICS_BYTES,e+=i.length);return e+=s.length,t?(this.offset=e,s.string):{string:s.string,length:e-r}},o.append=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof p||(e=p.wrap(e,t));var s=e.limit-e.offset;if(s<=0)return this;r+=s;var n=this.buffer.byteLength;return nr?n:r),r-=s,this.view.set(e.view.subarray(e.offset,e.limit),r),e.offset+=s,i&&(this.offset+=s),this},o.appendTo=function(e,t){return e.append(this,t),this},o.assert=function(e){return this.noAssert=!e,this},o.capacity=function(){return this.buffer.byteLength},o.clear=function(){return this.offset=0,this.limit=this.buffer.byteLength,this.markedOffset=-1,this},o.clone=function(e){var t=new p(0,this.littleEndian,this.noAssert);return e?(t.buffer=new ArrayBuffer(this.buffer.byteLength),t.view=new Uint8Array(t.buffer)):(t.buffer=this.buffer,t.view=this.view),t.offset=this.offset,t.markedOffset=this.markedOffset,t.limit=this.limit,t},o.compact=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(0===e&&t===this.buffer.byteLength)return this;var r=t-e;if(0===r)return this.buffer=n,this.view=null,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=0,this;var i=new ArrayBuffer(r),s=new Uint8Array(i);return s.set(this.view.subarray(e,t)),this.buffer=i,this.view=s,0<=this.markedOffset&&(this.markedOffset-=e),this.offset=0,this.limit=r,this},o.copy=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}if(e===t)return new p(0,this.littleEndian,this.noAssert);var r=t-e,i=new p(r,this.littleEndian,this.noAssert);return i.offset=0,i.limit=r,0<=i.markedOffset&&(i.markedOffset-=e),this.copyTo(i,0,e,t),i},o.copyTo=function(e,t,r,i){var s,n;if(!this.noAssert&&!p.isByteBuffer(e))throw TypeError("Illegal target: Not a ByteBuffer");if(t=(n=void 0===t)?e.offset:0|t,r=(s=void 0===r)?this.offset:0|r,i=void 0===i?this.limit:0|i,t<0||t>e.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+t+" <= "+e.buffer.byteLength);if(r<0||i>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+r+" <= "+this.buffer.byteLength);var o=i-r;return 0===o?e:(e.ensureCapacity(t+o),e.view.set(this.view.subarray(r,i),t),s&&(this.offset+=o),n&&(e.offset+=o),this)},o.ensureCapacity=function(e){var t=this.buffer.byteLength;return te?t:e):this},o.fill=function(e,t,r){var i=void 0===t;if(i&&(t=this.offset),"string"==typeof e&&0>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(r<=t)return this;for(;t>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}return this.markedOffset=e,this},o.order=function(e){if(!this.noAssert&&"boolean"!=typeof e)throw TypeError("Illegal littleEndian: Not a boolean");return this.littleEndian=!!e,this},o.LE=function(e){return this.littleEndian=void 0===e||!!e,this},o.BE=function(e){return this.littleEndian=void 0!==e&&!e,this},o.prepend=function(e,t,r){"number"!=typeof t&&"string"==typeof t||(r=t,t=void 0);var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}e instanceof p||(e=p.wrap(e,t));var s=e.limit-e.offset;if(s<=0)return this;var n=s-r;if(0>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}return e===t||Array.prototype.reverse.call(this.view.subarray(e,t)),this},o.skip=function(e){if(!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal length: "+e+" (not an integer)");e|=0}var t=this.offset+e;if(!this.noAssert&&(t<0||t>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+e+" <= "+this.buffer.byteLength);return this.offset=t,this},o.slice=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}var r=this.clone();return r.offset=e,r.limit=t,r},o.toBuffer=function(e){var t=this.offset,r=this.limit;if(!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal limit: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}if(!e&&0===t&&r===this.buffer.byteLength)return this.buffer;if(t===r)return n;var i=new ArrayBuffer(r-t);return new Uint8Array(i).set(new Uint8Array(this.buffer).subarray(t,r),0),i},o.toArrayBuffer=o.toBuffer,o.toString=function(e,t,r){if(void 0===e)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";switch("number"==typeof e&&(r=t=e="utf8"),e){case"utf8":return this.toUTF8(t,r);case"base64":return this.toBase64(t,r);case"hex":return this.toHex(t,r);case"binary":return this.toBinary(t,r);case"debug":return this.toDebug();case"columns":return this.toColumns();default:throw Error("Unsupported encoding: "+e)}};var h=function(){for(var e={},s=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],o=[],t=0,r=s.length;t>2&63]),i=(3&r)<<4,null!==(r=e())?(t(s[63&((i|=r>>4&15)|r>>4&15)]),i=(15&r)<<2,null!==(r=e())?(t(s[63&(i|r>>6&3)]),t(s[63&r])):(t(s[63&i]),t(61))):(t(s[63&i]),t(61),t(61))},e.decode=function(e,t){var r,i,s;function n(e){throw Error("Illegal character code: "+e)}for(;null!==(r=e());)if(void 0===(i=o[r])&&n(r),null!==(r=e())&&(void 0===(s=o[r])&&n(r),t(i<<2>>>0|(48&s)>>4),null!==(r=e()))){if(void 0===(i=o[r])){if(61===r)break;n(r)}if(t((15&s)<<4>>>0|(60&i)>>2),null!==(r=e())){if(void 0===(s=o[r])){if(61===r)break;n(r)}t((3&i)<<6>>>0|s)}}},e.test=function(e){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)},e}();o.toBase64=function(e,t){if(void 0===e&&(e=this.offset),void 0===t&&(t=this.limit),t|=0,(e|=0)<0||t>this.capacity||tthis.capacity()||t":s+=r===this.markedOffset?"'":e||0!==r&&r!==i?" ":""}if(e&&" "!==s){for(;s.length<51;)s+=" ";o+=s+n+"\n"}return e?o:s},p.fromDebug=function(e,t,r){for(var i,s,n=e.length,o=new p((n+1)/3|0,t,r),a=0,f=0,u=!1,h=!1,c=!1,l=!1,d=!1;a":if(!r){if(l){d=!0;break}l=!0}o.limit=f,u=!1;break;case"'":if(!r){if(c){d=!0;break}c=!0}o.markedOffset=f,u=!1;break;case" ":u=!1;break;default:if(!r&&u){d=!0;break}if(s=parseInt(i+e.charAt(a++),16),!r&&(isNaN(s)||s<0||255>>=0,"number"!=typeof t||t%1!=0)throw TypeError("Illegal end: Not an integer");if(t>>>=0,e<0||tthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+t+" <= "+this.buffer.byteLength)}for(var r,i=new Array(t-e);e>6&31|192):(r<65536?t(r>>12&15|224):(t(r>>18&7|240),t(r>>12&63|128)),t(r>>6&63|128)),t(63&r|128)),r=null},decodeUTF8:function(e,t){for(var r,i,s,n,o=function(e){e=e.slice(0,e.indexOf(null));var t=Error(e.toString());throw t.name="TruncatedError",t.bytes=e,t};null!==(r=e());)if(0==(128&r))t(r);else if(192==(224&r))null===(i=e())&&o([r,i]),t((31&r)<<6|63&i);else if(224==(240&r))(null===(i=e())||null===(s=e()))&&o([r,i,s]),t((15&r)<<12|(63&i)<<6|63&s);else{if(240!=(248&r))throw RangeError("Illegal starting byte: "+r);(null===(i=e())||null===(s=e())||null===(n=e()))&&o([r,i,s,n]),t((7&r)<<18|(63&i)<<12|(63&s)<<6|63&n)}},UTF16toUTF8:function(e,t){for(var r,i=null;null!==(r=null!==i?i:e());)55296<=r&&r<=57343&&null!==(i=e())&&56320<=i&&i<=57343?(t(1024*(r-55296)+i-56320+65536),i=null):t(r);null!==i&&t(i)},UTF8toUTF16:function(e,t){var r=null;for("number"==typeof e&&(r=e,e=function(){return null});null!==r||null!==(r=e());)r<=65535?t(r):(t(55296+((r-=65536)>>10)),t(r%1024+56320)),r=null},encodeUTF16toUTF8:function(e,t){c.UTF16toUTF8(e,function(e){c.encodeUTF8(e,t)})},decodeUTF8toUTF16:function(e,t){c.decodeUTF8(e,function(e){c.UTF8toUTF16(e,t)})},calculateCodePoint:function(e){return e<128?1:e<2048?2:e<65536?3:4},calculateUTF8:function(e){for(var t,r=0;null!==(t=e());)r+=t<128?1:t<2048?2:t<65536?3:4;return r},calculateUTF16asUTF8:function(e){var t=0,r=0;return c.UTF16toUTF8(e,function(e){++t,r+=e<128?1:e<2048?2:e<65536?3:4}),[t,r]}};return o.toUTF8=function(t,r){if(void 0===t&&(t=this.offset),void 0===r&&(r=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,t<0||rthis.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+r+" <= "+this.buffer.byteLength)}var e;try{l.decodeUTF8toUTF16(function(){return tr)?t=("rmd160"===e?new f:u(e)).update(t).digest():t.lengthf?t=e(t):t.length>>8^255&s^99,u[r]=s;var n=e[h[s]=r],o=e[n],a=e[o],f=257*e[s]^16843008*s;c[r]=f<<24|f>>>8,l[r]=f<<16|f>>>16,d[r]=f<<8|f>>>24,p[r]=f;f=16843009*a^65537*o^257*n^16843008*r;_[s]=f<<24|f>>>8,g[s]=f<<16|f>>>16,m[s]=f<<8|f>>>24,v[s]=f,r?(r=n^e[e[e[a^n]]],i^=e[e[i]]):r=i=1}}();var b=[0,1,2,4,8,16,32,64,128,27,54],i=r.AES=t.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var e=this._keyPriorReset=this._key,t=e.words,r=e.sigBytes/4,i=4*((this._nRounds=r+6)+1),s=this._keySchedule=[],n=0;n>>24]<<24|u[o>>>16&255]<<16|u[o>>>8&255]<<8|u[255&o]):(o=u[(o=o<<8|o>>>24)>>>24]<<24|u[o>>>16&255]<<16|u[o>>>8&255]<<8|u[255&o],o^=b[n/r|0]<<24),s[n]=s[n-r]^o}for(var a=this._invKeySchedule=[],f=0;f>>24]]^g[u[o>>>16&255]]^m[u[o>>>8&255]]^v[u[255&o]]}}},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,c,l,d,p,u)},decryptBlock:function(e,t){var r=e[t+1];e[t+1]=e[t+3],e[t+3]=r,this._doCryptBlock(e,t,this._invKeySchedule,_,g,m,v,h);r=e[t+1];e[t+1]=e[t+3],e[t+3]=r},_doCryptBlock:function(e,t,r,i,s,n,o,a){for(var f=this._nRounds,u=e[t]^r[0],h=e[t+1]^r[1],c=e[t+2]^r[2],l=e[t+3]^r[3],d=4,p=1;p>>24]^s[h>>>16&255]^n[c>>>8&255]^o[255&l]^r[d++],g=i[h>>>24]^s[c>>>16&255]^n[l>>>8&255]^o[255&u]^r[d++],m=i[c>>>24]^s[l>>>16&255]^n[u>>>8&255]^o[255&h]^r[d++],v=i[l>>>24]^s[u>>>16&255]^n[h>>>8&255]^o[255&c]^r[d++];u=_,h=g,c=m,l=v}_=(a[u>>>24]<<24|a[h>>>16&255]<<16|a[c>>>8&255]<<8|a[255&l])^r[d++],g=(a[h>>>24]<<24|a[c>>>16&255]<<16|a[l>>>8&255]<<8|a[255&u])^r[d++],m=(a[c>>>24]<<24|a[l>>>16&255]<<16|a[u>>>8&255]<<8|a[255&h])^r[d++],v=(a[l>>>24]<<24|a[u>>>16&255]<<16|a[h>>>8&255]<<8|a[255&c])^r[d++];e[t]=_,e[t+1]=g,e[t+2]=m,e[t+3]=v},keySize:8});e.AES=t._createHelper(i)}(),s.AES},"object"==typeof r?t.exports=r=s(e("./core"),e("./enc-base64"),e("./md5"),e("./evpkdf"),e("./cipher-core")):s(i.CryptoJS)},{"./cipher-core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/cipher-core.js","./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js","./enc-base64":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-base64.js","./evpkdf":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/evpkdf.js","./md5":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/md5.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/cipher-core.js":[function(e,t,r){var i,s;i=this,s=function(e){var o,t,r,i,f,s,n,a,u,h,c,l,d,p,_,g,m,v,b;e.lib.Cipher||(r=(t=e).lib,i=r.Base,f=r.WordArray,s=r.BufferedBlockAlgorithm,(n=t.enc).Utf8,a=n.Base64,u=t.algo.EvpKDF,h=r.Cipher=s.extend({cfg:i.extend(),createEncryptor:function(e,t){return this.create(this._ENC_XFORM_MODE,e,t)},createDecryptor:function(e,t){return this.create(this._DEC_XFORM_MODE,e,t)},init:function(e,t,r){this.cfg=this.cfg.extend(r),this._xformMode=e,this._key=t,this.reset()},reset:function(){s.reset.call(this),this._doReset()},process:function(e){return this._append(e),this._process()},finalize:function(e){return e&&this._append(e),this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(){function s(e){return"string"==typeof e?b:m}return function(i){return{encrypt:function(e,t,r){return s(t).encrypt(i,e,t,r)},decrypt:function(e,t,r){return s(t).decrypt(i,e,t,r)}}}}()}),r.StreamCipher=h.extend({_doFinalize:function(){return this._process(!0)},blockSize:1}),c=t.mode={},l=r.BlockCipherMode=i.extend({createEncryptor:function(e,t){return this.Encryptor.create(e,t)},createDecryptor:function(e,t){return this.Decryptor.create(e,t)},init:function(e,t){this._cipher=e,this._iv=t}}),d=c.CBC=function(){var e=l.extend();function n(e,t,r){var i=this._iv;if(i){var s=i;this._iv=o}else s=this._prevBlock;for(var n=0;n>>2];e.sigBytes-=t}},r.BlockCipher=h.extend({cfg:h.cfg.extend({mode:d,padding:p}),reset:function(){h.reset.call(this);var e=this.cfg,t=e.iv,r=e.mode;if(this._xformMode==this._ENC_XFORM_MODE)var i=r.createEncryptor;else{i=r.createDecryptor;this._minBufferSize=1}this._mode&&this._mode.__creator==i?this._mode.init(this,t&&t.words):(this._mode=i.call(r,this,t&&t.words),this._mode.__creator=i)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else{t=this._process(!0);e.unpad(t)}return t},blockSize:4}),_=r.CipherParams=i.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),g=(t.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext,r=e.salt;if(r)var i=f.create([1398893684,1701076831]).concat(r).concat(t);else i=t;return i.toString(a)},parse:function(e){var t=a.parse(e),r=t.words;if(1398893684==r[0]&&1701076831==r[1]){var i=f.create(r.slice(2,4));r.splice(0,4),t.sigBytes-=16}return _.create({ciphertext:t,salt:i})}},m=r.SerializableCipher=i.extend({cfg:i.extend({format:g}),encrypt:function(e,t,r,i){i=this.cfg.extend(i);var s=e.createEncryptor(r,i),n=s.finalize(t),o=s.cfg;return _.create({ciphertext:n,key:r,iv:o.iv,algorithm:e,mode:o.mode,padding:o.padding,blockSize:e.blockSize,formatter:i.format})},decrypt:function(e,t,r,i){return i=this.cfg.extend(i),t=this._parse(t,i.format),e.createDecryptor(r,i).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}}),v=(t.kdf={}).OpenSSL={execute:function(e,t,r,i){i||(i=f.random(8));var s=u.create({keySize:t+r}).compute(e,i),n=f.create(s.words.slice(t),4*r);return s.sigBytes=4*t,_.create({key:s,iv:n,salt:i})}},b=r.PasswordBasedCipher=m.extend({cfg:m.cfg.extend({kdf:v}),encrypt:function(e,t,r,i){var s=(i=this.cfg.extend(i)).kdf.execute(r,e.keySize,e.ivSize);i.iv=s.iv;var n=m.encrypt.call(this,e,t,s.key,i);return n.mixIn(s),n},decrypt:function(e,t,r,i){i=this.cfg.extend(i),t=this._parse(t,i.format);var s=i.kdf.execute(r,e.keySize,e.ivSize,t.salt);return i.iv=s.iv,m.decrypt.call(this,e,t,s.key,i)}}))},"object"==typeof r?t.exports=r=s(e("./core"),e("./evpkdf")):s(i.CryptoJS)},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js","./evpkdf":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/evpkdf.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js":[function(e,t,r){var i,s;i=this,s=function(){var h,r,e,t,i,c,s,n,o,a,f,u,l=l||(h=Math,r=Object.create||function(){function r(){}return function(e){var t;return r.prototype=e,t=new r,r.prototype=null,t}}(),t=(e={}).lib={},i=t.Base={extend:function(e){var t=r(this);return e&&t.mixIn(e),t.hasOwnProperty("init")&&this.init!==t.init||(t.init=function(){t.$super.init.apply(this,arguments)}),(t.init.prototype=t).$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},c=t.WordArray=i.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||n).stringify(this)},concat:function(e){var t=this.words,r=e.words,i=this.sigBytes,s=e.sigBytes;if(this.clamp(),i%4)for(var n=0;n>>2]>>>24-n%4*8&255;t[i+n>>>2]|=o<<24-(i+n)%4*8}else for(n=0;n>>2]=r[n>>>2];return this.sigBytes+=s,this},clamp:function(){var e=this.words,t=this.sigBytes;e[t>>>2]&=4294967295<<32-t%4*8,e.length=h.ceil(t/4)},clone:function(){var e=i.clone.call(this);return e.words=this.words.slice(0),e},random:function(e){for(var t,r=[],i=function(t){t=t;var r=987654321,i=4294967295;return function(){var e=((r=36969*(65535&r)+(r>>16)&i)<<16)+(t=18e3*(65535&t)+(t>>16)&i)&i;return e/=4294967296,(e+=.5)*(.5>>2]>>>24-s%4*8&255;i.push((n>>>4).toString(16)),i.push((15&n).toString(16))}return i.join("")},parse:function(e){for(var t=e.length,r=[],i=0;i>>3]|=parseInt(e.substr(i,2),16)<<24-i%8*4;return new c.init(r,t/2)}},o=s.Latin1={stringify:function(e){for(var t=e.words,r=e.sigBytes,i=[],s=0;s>>2]>>>24-s%4*8&255;i.push(String.fromCharCode(n))}return i.join("")},parse:function(e){for(var t=e.length,r=[],i=0;i>>2]|=(255&e.charCodeAt(i))<<24-i%4*8;return new c.init(r,t)}},a=s.Utf8={stringify:function(e){try{return decodeURIComponent(escape(o.stringify(e)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(e){return o.parse(unescape(encodeURIComponent(e)))}},f=t.BufferedBlockAlgorithm=i.extend({reset:function(){this._data=new c.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=a.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(e){var t=this._data,r=t.words,i=t.sigBytes,s=this.blockSize,n=i/(4*s),o=(n=e?h.ceil(n):h.max((0|n)-this._minBufferSize,0))*s,a=h.min(4*o,i);if(o){for(var f=0;f>>2]>>>24-n%4*8&255)<<16|(t[n+1>>>2]>>>24-(n+1)%4*8&255)<<8|t[n+2>>>2]>>>24-(n+2)%4*8&255,a=0;a<4&&n+.75*a>>6*(3-a)&63));var f=i.charAt(64);if(f)for(;s.length%4;)s.push(f);return s.join("")},parse:function(e){var t=e.length,r=this._map,i=this._reverseMap;if(!i){i=this._reverseMap=[];for(var s=0;s>>6-n%4*2;i[s>>>2]|=(o|a)<<24-s%4*8,s++}return f.create(i,s)}(e,t,i)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},e.enc.Base64},"object"==typeof r?t.exports=r=s(e("./core")):s(i.CryptoJS)},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/enc-hex.js":[function(e,t,r){var i,s;i=this,s=function(e){return e.enc.Hex},"object"==typeof r?t.exports=r=s(e("./core")):s(i.CryptoJS)},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/evpkdf.js":[function(e,t,r){var i,s;i=this,s=function(e){var t,r,i,h,s,n,o;return r=(t=e).lib,i=r.Base,h=r.WordArray,s=t.algo,n=s.MD5,o=s.EvpKDF=i.extend({cfg:i.extend({keySize:4,hasher:n,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var r=this.cfg,i=r.hasher.create(),s=h.create(),n=s.words,o=r.keySize,a=r.iterations;n.lengthi&&(t=e.finalize(t)),t.clamp();for(var s=this._oKey=t.clone(),n=this._iKey=t.clone(),o=s.words,a=n.words,f=0;f>>24)|4278255360&(s<<24|s>>>8)}var n=this._hash.words,o=e[t+0],a=e[t+1],f=e[t+2],u=e[t+3],h=e[t+4],c=e[t+5],l=e[t+6],d=e[t+7],p=e[t+8],_=e[t+9],g=e[t+10],m=e[t+11],v=e[t+12],b=e[t+13],y=e[t+14],w=e[t+15],j=n[0],B=n[1],E=n[2],x=n[3];B=I(B=I(B=I(B=I(B=k(B=k(B=k(B=k(B=S(B=S(B=S(B=S(B=T(B=T(B=T(B=T(B,E=T(E,x=T(x,j=T(j,B,E,x,o,7,D[0]),B,E,a,12,D[1]),j,B,f,17,D[2]),x,j,u,22,D[3]),E=T(E,x=T(x,j=T(j,B,E,x,h,7,D[4]),B,E,c,12,D[5]),j,B,l,17,D[6]),x,j,d,22,D[7]),E=T(E,x=T(x,j=T(j,B,E,x,p,7,D[8]),B,E,_,12,D[9]),j,B,g,17,D[10]),x,j,m,22,D[11]),E=T(E,x=T(x,j=T(j,B,E,x,v,7,D[12]),B,E,b,12,D[13]),j,B,y,17,D[14]),x,j,w,22,D[15]),E=S(E,x=S(x,j=S(j,B,E,x,a,5,D[16]),B,E,l,9,D[17]),j,B,m,14,D[18]),x,j,o,20,D[19]),E=S(E,x=S(x,j=S(j,B,E,x,c,5,D[20]),B,E,g,9,D[21]),j,B,w,14,D[22]),x,j,h,20,D[23]),E=S(E,x=S(x,j=S(j,B,E,x,_,5,D[24]),B,E,y,9,D[25]),j,B,u,14,D[26]),x,j,p,20,D[27]),E=S(E,x=S(x,j=S(j,B,E,x,b,5,D[28]),B,E,f,9,D[29]),j,B,d,14,D[30]),x,j,v,20,D[31]),E=k(E,x=k(x,j=k(j,B,E,x,c,4,D[32]),B,E,p,11,D[33]),j,B,m,16,D[34]),x,j,y,23,D[35]),E=k(E,x=k(x,j=k(j,B,E,x,a,4,D[36]),B,E,h,11,D[37]),j,B,d,16,D[38]),x,j,g,23,D[39]),E=k(E,x=k(x,j=k(j,B,E,x,b,4,D[40]),B,E,o,11,D[41]),j,B,u,16,D[42]),x,j,l,23,D[43]),E=k(E,x=k(x,j=k(j,B,E,x,_,4,D[44]),B,E,v,11,D[45]),j,B,w,16,D[46]),x,j,f,23,D[47]),E=I(E,x=I(x,j=I(j,B,E,x,o,6,D[48]),B,E,d,10,D[49]),j,B,y,15,D[50]),x,j,c,21,D[51]),E=I(E,x=I(x,j=I(j,B,E,x,v,6,D[52]),B,E,u,10,D[53]),j,B,g,15,D[54]),x,j,a,21,D[55]),E=I(E,x=I(x,j=I(j,B,E,x,p,6,D[56]),B,E,w,10,D[57]),j,B,l,15,D[58]),x,j,b,21,D[59]),E=I(E,x=I(x,j=I(j,B,E,x,h,6,D[60]),B,E,m,10,D[61]),j,B,f,15,D[62]),x,j,_,21,D[63]),n[0]=n[0]+j|0,n[1]=n[1]+B|0,n[2]=n[2]+E|0,n[3]=n[3]+x|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,i=8*e.sigBytes;t[i>>>5]|=128<<24-i%32;var s=h.floor(r/4294967296),n=r;t[15+(i+64>>>9<<4)]=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8),t[14+(i+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),e.sigBytes=4*(t.length+1),this._process();for(var o=this._hash,a=o.words,f=0;f<4;f++){var u=a[f];a[f]=16711935&(u<<8|u>>>24)|4278255360&(u<<24|u>>>8)}return o},clone:function(){var e=i.clone.call(this);return e._hash=this._hash.clone(),e}});function T(e,t,r,i,s,n,o){var a=e+(t&r|~t&i)+s+o;return(a<>>32-n)+t}function S(e,t,r,i,s,n,o){var a=e+(t&i|r&~i)+s+o;return(a<>>32-n)+t}function k(e,t,r,i,s,n,o){var a=e+(t^r^i)+s+o;return(a<>>32-n)+t}function I(e,t,r,i,s,n,o){var a=e+(r^(t|~i))+s+o;return(a<>>32-n)+t}e.MD5=i._createHelper(n),e.HmacMD5=i._createHmacHelper(n)}(Math),o.MD5},"object"==typeof r?t.exports=r=s(e("./core")):s(i.CryptoJS)},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/sha1.js":[function(e,t,r){var i,s;i=this,s=function(e){var t,r,i,s,n,c,o;return r=(t=e).lib,i=r.WordArray,s=r.Hasher,n=t.algo,c=[],o=n.SHA1=s.extend({_doReset:function(){this._hash=new i.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(e,t){for(var r=this._hash.words,i=r[0],s=r[1],n=r[2],o=r[3],a=r[4],f=0;f<80;f++){if(f<16)c[f]=0|e[t+f];else{var u=c[f-3]^c[f-8]^c[f-14]^c[f-16];c[f]=u<<1|u>>>31}var h=(i<<5|i>>>27)+a+c[f];h+=f<20?1518500249+(s&n|~s&o):f<40?1859775393+(s^n^o):f<60?(s&n|s&o|n&o)-1894007588:(s^n^o)-899497514,a=o,o=n,n=s<<30|s>>>2,s=i,i=h}r[0]=r[0]+i|0,r[1]=r[1]+s|0,r[2]=r[2]+n|0,r[3]=r[3]+o|0,r[4]=r[4]+a|0},_doFinalize:function(){var e=this._data,t=e.words,r=8*this._nDataBytes,i=8*e.sigBytes;return t[i>>>5]|=128<<24-i%32,t[14+(i+64>>>9<<4)]=Math.floor(r/4294967296),t[15+(i+64>>>9<<4)]=r,e.sigBytes=4*t.length,this._process(),this._hash},clone:function(){var e=s.clone.call(this);return e._hash=this._hash.clone(),e}}),t.SHA1=s._createHelper(o),t.HmacSHA1=s._createHmacHelper(o),e.SHA1},"object"==typeof r?t.exports=r=s(e("./core")):s(i.CryptoJS)},{"./core":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/crypto-js/core.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/deep-equal/index.js":[function(e,t,r){var a=Array.prototype.slice,f=e("./lib/keys.js"),u=e("./lib/is_arguments.js"),h=t.exports=function(e,t,r){return r||(r={}),e===t||(e instanceof Date&&t instanceof Date?e.getTime()===t.getTime():!e||!t||"object"!=typeof e&&"object"!=typeof t?r.strict?e===t:e==t:function(e,t,r){var i,s;if(c(e)||c(t))return!1;if(e.prototype!==t.prototype)return!1;if(u(e))return!!u(t)&&(e=a.call(e),t=a.call(t),h(e,t,r));if(l(e)){if(!l(t))return!1;if(e.length!==t.length)return!1;for(i=0;is){o.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+o.length+' "'+String(t)+'" listeners added. Use emitter.setMaxListeners() to increase limit.');a.name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=o.length,"object"==typeof console&&console.warn&&console.warn("%s: %s",a.name,a.message)}}else o=n[t]=r,++e._eventsCount;return e}function l(){if(!this.fired)switch(this.target.removeListener(this.type,this.wrapFn),this.fired=!0,arguments.length){case 0:return this.listener.call(this.target);case 1:return this.listener.call(this.target,arguments[0]);case 2:return this.listener.call(this.target,arguments[0],arguments[1]);case 3:return this.listener.call(this.target,arguments[0],arguments[1],arguments[2]);default:for(var e=new Array(arguments.length),t=0;t=this._blockSize;){for(var s=this._blockOffset;s>1,h=-7,c=r?s-1:0,l=r?-1:1,d=e[t+c];for(c+=l,n=d&(1<<-h)-1,d>>=-h,h+=a;0>=-h,h+=i;0>1,l=23===s?Math.pow(2,-24)-Math.pow(2,-77):0,d=i?0:n-1,p=i?1:-1,_=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=h):(o=Math.floor(Math.log(t)/Math.LN2),t*(f=Math.pow(2,-o))<1&&(o--,f*=2),2<=(t+=1<=o+c?l/f:l*Math.pow(2,1-c))*f&&(o++,f/=2),h<=o+c?(a=0,o=h):1<=o+c?(a=(t*f-1)*Math.pow(2,s),o+=c):(a=t*Math.pow(2,c-1)*Math.pow(2,s),o=0));8<=s;e[r+d]=255&a,d+=p,a/=256,s-=8);for(o=o<>>=0)&&e<256)&&(i=o[e])?i:(r=_(e,(0|e)<0?-1:0,!0),s&&(o[e]=r),r):(s=-128<=(e|=0)&&e<128)&&(i=n[e])?i:(r=_(e,e<0?-1:0,!1),s&&(n[e]=r),r)}function p(e,t){if(isNaN(e)||!isFinite(e))return t?f:v;if(t){if(e<0)return f;if(s<=e)return w}else{if(e<=-a)return j;if(a<=e+1)return y}return e<0?p(-e,t).neg():_(e%r|0,e/r|0,t)}function _(e,t,r){return new i(e,t,r)}i.fromInt=e,i.fromNumber=p,i.fromBits=_;var h=Math.pow;function c(e,t,r){if(0===e.length)throw Error("empty string");if("NaN"===e||"Infinity"===e||"+Infinity"===e||"-Infinity"===e)return v;if("number"==typeof t?(r=t,t=!1):t=!!t,(r=r||10)<2||36>>0:this.low},t.toNumber=function(){return this.unsigned?(this.high>>>0)*r+(this.low>>>0):this.high*r+(this.low>>>0)},t.toString=function(e){if((e=e||10)<2||36>>0).toString(e);if((n=a).isZero())return f+o;for(;f.length<6;)f="0"+f;o=""+f+o}},t.getHighBits=function(){return this.high},t.getHighBitsUnsigned=function(){return this.high>>>0},t.getLowBits=function(){return this.low},t.getLowBitsUnsigned=function(){return this.low>>>0},t.getNumBitsAbs=function(){if(this.isNegative())return this.eq(j)?64:this.neg().getNumBitsAbs();for(var e=0!=this.high?this.high:this.low,t=31;0>>31!=1||e.high>>>31!=1)&&(this.high===e.high&&this.low===e.low)},t.eq=t.equals,t.notEquals=function(e){return!this.eq(e)},t.neq=t.notEquals,t.lessThan=function(e){return this.comp(e)<0},t.lt=t.lessThan,t.lessThanOrEqual=function(e){return this.comp(e)<=0},t.lte=t.lessThanOrEqual,t.greaterThan=function(e){return 0>>0>this.high>>>0||e.high===this.high&&e.low>>>0>this.low>>>0?-1:1:this.sub(e).isNegative()?-1:1},t.comp=t.compare,t.negate=function(){return!this.unsigned&&this.eq(j)?j:this.not().add(u)},t.neg=t.negate,t.add=function(e){d(e)||(e=g(e));var t=this.high>>>16,r=65535&this.high,i=this.low>>>16,s=65535&this.low,n=e.high>>>16,o=65535&e.high,a=e.low>>>16,f=0,u=0,h=0,c=0;return h+=(c+=s+(65535&e.low))>>>16,u+=(h+=i+a)>>>16,f+=(u+=r+o)>>>16,f+=t+n,_((h&=65535)<<16|(c&=65535),(f&=65535)<<16|(u&=65535),this.unsigned)},t.subtract=function(e){return d(e)||(e=g(e)),this.add(e.neg())},t.sub=t.subtract,t.multiply=function(e){if(this.isZero())return v;if(d(e)||(e=g(e)),e.isZero())return v;if(this.eq(j))return e.isOdd()?j:v;if(e.eq(j))return this.isOdd()?j:v;if(this.isNegative())return e.isNegative()?this.neg().mul(e.neg()):this.neg().mul(e).neg();if(e.isNegative())return this.mul(e.neg()).neg();if(this.lt(m)&&e.lt(m))return p(this.toNumber()*e.toNumber(),this.unsigned);var t=this.high>>>16,r=65535&this.high,i=this.low>>>16,s=65535&this.low,n=e.high>>>16,o=65535&e.high,a=e.low>>>16,f=65535&e.low,u=0,h=0,c=0,l=0;return c+=(l+=s*f)>>>16,h+=(c+=i*f)>>>16,c&=65535,h+=(c+=s*a)>>>16,u+=(h+=r*f)>>>16,h&=65535,u+=(h+=i*a)>>>16,h&=65535,u+=(h+=s*o)>>>16,u+=t*f+r*a+i*o+s*n,_((c&=65535)<<16|(l&=65535),(u&=65535)<<16|(h&=65535),this.unsigned)},t.mul=t.multiply,t.divide=function(e){if(d(e)||(e=g(e)),e.isZero())throw Error("division by zero");if(this.isZero())return this.unsigned?f:v;var t,r,i;if(this.unsigned){if(e.unsigned||(e=e.toUnsigned()),e.gt(this))return f;if(e.gt(this.shru(1)))return l;i=f}else{if(this.eq(j))return e.eq(u)||e.eq(b)?j:e.eq(j)?u:(t=this.shr(1).div(e).shl(1)).eq(v)?e.isNegative()?u:b:(r=this.sub(e.mul(t)),i=t.add(r.div(e)));else if(e.eq(j))return this.unsigned?f:v;if(this.isNegative())return e.isNegative()?this.neg().div(e.neg()):this.neg().div(e).neg();if(e.isNegative())return this.div(e.neg()).neg();i=v}for(r=this;r.gte(e);){t=Math.max(1,Math.floor(r.toNumber()/e.toNumber()));for(var s=Math.ceil(Math.log(t)/Math.LN2),n=s<=48?1:h(2,s-48),o=p(t),a=o.mul(e);a.isNegative()||a.gt(r);)a=(o=p(t-=n,this.unsigned)).mul(e);o.isZero()&&(o=u),i=i.add(o),r=r.sub(a)}return i},t.div=t.divide,t.modulo=function(e){return d(e)||(e=g(e)),this.sub(this.div(e).mul(e))},t.mod=t.modulo,t.not=function(){return _(~this.low,~this.high,this.unsigned)},t.and=function(e){return d(e)||(e=g(e)),_(this.low&e.low,this.high&e.high,this.unsigned)},t.or=function(e){return d(e)||(e=g(e)),_(this.low|e.low,this.high|e.high,this.unsigned)},t.xor=function(e){return d(e)||(e=g(e)),_(this.low^e.low,this.high^e.high,this.unsigned)},t.shiftLeft=function(e){return d(e)&&(e=e.toInt()),0==(e&=63)?this:e<32?_(this.low<>>32-e,this.unsigned):_(0,this.low<>>e|this.high<<32-e,this.high>>e,this.unsigned):_(this.high>>e-32,0<=this.high?0:-1,this.unsigned)},t.shr=t.shiftRight,t.shiftRightUnsigned=function(e){if(d(e)&&(e=e.toInt()),0===(e&=63))return this;var t=this.high;return e<32?_(this.low>>>e|t<<32-e,t>>>e,this.unsigned):_(32===e?t:t>>>e-32,0,this.unsigned)},t.shru=t.shiftRightUnsigned,t.toSigned=function(){return this.unsigned?_(this.low,this.high,!1):this},t.toUnsigned=function(){return this.unsigned?this:_(this.low,this.high,!0)},t.toBytes=function(e){return e?this.toBytesLE():this.toBytesBE()},t.toBytesLE=function(){var e=this.high,t=this.low;return[255&t,t>>>8&255,t>>>16&255,t>>>24&255,255&e,e>>>8&255,e>>>16&255,e>>>24&255]},t.toBytesBE=function(){var e=this.high,t=this.low;return[e>>>24&255,e>>>16&255,e>>>8&255,255&e,t>>>24&255,t>>>16&255,t>>>8&255,255&t]},i},"function"==typeof e&&"object"==typeof t&&t&&t.exports?t.exports=s():(i.dcodeIO=i.dcodeIO||{}).Long=s()},{}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/md5.js/index.js":[function(s,n,e){(function(t){"use strict";var e=s("inherits"),r=s("hash-base"),o=new Array(16);function i(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878}function a(e,t){return e<>>32-t}function f(e,t,r,i,s,n,o){return a(e+(t&r|~t&i)+s+n|0,o)+t|0}function u(e,t,r,i,s,n,o){return a(e+(t&i|r&~i)+s+n|0,o)+t|0}function h(e,t,r,i,s,n,o){return a(e+(t^r^i)+s+n|0,o)+t|0}function c(e,t,r,i,s,n,o){return a(e+(r^(t|~i))+s+n|0,o)+t|0}e(i,r),i.prototype._update=function(){for(var e=o,t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var r=this._a,i=this._b,s=this._c,n=this._d;i=c(i=c(i=c(i=c(i=h(i=h(i=h(i=h(i=u(i=u(i=u(i=u(i=f(i=f(i=f(i=f(i,s=f(s,n=f(n,r=f(r,i,s,n,e[0],3614090360,7),i,s,e[1],3905402710,12),r,i,e[2],606105819,17),n,r,e[3],3250441966,22),s=f(s,n=f(n,r=f(r,i,s,n,e[4],4118548399,7),i,s,e[5],1200080426,12),r,i,e[6],2821735955,17),n,r,e[7],4249261313,22),s=f(s,n=f(n,r=f(r,i,s,n,e[8],1770035416,7),i,s,e[9],2336552879,12),r,i,e[10],4294925233,17),n,r,e[11],2304563134,22),s=f(s,n=f(n,r=f(r,i,s,n,e[12],1804603682,7),i,s,e[13],4254626195,12),r,i,e[14],2792965006,17),n,r,e[15],1236535329,22),s=u(s,n=u(n,r=u(r,i,s,n,e[1],4129170786,5),i,s,e[6],3225465664,9),r,i,e[11],643717713,14),n,r,e[0],3921069994,20),s=u(s,n=u(n,r=u(r,i,s,n,e[5],3593408605,5),i,s,e[10],38016083,9),r,i,e[15],3634488961,14),n,r,e[4],3889429448,20),s=u(s,n=u(n,r=u(r,i,s,n,e[9],568446438,5),i,s,e[14],3275163606,9),r,i,e[3],4107603335,14),n,r,e[8],1163531501,20),s=u(s,n=u(n,r=u(r,i,s,n,e[13],2850285829,5),i,s,e[2],4243563512,9),r,i,e[7],1735328473,14),n,r,e[12],2368359562,20),s=h(s,n=h(n,r=h(r,i,s,n,e[5],4294588738,4),i,s,e[8],2272392833,11),r,i,e[11],1839030562,16),n,r,e[14],4259657740,23),s=h(s,n=h(n,r=h(r,i,s,n,e[1],2763975236,4),i,s,e[4],1272893353,11),r,i,e[7],4139469664,16),n,r,e[10],3200236656,23),s=h(s,n=h(n,r=h(r,i,s,n,e[13],681279174,4),i,s,e[0],3936430074,11),r,i,e[3],3572445317,16),n,r,e[6],76029189,23),s=h(s,n=h(n,r=h(r,i,s,n,e[9],3654602809,4),i,s,e[12],3873151461,11),r,i,e[15],530742520,16),n,r,e[2],3299628645,23),s=c(s,n=c(n,r=c(r,i,s,n,e[0],4096336452,6),i,s,e[7],1126891415,10),r,i,e[14],2878612391,15),n,r,e[5],4237533241,21),s=c(s,n=c(n,r=c(r,i,s,n,e[12],1700485571,6),i,s,e[3],2399980690,10),r,i,e[10],4293915773,15),n,r,e[1],2240044497,21),s=c(s,n=c(n,r=c(r,i,s,n,e[8],1873313359,6),i,s,e[15],4264355552,10),r,i,e[6],2734768916,15),n,r,e[13],1309151649,21),s=c(s,n=c(n,r=c(r,i,s,n,e[4],4149444226,6),i,s,e[11],3174756917,10),r,i,e[2],718787259,15),n,r,e[9],3951481745,21),this._a=this._a+r|0,this._b=this._b+i|0,this._c=this._c+s|0,this._d=this._d+n|0},i.prototype._digest=function(){this._block[this._blockOffset++]=128,56=this._blockSize;){for(var s=this._blockOffset;st.highWaterMark&&(t.highWaterMark=(c<=(r=e)?r=c:(r--,r|=r>>>1,r|=r>>>2,r|=r>>>4,r|=r>>>8,r|=r>>>16,r++),r)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0));var r}function p(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(w("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?v(_,e):_(e))}function _(e){w("emit readable"),e.emit("readable"),E(e)}function g(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=function(e,t,r){var i;en.length?n.length:e;if(o===n.length?s+=n:s+=n.slice(0,e),0===(e-=o)){o===n.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r).data=n.slice(o);break}++i}return t.length-=i,s}(e,t):function(e,t){var r=a.allocUnsafe(e),i=t.head,s=1;i.data.copy(r),e-=i.data.length;for(;i=i.next;){var n=i.data,o=e>n.length?n.length:e;if(n.copy(r,r.length-e,0,o),0===(e-=o)){o===n.length?(++s,i.next?t.head=i.next:t.head=t.tail=null):(t.head=i).data=n.slice(o);break}++s}return t.length-=s,r}(e,t);return i}(e,t.buffer,t.decoder),r);var r}function D(e){var t=e._readableState;if(0=t.highWaterMark||t.ended))return w("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?D(this):p(this),null;if(0===(e=d(e,t))&&t.ended)return 0===t.length&&D(this),null;var i,s=t.needReadable;return w("need readable",s),(0===t.length||t.length-e>>0),r=this.head,i=0;r;)r.data.copy(t,i),i+=r.data.length,r=r.next;return t}},{buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js","buffer-shims":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer-shims/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/internal/streams/stream-browser.js":[function(e,t,r){t.exports=e("events").EventEmitter},{events:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/events/events.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/passthrough.js":[function(e,t,r){t.exports=e("./readable").PassThrough},{"./readable":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js":[function(e,t,r){(((r=t.exports=e("./lib/_stream_readable.js")).Stream=r).Readable=r).Writable=e("./lib/_stream_writable.js"),r.Duplex=e("./lib/_stream_duplex.js"),r.Transform=e("./lib/_stream_transform.js"),r.PassThrough=e("./lib/_stream_passthrough.js")},{"./lib/_stream_duplex.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_duplex.js","./lib/_stream_passthrough.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_passthrough.js","./lib/_stream_readable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_readable.js","./lib/_stream_transform.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_transform.js","./lib/_stream_writable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_writable.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/transform.js":[function(e,t,r){t.exports=e("./readable").Transform},{"./readable":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/writable-browser.js":[function(e,t,r){t.exports=e("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/lib/_stream_writable.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/ripemd160/index.js":[function(s,n,e){(function(t){"use strict";var e=s("inherits"),r=s("hash-base");function i(){r.call(this,64),this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520}function d(e,t){return e<>>32-t}function p(e,t,r,i,s,n,o,a){return d(e+(t^r^i)+n+o|0,a)+s|0}function _(e,t,r,i,s,n,o,a){return d(e+(t&r|~t&i)+n+o|0,a)+s|0}function g(e,t,r,i,s,n,o,a){return d(e+((t|~r)^i)+n+o|0,a)+s|0}function m(e,t,r,i,s,n,o,a){return d(e+(t&i|r&~i)+n+o|0,a)+s|0}function v(e,t,r,i,s,n,o,a){return d(e+(t^(r|~i))+n+o|0,a)+s|0}e(i,r),i.prototype._update=function(){for(var e=new Array(16),t=0;t<16;++t)e[t]=this._block.readInt32LE(4*t);var r=this._a,i=this._b,s=this._c,n=this._d,o=this._e;o=p(o,r=p(r,i,s,n,o,e[0],0,11),i,s=d(s,10),n,e[1],0,14),i=p(i=d(i,10),s=p(s,n=p(n,o,r,i,s,e[2],0,15),o,r=d(r,10),i,e[3],0,12),n,o=d(o,10),r,e[4],0,5),n=p(n=d(n,10),o=p(o,r=p(r,i,s,n,o,e[5],0,8),i,s=d(s,10),n,e[6],0,7),r,i=d(i,10),s,e[7],0,9),r=p(r=d(r,10),i=p(i,s=p(s,n,o,r,i,e[8],0,11),n,o=d(o,10),r,e[9],0,13),s,n=d(n,10),o,e[10],0,14),s=p(s=d(s,10),n=p(n,o=p(o,r,i,s,n,e[11],0,15),r,i=d(i,10),s,e[12],0,6),o,r=d(r,10),i,e[13],0,7),o=_(o=d(o,10),r=p(r,i=p(i,s,n,o,r,e[14],0,9),s,n=d(n,10),o,e[15],0,8),i,s=d(s,10),n,e[7],1518500249,7),i=_(i=d(i,10),s=_(s,n=_(n,o,r,i,s,e[4],1518500249,6),o,r=d(r,10),i,e[13],1518500249,8),n,o=d(o,10),r,e[1],1518500249,13),n=_(n=d(n,10),o=_(o,r=_(r,i,s,n,o,e[10],1518500249,11),i,s=d(s,10),n,e[6],1518500249,9),r,i=d(i,10),s,e[15],1518500249,7),r=_(r=d(r,10),i=_(i,s=_(s,n,o,r,i,e[3],1518500249,15),n,o=d(o,10),r,e[12],1518500249,7),s,n=d(n,10),o,e[0],1518500249,12),s=_(s=d(s,10),n=_(n,o=_(o,r,i,s,n,e[9],1518500249,15),r,i=d(i,10),s,e[5],1518500249,9),o,r=d(r,10),i,e[2],1518500249,11),o=_(o=d(o,10),r=_(r,i=_(i,s,n,o,r,e[14],1518500249,7),s,n=d(n,10),o,e[11],1518500249,13),i,s=d(s,10),n,e[8],1518500249,12),i=g(i=d(i,10),s=g(s,n=g(n,o,r,i,s,e[3],1859775393,11),o,r=d(r,10),i,e[10],1859775393,13),n,o=d(o,10),r,e[14],1859775393,6),n=g(n=d(n,10),o=g(o,r=g(r,i,s,n,o,e[4],1859775393,7),i,s=d(s,10),n,e[9],1859775393,14),r,i=d(i,10),s,e[15],1859775393,9),r=g(r=d(r,10),i=g(i,s=g(s,n,o,r,i,e[8],1859775393,13),n,o=d(o,10),r,e[1],1859775393,15),s,n=d(n,10),o,e[2],1859775393,14),s=g(s=d(s,10),n=g(n,o=g(o,r,i,s,n,e[7],1859775393,8),r,i=d(i,10),s,e[0],1859775393,13),o,r=d(r,10),i,e[6],1859775393,6),o=g(o=d(o,10),r=g(r,i=g(i,s,n,o,r,e[13],1859775393,5),s,n=d(n,10),o,e[11],1859775393,12),i,s=d(s,10),n,e[5],1859775393,7),i=m(i=d(i,10),s=m(s,n=g(n,o,r,i,s,e[12],1859775393,5),o,r=d(r,10),i,e[1],2400959708,11),n,o=d(o,10),r,e[9],2400959708,12),n=m(n=d(n,10),o=m(o,r=m(r,i,s,n,o,e[11],2400959708,14),i,s=d(s,10),n,e[10],2400959708,15),r,i=d(i,10),s,e[0],2400959708,14),r=m(r=d(r,10),i=m(i,s=m(s,n,o,r,i,e[8],2400959708,15),n,o=d(o,10),r,e[12],2400959708,9),s,n=d(n,10),o,e[4],2400959708,8),s=m(s=d(s,10),n=m(n,o=m(o,r,i,s,n,e[13],2400959708,9),r,i=d(i,10),s,e[3],2400959708,14),o,r=d(r,10),i,e[7],2400959708,5),o=m(o=d(o,10),r=m(r,i=m(i,s,n,o,r,e[15],2400959708,6),s,n=d(n,10),o,e[14],2400959708,8),i,s=d(s,10),n,e[5],2400959708,6),i=v(i=d(i,10),s=m(s,n=m(n,o,r,i,s,e[6],2400959708,5),o,r=d(r,10),i,e[2],2400959708,12),n,o=d(o,10),r,e[4],2840853838,9),n=v(n=d(n,10),o=v(o,r=v(r,i,s,n,o,e[0],2840853838,15),i,s=d(s,10),n,e[5],2840853838,5),r,i=d(i,10),s,e[9],2840853838,11),r=v(r=d(r,10),i=v(i,s=v(s,n,o,r,i,e[7],2840853838,6),n,o=d(o,10),r,e[12],2840853838,8),s,n=d(n,10),o,e[2],2840853838,13),s=v(s=d(s,10),n=v(n,o=v(o,r,i,s,n,e[10],2840853838,12),r,i=d(i,10),s,e[14],2840853838,5),o,r=d(r,10),i,e[1],2840853838,12),o=v(o=d(o,10),r=v(r,i=v(i,s,n,o,r,e[3],2840853838,13),s,n=d(n,10),o,e[8],2840853838,14),i,s=d(s,10),n,e[11],2840853838,11),i=v(i=d(i,10),s=v(s,n=v(n,o,r,i,s,e[6],2840853838,8),o,r=d(r,10),i,e[15],2840853838,5),n,o=d(o,10),r,e[13],2840853838,6),n=d(n,10);var a=this._a,f=this._b,u=this._c,h=this._d,c=this._e;c=v(c,a=v(a,f,u,h,c,e[5],1352829926,8),f,u=d(u,10),h,e[14],1352829926,9),f=v(f=d(f,10),u=v(u,h=v(h,c,a,f,u,e[7],1352829926,9),c,a=d(a,10),f,e[0],1352829926,11),h,c=d(c,10),a,e[9],1352829926,13),h=v(h=d(h,10),c=v(c,a=v(a,f,u,h,c,e[2],1352829926,15),f,u=d(u,10),h,e[11],1352829926,15),a,f=d(f,10),u,e[4],1352829926,5),a=v(a=d(a,10),f=v(f,u=v(u,h,c,a,f,e[13],1352829926,7),h,c=d(c,10),a,e[6],1352829926,7),u,h=d(h,10),c,e[15],1352829926,8),u=v(u=d(u,10),h=v(h,c=v(c,a,f,u,h,e[8],1352829926,11),a,f=d(f,10),u,e[1],1352829926,14),c,a=d(a,10),f,e[10],1352829926,14),c=m(c=d(c,10),a=v(a,f=v(f,u,h,c,a,e[3],1352829926,12),u,h=d(h,10),c,e[12],1352829926,6),f,u=d(u,10),h,e[6],1548603684,9),f=m(f=d(f,10),u=m(u,h=m(h,c,a,f,u,e[11],1548603684,13),c,a=d(a,10),f,e[3],1548603684,15),h,c=d(c,10),a,e[7],1548603684,7),h=m(h=d(h,10),c=m(c,a=m(a,f,u,h,c,e[0],1548603684,12),f,u=d(u,10),h,e[13],1548603684,8),a,f=d(f,10),u,e[5],1548603684,9),a=m(a=d(a,10),f=m(f,u=m(u,h,c,a,f,e[10],1548603684,11),h,c=d(c,10),a,e[14],1548603684,7),u,h=d(h,10),c,e[15],1548603684,7),u=m(u=d(u,10),h=m(h,c=m(c,a,f,u,h,e[8],1548603684,12),a,f=d(f,10),u,e[12],1548603684,7),c,a=d(a,10),f,e[4],1548603684,6),c=m(c=d(c,10),a=m(a,f=m(f,u,h,c,a,e[9],1548603684,15),u,h=d(h,10),c,e[1],1548603684,13),f,u=d(u,10),h,e[2],1548603684,11),f=g(f=d(f,10),u=g(u,h=g(h,c,a,f,u,e[15],1836072691,9),c,a=d(a,10),f,e[5],1836072691,7),h,c=d(c,10),a,e[1],1836072691,15),h=g(h=d(h,10),c=g(c,a=g(a,f,u,h,c,e[3],1836072691,11),f,u=d(u,10),h,e[7],1836072691,8),a,f=d(f,10),u,e[14],1836072691,6),a=g(a=d(a,10),f=g(f,u=g(u,h,c,a,f,e[6],1836072691,6),h,c=d(c,10),a,e[9],1836072691,14),u,h=d(h,10),c,e[11],1836072691,12),u=g(u=d(u,10),h=g(h,c=g(c,a,f,u,h,e[8],1836072691,13),a,f=d(f,10),u,e[12],1836072691,5),c,a=d(a,10),f,e[2],1836072691,14),c=g(c=d(c,10),a=g(a,f=g(f,u,h,c,a,e[10],1836072691,13),u,h=d(h,10),c,e[0],1836072691,13),f,u=d(u,10),h,e[4],1836072691,7),f=_(f=d(f,10),u=_(u,h=g(h,c,a,f,u,e[13],1836072691,5),c,a=d(a,10),f,e[8],2053994217,15),h,c=d(c,10),a,e[6],2053994217,5),h=_(h=d(h,10),c=_(c,a=_(a,f,u,h,c,e[4],2053994217,8),f,u=d(u,10),h,e[1],2053994217,11),a,f=d(f,10),u,e[3],2053994217,14),a=_(a=d(a,10),f=_(f,u=_(u,h,c,a,f,e[11],2053994217,14),h,c=d(c,10),a,e[15],2053994217,6),u,h=d(h,10),c,e[0],2053994217,14),u=_(u=d(u,10),h=_(h,c=_(c,a,f,u,h,e[5],2053994217,6),a,f=d(f,10),u,e[12],2053994217,9),c,a=d(a,10),f,e[2],2053994217,12),c=_(c=d(c,10),a=_(a,f=_(f,u,h,c,a,e[13],2053994217,9),u,h=d(h,10),c,e[9],2053994217,12),f,u=d(u,10),h,e[7],2053994217,5),f=p(f=d(f,10),u=_(u,h=_(h,c,a,f,u,e[10],2053994217,15),c,a=d(a,10),f,e[14],2053994217,8),h,c=d(c,10),a,e[12],0,8),h=p(h=d(h,10),c=p(c,a=p(a,f,u,h,c,e[15],0,5),f,u=d(u,10),h,e[10],0,12),a,f=d(f,10),u,e[4],0,9),a=p(a=d(a,10),f=p(f,u=p(u,h,c,a,f,e[1],0,12),h,c=d(c,10),a,e[5],0,5),u,h=d(h,10),c,e[8],0,14),u=p(u=d(u,10),h=p(h,c=p(c,a,f,u,h,e[7],0,6),a,f=d(f,10),u,e[6],0,8),c,a=d(a,10),f,e[2],0,13),c=p(c=d(c,10),a=p(a,f=p(f,u,h,c,a,e[13],0,6),u,h=d(h,10),c,e[14],0,5),f,u=d(u,10),h,e[0],0,15),f=p(f=d(f,10),u=p(u,h=p(h,c,a,f,u,e[3],0,13),c,a=d(a,10),f,e[9],0,11),h,c=d(c,10),a,e[11],0,11),h=d(h,10);var l=this._b+s+h|0;this._b=this._c+n+c|0,this._c=this._d+o+a|0,this._d=this._e+r+f|0,this._e=this._a+i+u|0,this._a=l},i.prototype._digest=function(){this._block[this._blockOffset++]=128,56=8*this._finalSize&&(this._update(this._block),this._block.fill(0)),this._block.writeInt32BE(t,this._blockSize-4);var r=this._update(this._block)||this._hash();return e?r.toString(e):r},e.prototype._update=function(){throw new Error("_update must be implemented by subclass")},t.exports=e}).call(this,e("buffer").Buffer)},{buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/index.js":[function(e,t,r){(r=t.exports=function(e){e=e.toLowerCase();var t=r[e];if(!t)throw new Error(e+" is not supported (we accept pull requests)");return new t}).sha=e("./sha"),r.sha1=e("./sha1"),r.sha224=e("./sha224"),r.sha256=e("./sha256"),r.sha384=e("./sha384"),r.sha512=e("./sha512")},{"./sha":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha.js","./sha1":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha1.js","./sha224":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha224.js","./sha256":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha256.js","./sha384":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha384.js","./sha512":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha512.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha.js":[function(n,o,e){(function(t){var e=n("inherits"),r=n("./hash"),m=[1518500249,1859775393,-1894007588,-899497514],i=new Array(80);function s(){this.init(),this._w=i,r.call(this,64,56)}e(s,r),s.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},s.prototype._update=function(e){for(var t,r,i,s,n,o,a=this._w,f=0|this._a,u=0|this._b,h=0|this._c,c=0|this._d,l=0|this._e,d=0;d<16;++d)a[d]=e.readInt32BE(4*d);for(;d<80;++d)a[d]=a[d-3]^a[d-8]^a[d-14]^a[d-16];for(var p=0;p<80;++p){var _=~~(p/20),g=0|((o=f)<<5|o>>>27)+(i=u,s=h,n=c,0===(r=_)?i&s|~i&n:2===r?i&s|i&n|s&n:i^s^n)+l+a[p]+m[_];l=c,c=h,h=(t=u)<<30|t>>>2,u=f,f=g}this._a=f+this._a|0,this._b=u+this._b|0,this._c=h+this._c|0,this._d=c+this._d|0,this._e=l+this._e|0},s.prototype._hash=function(){var e=new t(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},o.exports=s}).call(this,n("buffer").Buffer)},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js",buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha1.js":[function(n,o,e){(function(t){var e=n("inherits"),r=n("./hash"),v=[1518500249,1859775393,-1894007588,-899497514],i=new Array(80);function s(){this.init(),this._w=i,r.call(this,64,56)}e(s,r),s.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},s.prototype._update=function(e){for(var t,r,i,s,n,o,a,f=this._w,u=0|this._a,h=0|this._b,c=0|this._c,l=0|this._d,d=0|this._e,p=0;p<16;++p)f[p]=e.readInt32BE(4*p);for(;p<80;++p)f[p]=(t=f[p-3]^f[p-8]^f[p-14]^f[p-16])<<1|t>>>31;for(var _=0;_<80;++_){var g=~~(_/20),m=0|((a=u)<<5|a>>>27)+(s=h,n=c,o=l,0===(i=g)?s&n|~s&o:2===i?s&n|s&o|n&o:s^n^o)+d+f[_]+v[g];d=l,l=c,c=(r=h)<<30|r>>>2,h=u,u=m}this._a=u+this._a|0,this._b=h+this._b|0,this._c=c+this._c|0,this._d=l+this._d|0,this._e=d+this._e|0},s.prototype._hash=function(){var e=new t(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},o.exports=s}).call(this,n("buffer").Buffer)},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js",buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha224.js":[function(o,a,e){(function(t){var e=o("inherits"),r=o("./sha256"),i=o("./hash"),s=new Array(64);function n(){this.init(),this._w=s,i.call(this,64,56)}e(n,r),n.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},n.prototype._hash=function(){var e=new t(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},a.exports=n}).call(this,o("buffer").Buffer)},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","./sha256":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha256.js",buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha256.js":[function(n,o,e){(function(t){var e=n("inherits"),r=n("./hash"),w=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],i=new Array(64);function s(){this.init(),this._w=i,r.call(this,64,56)}e(s,r),s.prototype.init=function(){return this._a=1779033703,this._b=3144134277,this._c=1013904242,this._d=2773480762,this._e=1359893119,this._f=2600822924,this._g=528734635,this._h=1541459225,this},s.prototype._update=function(e){for(var t,r,i,s,n,o,a,f=this._w,u=0|this._a,h=0|this._b,c=0|this._c,l=0|this._d,d=0|this._e,p=0|this._f,_=0|this._g,g=0|this._h,m=0;m<16;++m)f[m]=e.readInt32BE(4*m);for(;m<64;++m)f[m]=0|(((r=f[m-2])>>>17|r<<15)^(r>>>19|r<<13)^r>>>10)+f[m-7]+(((t=f[m-15])>>>7|t<<25)^(t>>>18|t<<14)^t>>>3)+f[m-16];for(var v=0;v<64;++v){var b=g+(((a=d)>>>6|a<<26)^(a>>>11|a<<21)^(a>>>25|a<<7))+((o=_)^d&(p^o))+w[v]+f[v]|0,y=0|(((n=u)>>>2|n<<30)^(n>>>13|n<<19)^(n>>>22|n<<10))+((i=u)&(s=h)|c&(i|s));g=_,_=p,p=d,d=l+b|0,l=c,c=h,h=u,u=b+y|0}this._a=u+this._a|0,this._b=h+this._b|0,this._c=c+this._c|0,this._d=l+this._d|0,this._e=d+this._e|0,this._f=p+this._f|0,this._g=_+this._g|0,this._h=g+this._h|0},s.prototype._hash=function(){var e=new t(32);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e.writeInt32BE(this._h,28),e},o.exports=s}).call(this,n("buffer").Buffer)},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js",buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha384.js":[function(o,a,e){(function(t){var e=o("inherits"),r=o("./sha512"),i=o("./hash"),s=new Array(160);function n(){this.init(),this._w=s,i.call(this,128,112)}e(n,r),n.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},n.prototype._hash=function(){var i=new t(48);function e(e,t,r){i.writeInt32BE(e,r),i.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),i},a.exports=n}).call(this,o("buffer").Buffer)},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js","./sha512":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha512.js",buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/sha512.js":[function(n,o,e){(function(t){var e=n("inherits"),r=n("./hash"),ee=[1116352408,3609767458,1899447441,602891725,3049323471,3964484399,3921009573,2173295548,961987163,4081628472,1508970993,3053834265,2453635748,2937671579,2870763221,3664609560,3624381080,2734883394,310598401,1164996542,607225278,1323610764,1426881987,3590304994,1925078388,4068182383,2162078206,991336113,2614888103,633803317,3248222580,3479774868,3835390401,2666613458,4022224774,944711139,264347078,2341262773,604807628,2007800933,770255983,1495990901,1249150122,1856431235,1555081692,3175218132,1996064986,2198950837,2554220882,3999719339,2821834349,766784016,2952996808,2566594879,3210313671,3203337956,3336571891,1034457026,3584528711,2466948901,113926993,3758326383,338241895,168717936,666307205,1188179964,773529912,1546045734,1294757372,1522805485,1396182291,2643833823,1695183700,2343527390,1986661051,1014477480,2177026350,1206759142,2456956037,344077627,2730485921,1290863460,2820302411,3158454273,3259730800,3505952657,3345764771,106217008,3516065817,3606008344,3600352804,1432725776,4094571909,1467031594,275423344,851169720,430227734,3100823752,506948616,1363258195,659060556,3750685593,883997877,3785050280,958139571,3318307427,1322822218,3812723403,1537002063,2003034995,1747873779,3602036899,1955562222,1575990012,2024104815,1125592928,2227730452,2716904306,2361852424,442776044,2428436474,593698344,2756734187,3733110249,3204031479,2999351573,3329325298,3815920427,3391569614,3928383900,3515267271,566280711,3940187606,3454069534,4118630271,4000239992,116418474,1914138554,174292421,2731055270,289380356,3203993006,460393269,320620315,685471733,587496836,852142971,1086792851,1017036298,365543100,1126000580,2618297676,1288033470,3409855158,1501505948,4234509866,1607167915,987167468,1816402316,1246189591],i=new Array(160);function s(){this.init(),this._w=i,r.call(this,128,112)}function te(e,t,r){return r^e&(t^r)}function re(e,t,r){return e&t|r&(e|t)}function ie(e,t){return(e>>>28|t<<4)^(t>>>2|e<<30)^(t>>>7|e<<25)}function se(e,t){return(e>>>14|t<<18)^(e>>>18|t<<14)^(t>>>9|e<<23)}function ne(e,t){return e>>>0>>0?1:0}e(s,r),s.prototype.init=function(){return this._ah=1779033703,this._bh=3144134277,this._ch=1013904242,this._dh=2773480762,this._eh=1359893119,this._fh=2600822924,this._gh=528734635,this._hh=1541459225,this._al=4089235720,this._bl=2227873595,this._cl=4271175723,this._dl=1595750129,this._el=2917565137,this._fl=725511199,this._gl=4215389547,this._hl=327033209,this},s.prototype._update=function(e){for(var t,r,i,s,n,o,a,f,u=this._w,h=0|this._ah,c=0|this._bh,l=0|this._ch,d=0|this._dh,p=0|this._eh,_=0|this._fh,g=0|this._gh,m=0|this._hh,v=0|this._al,b=0|this._bl,y=0|this._cl,w=0|this._dl,j=0|this._el,B=0|this._fl,E=0|this._gl,x=0|this._hl,D=0;D<32;D+=2)u[D]=e.readInt32BE(4*D),u[D+1]=e.readInt32BE(4*D+4);for(;D<160;D+=2){var T=u[D-30],S=u[D-30+1],k=((a=T)>>>1|(f=S)<<31)^(a>>>8|f<<24)^a>>>7,I=((n=S)>>>1|(o=T)<<31)^(n>>>8|o<<24)^(n>>>7|o<<25);T=u[D-4],S=u[D-4+1];var A=((i=T)>>>19|(s=S)<<13)^(s>>>29|i<<3)^i>>>6,L=((t=S)>>>19|(r=T)<<13)^(r>>>29|t<<3)^(t>>>6|r<<26),C=u[D-14],O=u[D-14+1],U=u[D-32],M=u[D-32+1],q=I+O|0,R=k+C+ne(q,I)|0;R=(R=R+A+ne(q=q+L|0,L)|0)+U+ne(q=q+M|0,M)|0,u[D]=R,u[D+1]=q}for(var z=0;z<160;z+=2){R=u[z],q=u[z+1];var N=re(h,c,l),P=re(v,b,y),F=ie(h,v),K=ie(v,h),H=se(p,j),V=se(j,p),W=ee[z],Z=ee[z+1],G=te(p,_,g),J=te(j,B,E),Y=x+V|0,X=m+H+ne(Y,x)|0;X=(X=(X=X+G+ne(Y=Y+J|0,J)|0)+W+ne(Y=Y+Z|0,Z)|0)+R+ne(Y=Y+q|0,q)|0;var Q=K+P|0,$=F+N+ne(Q,K)|0;m=g,x=E,g=_,E=B,_=p,B=j,p=d+X+ne(j=w+Y|0,w)|0,d=l,w=y,l=c,y=b,c=h,b=v,h=X+$+ne(v=Y+Q|0,Y)|0}this._al=this._al+v|0,this._bl=this._bl+b|0,this._cl=this._cl+y|0,this._dl=this._dl+w|0,this._el=this._el+j|0,this._fl=this._fl+B|0,this._gl=this._gl+E|0,this._hl=this._hl+x|0,this._ah=this._ah+h+ne(this._al,v)|0,this._bh=this._bh+c+ne(this._bl,b)|0,this._ch=this._ch+l+ne(this._cl,y)|0,this._dh=this._dh+d+ne(this._dl,w)|0,this._eh=this._eh+p+ne(this._el,j)|0,this._fh=this._fh+_+ne(this._fl,B)|0,this._gh=this._gh+g+ne(this._gl,E)|0,this._hh=this._hh+m+ne(this._hl,x)|0},s.prototype._hash=function(){var i=new t(64);function e(e,t,r){i.writeInt32BE(e,r),i.writeInt32BE(t,r+4)}return e(this._ah,this._al,0),e(this._bh,this._bl,8),e(this._ch,this._cl,16),e(this._dh,this._dl,24),e(this._eh,this._el,32),e(this._fh,this._fl,40),e(this._gh,this._gl,48),e(this._hh,this._hl,56),i},o.exports=s}).call(this,n("buffer").Buffer)},{"./hash":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/sha.js/hash.js",buffer:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/buffer/index.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/stream-browserify/index.js":[function(e,t,r){t.exports=i;var h=e("events").EventEmitter;function i(){h.call(this)}e("inherits")(i,h),i.Readable=e("readable-stream/readable.js"),i.Writable=e("readable-stream/writable.js"),i.Duplex=e("readable-stream/duplex.js"),i.Transform=e("readable-stream/transform.js"),i.PassThrough=e("readable-stream/passthrough.js"),(i.Stream=i).prototype.pipe=function(t,e){var r=this;function i(e){t.writable&&!1===t.write(e)&&r.pause&&r.pause()}function s(){r.readable&&r.resume&&r.resume()}r.on("data",i),t.on("drain",s),t._isStdio||e&&!1===e.end||(r.on("end",o),r.on("close",a));var n=!1;function o(){n||(n=!0,t.end())}function a(){n||(n=!0,"function"==typeof t.destroy&&t.destroy())}function f(e){if(u(),0===h.listenerCount(this,"error"))throw e}function u(){r.removeListener("data",i),t.removeListener("drain",s),r.removeListener("end",o),r.removeListener("close",a),r.removeListener("error",f),t.removeListener("error",f),r.removeListener("end",u),r.removeListener("close",u),t.removeListener("close",u)}return r.on("error",f),t.on("error",f),r.on("end",u),r.on("close",u),t.on("close",u),t.emit("pipe",r),t}},{events:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/events/events.js",inherits:"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/inherits/inherits_browser.js","readable-stream/duplex.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/duplex-browser.js","readable-stream/passthrough.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/passthrough.js","readable-stream/readable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/readable-browser.js","readable-stream/transform.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/transform.js","readable-stream/writable.js":"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/readable-stream/writable-browser.js"}],"/home/sigve/Dev/Bitshares/bitsharesjs/node_modules/string_decoder/lib/string_decoder.js":[function(e,t,r){"use strict";var i=e("buffer").Buffer,s=e("buffer-shims"),n=i.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(e){var t;switch(this.encoding=function(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"!=typeof t&&(i.isEncoding===n||!n(e)))throw new Error("Unknown encoding: "+e);return t||e}(e),this.encoding){case"utf16le":this.text=u,this.end=h,t=4;break;case"utf8":this.fillLast=f,t=4;break;case"base64":this.text=c,this.end=l,t=3;break;default:return this.write=d,void(this.end=p)}this.lastNeed=0,this.lastTotal=0,this.lastChar=s.allocUnsafe(t)}function a(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:-1}function f(e){var t=this.lastTotal-this.lastNeed,r=function(e,t,r){if(128!=(192&t[0]))return e.lastNeed=0,"�".repeat(r);if(1 5%", + "node": "10" + } + } + ] + ], + "plugins": ["@babel/plugin-proposal-class-properties"] +} diff --git a/packages/bitsharesjs-ws/.gitignore b/packages/bitsharesjs-ws/.gitignore new file mode 100644 index 00000000..5e8f7ef0 --- /dev/null +++ b/packages/bitsharesjs-ws/.gitignore @@ -0,0 +1,10 @@ +.npmrc +npm-debug.log +node_modules +cjs +es +*.swp +browser-test/browser-test.js +build +package-lock.json +lib diff --git a/packages/bitsharesjs-ws/.npmignore b/packages/bitsharesjs-ws/.npmignore new file mode 100644 index 00000000..0ee8cc2a --- /dev/null +++ b/packages/bitsharesjs-ws/.npmignore @@ -0,0 +1,6 @@ +src +test +examples +build +browser-test +tools \ No newline at end of file diff --git a/packages/bitsharesjs-ws/LICENSE b/packages/bitsharesjs-ws/LICENSE new file mode 100644 index 00000000..d570bdb2 --- /dev/null +++ b/packages/bitsharesjs-ws/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 BitShares + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/bitsharesjs-ws/README.md b/packages/bitsharesjs-ws/README.md new file mode 100644 index 00000000..95affe5b --- /dev/null +++ b/packages/bitsharesjs-ws/README.md @@ -0,0 +1,136 @@ +# Bitshares websocket interface (bitsharesjs-ws) + +Pure JavaScript Bitshares websocket library for node.js and browsers. Can be used to easily connect to and obtain data from the Bitshares blockchain via public apis or local nodes. + +Credit for the original implementation goes to [jcalfeee](https://github.com/jcalfee). + +[![npm version](https://img.shields.io/npm/v/bitsharesjs-ws.svg?style=flat-square)](https://www.npmjs.com/package/bitsharesjs-ws) +[![npm downloads](https://img.shields.io/npm/dm/bitsharesjs-ws.svg?style=flat-square)](https://www.npmjs.com/package/bitsharesjs-ws) + +## Setup + +This library can be obtained through npm: + +``` +npm install bitsharesjs-ws +``` + +## Usage + +Several examples are available in the /examples folder, and the tests in /test also show how to use the library. + +Browser bundles are provided in /build/, for testing purposes you can access this from rawgit: + +``` + + + + + + + diff --git a/packages/bitsharesjs-ws/examples/accountIteration.js b/packages/bitsharesjs-ws/examples/accountIteration.js new file mode 100644 index 00000000..e77c0360 --- /dev/null +++ b/packages/bitsharesjs-ws/examples/accountIteration.js @@ -0,0 +1,100 @@ +// Node.js example +// This example shows how to iterate over all accounts in order determine +// the holders of a particular asset, in this case OBITS. It will do heavy polling so +// I recommend using a local node + +/* running 'npm run build' is necessary before launching the examples */ + +var {Apis} = require("../cjs"); +// let wsString = "wss://bitshares.openledger.info/ws"; +let wsStringLocal = "ws://127.0.0.1:8090"; + +let holders = {}; + +Apis.instance(wsStringLocal, true).init_promise.then(res => { + console.log("connected to:", res[0].network); + + Apis.instance() + .db_api() + .exec("lookup_asset_symbols", [["OBITS"]]) + .then(assets => { + console.log("OBITS id:", assets[0].id); + let assetID = assets[0].id; + + let maxIter = 2; + let iterations = 0; + let accountLimit = 500; + function balanceCheck(startChar) { + console.log("balanceCheck:", startChar); + try { + lookupAccounts(startChar, accountLimit).then(accounts => { + accounts.forEach(account => { + if ("balances" in account[1]) { + for ( + let i = 0; + i < account[1].balances.length; + i++ + ) { + if ( + account[1].balances[i].asset_type === + assetID && + parseInt( + account[1].balances[i].balance, + 10 + ) > 0 + ) { + // console.log(account[1].account.name, "has OBITS"); + holders[account[1].account.name] = + account[1].balances[i].balance; + break; + } + } + } + }); + if ( + accounts.length === accountLimit && + iterations < maxIter + ) { + iterations++; + console.log( + "Starting new iteration, so far found", + Object.keys(holders).length, + "holders" + ); + return balanceCheck( + accounts[accounts.length - 1][1].account.name + ); + } else { + // DONE, save holders to a file here + console.log( + "Found", + Object.keys(holders).length, + "OBITS holders" + ); + } + }); + } catch (err) { + console.log("err:", err); + } + } + + balanceCheck("a"); + }); +}); + +function lookupAccounts(startChar, limit = 1) { + return Apis.instance() + .db_api() + .exec("lookup_accounts", [startChar, limit]) + .then(accounts => { + let newInput = accounts.map(account => { + return account[0]; + }); + return Apis.instance() + .db_api() + .exec("get_full_accounts", [newInput, false]); + }) + .catch(err => { + console.log("err:", err); + }); +} diff --git a/packages/bitsharesjs-ws/examples/api.js b/packages/bitsharesjs-ws/examples/api.js new file mode 100644 index 00000000..33a980ef --- /dev/null +++ b/packages/bitsharesjs-ws/examples/api.js @@ -0,0 +1,17 @@ +// Node.js example +/* running 'npm run build' is necessary before launching the examples */ +var {Apis} = require("../cjs"); +let wsString = "wss://bitshares.openledger.info/ws"; +let wsStringLocal = "ws://127.0.0.1:8090"; + +Apis.instance(wsString, true).init_promise.then(res => { + console.log("connected to:", res[0].network); + + Apis.instance() + .db_api() + .exec("set_subscribe_callback", [updateListener, true]); +}); + +function updateListener(object) { + console.log("set_subscribe_callback update:\n", object); +} diff --git a/packages/bitsharesjs-ws/examples/index.html b/packages/bitsharesjs-ws/examples/index.html new file mode 100644 index 00000000..d289c214 --- /dev/null +++ b/packages/bitsharesjs-ws/examples/index.html @@ -0,0 +1,59 @@ + + + + + + +
Hello bitsharesjs-ws
+ +
+ +
+ + +
+
+ + + + + diff --git a/packages/bitsharesjs-ws/examples/sub_unsub.js b/packages/bitsharesjs-ws/examples/sub_unsub.js new file mode 100644 index 00000000..0d8db9c8 --- /dev/null +++ b/packages/bitsharesjs-ws/examples/sub_unsub.js @@ -0,0 +1,30 @@ +// Node.js example +/* running 'npm run build' is necessary before launching the examples */ +var {Apis} = require("../cjs"); +let wsString = "wss://bitshares.openledger.info/ws"; +let wsStringLocal = "ws://127.0.0.1:8090"; + +Apis.instance(wsString, true).init_promise.then(res => { + console.log("connected to:", res[0].network); + + Apis.instance() + .db_api() + .exec("subscribe_to_market", [updateListener, "1.3.0", "1.3.19"]); + + setTimeout(() => { + Apis.instance() + .db_api() + .exec("unsubscribe_from_market", [ + updateListener, + "1.3.0", + "1.3.19" + ]) + .then(unsub => { + console.log("unsub result:", unsub); + }); + }, 1500); +}); + +function updateListener(object) { + console.log("subscribe_to_market update:\n", object); +} diff --git a/packages/bitsharesjs-ws/package.json b/packages/bitsharesjs-ws/package.json new file mode 100644 index 00000000..793b5327 --- /dev/null +++ b/packages/bitsharesjs-ws/package.json @@ -0,0 +1,57 @@ +{ + "name": "bitsharesjs-ws", + "version": "1.6.5", + "description": "Pure JavaScript Bitshares/Graphene websocket interface for node.js and browsers.", + "browser": { + "ws": false + }, + "scripts": { + "test": "BABEL_ENV=test mocha --require @babel/register --recursive", + "test:watch": "npm test -- --watch", + "test:connection": "BABEL_ENV=test mocha --require @babel/register ./test/Connection --watch", + "test:api": "BABEL_ENV=test mocha --require @babel/register ./test/Api --watch", + "test:manager": "BABEL_ENV=test mocha --require @babel/register ./test/Manager --watch", + "pretest:browser": "NODE_ENV=dev browserify test/*.js -o browser-test/browser-test.js -t [ babelify ]", + "test:browser": "BABEL_ENV=test http-server ./browser-test", + "clean": "rm -rf ./lib/* & rm -rf ./build/*", + "prebuild": "npm run clean", + "build": "babel src -d lib", + "postbuild": "npm run browserify", + "prepublish": "npm run build", + "browserify": "NODE_ENV=production browserify lib/index.js --standalone bitshares_ws -o build/bitsharesjs-ws.js -d", + "postbrowserify": "NODE_ENV=production minify build/bitsharesjs-ws.js -o build/bitsharesjs-ws.min.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bitshares/bitsharesjs-ws.git" + }, + "author": "Sigve Kvalsvik (https://github.com/svk31)", + "contributors": [ + "James Calfee (https://github.com/jcalfee/)", + "scientistnik (https://github.com/scientistnik)" + ], + "license": "BSD-2-Clause-FreeBSD", + "bugs": { + "url": "https://github.com/bitshares/bitsharesjs-ws/issues" + }, + "engines": { + "node": ">= 10.0.0" + }, + "main": "lib/index.js", + "dependencies": { + "isomorphic-ws": "^4.0.1", + "ws": "4.1.0" + }, + "devDependencies": { + "@babel/cli": "^7.2.3", + "@babel/core": "^7.3.3", + "@babel/plugin-proposal-class-properties": "^7.3.3", + "@babel/preset-env": "^7.3.1", + "@babel/register": "^7.0.0", + "assert": "^1.3.0", + "babel-minify": "^0.5.0", + "browserify": "^16.2.3", + "http-server": "^0.11.1", + "mocha": "^5.2.0" + } +} diff --git a/packages/bitsharesjs-ws/src/ApiInstances.js b/packages/bitsharesjs-ws/src/ApiInstances.js new file mode 100644 index 00000000..d3a7903f --- /dev/null +++ b/packages/bitsharesjs-ws/src/ApiInstances.js @@ -0,0 +1,186 @@ +import ChainWebSocket from "./ChainWebSocket"; +import GrapheneApi from "./GrapheneApi"; +import ChainConfig from "./ChainConfig"; + +let autoReconnect = false; // by default don't use reconnecting-websocket + +var Apis = null; +var statusCb = null; + +export const setRpcConnectionStatusCallback = callback => { + statusCb = callback; + if (Apis) Apis.setRpcConnectionStatusCallback(callback); +}; + +export const setAutoReconnect = auto => { + autoReconnect = auto; +}; + +export const reset = ( + cs = "ws://localhost:8090", + connect, + connectTimeout = 4000, + optionalApis, + closeCb +) => { + return close().then(() => { + Apis = newApis(); + Apis.setRpcConnectionStatusCallback(statusCb); + + if (Apis && connect) + Apis.connect(cs, connectTimeout, optionalApis, closeCb); + + return Apis; + }); +}; + +export const instance = ( + cs = "ws://localhost:8090", + connect, + connectTimeout = 4000, + optionalApis, + closeCb +) => { + if (!Apis) { + Apis = newApis(); + Apis.setRpcConnectionStatusCallback(statusCb); + } + + if (Apis && connect) { + Apis.connect(cs, connectTimeout, optionalApis); + } + if (closeCb) Apis.closeCb = closeCb; + return Apis; +}; + +export const chainId = () => { + return instance().chain_id; +}; + +export const close = async () => { + if (Apis) { + await Apis.close(); + Apis = null; + } +}; + +const get = name => + new Proxy([], { + get: (_, method) => (...args) => Apis[name].exec(method, [...args]) + }); + +export const db = get("_db"); +export const network = get("_net"); +export const history = get("_hist"); +export const crypto = get("_crypt"); +export const orders = get("_orders"); + +const newApis = () => ({ + connect: ( + cs, + connectTimeout, + optionalApis = {enableCrypto: false, enableOrders: false} + ) => { + // console.log("INFO\tApiInstances\tconnect\t", cs); + Apis.url = cs; + let rpc_user = "", + rpc_password = ""; + if ( + typeof window !== "undefined" && + window.location && + window.location.protocol === "https:" && + cs.indexOf("wss://") < 0 + ) { + throw new Error("Secure domains require wss connection"); + } + + if (Apis.ws_rpc) { + Apis.ws_rpc.statusCb = null; + Apis.ws_rpc.keepAliveCb = null; + Apis.ws_rpc.on_close = null; + Apis.ws_rpc.on_reconnect = null; + } + Apis.ws_rpc = new ChainWebSocket( + cs, + Apis.statusCb, + connectTimeout, + autoReconnect, + closed => { + if (Apis._db && !closed) { + Apis._db.exec("get_objects", [["2.1.0"]]).catch(e => {}); + } + } + ); + + Apis.init_promise = Apis.ws_rpc + .login(rpc_user, rpc_password) + .then(() => { + //console.log("Connected to API node:", cs); + Apis._db = new GrapheneApi(Apis.ws_rpc, "database"); + Apis._net = new GrapheneApi(Apis.ws_rpc, "network_broadcast"); + Apis._hist = new GrapheneApi(Apis.ws_rpc, "history"); + if (optionalApis.enableOrders) + Apis._orders = new GrapheneApi(Apis.ws_rpc, "orders"); + if (optionalApis.enableCrypto) + Apis._crypt = new GrapheneApi(Apis.ws_rpc, "crypto"); + var db_promise = Apis._db.init().then(() => { + //https://github.com/cryptonomex/graphene/wiki/chain-locked-tx + return Apis._db.exec("get_chain_id", []).then(_chain_id => { + Apis.chain_id = _chain_id; + return ChainConfig.setChainId(_chain_id); + //DEBUG console.log("chain_id1",this.chain_id) + }); + }); + Apis.ws_rpc.on_reconnect = () => { + if (!Apis.ws_rpc) return; + Apis.ws_rpc.login("", "").then(() => { + Apis._db.init().then(() => { + if (Apis.statusCb) Apis.statusCb("reconnect"); + }); + Apis._net.init(); + Apis._hist.init(); + if (optionalApis.enableOrders) Apis._orders.init(); + if (optionalApis.enableCrypto) Apis._crypt.init(); + }); + }; + Apis.ws_rpc.on_close = () => { + Apis.close().then(() => { + if (Apis.closeCb) Apis.closeCb(); + }); + }; + let initPromises = [ + db_promise, + Apis._net.init(), + Apis._hist.init() + ]; + + if (optionalApis.enableOrders) + initPromises.push(Apis._orders.init()); + if (optionalApis.enableCrypto) + initPromises.push(Apis._crypt.init()); + return Promise.all(initPromises); + }) + .catch(err => { + console.error( + cs, + "Failed to initialize with error", + err && err.message + ); + return Apis.close().then(() => { + throw err; + }); + }); + }, + close: async () => { + if (Apis.ws_rpc && Apis.ws_rpc.ws.readyState === 1) + await Apis.ws_rpc.close(); + + Apis.ws_rpc = null; + }, + db_api: () => Apis._db, + network_api: () => Apis._net, + history_api: () => Apis._hist, + crypto_api: () => Apis._crypt, + orders_api: () => Apis._orders, + setRpcConnectionStatusCallback: callback => (Apis.statusCb = callback) +}); diff --git a/packages/bitsharesjs-ws/src/ChainConfig.js b/packages/bitsharesjs-ws/src/ChainConfig.js new file mode 100644 index 00000000..34bd2443 --- /dev/null +++ b/packages/bitsharesjs-ws/src/ChainConfig.js @@ -0,0 +1,65 @@ +var config = { + core_asset: "CORE", + address_prefix: "GPH", + expire_in_secs: 15, + expire_in_secs_proposal: 24 * 60 * 60, + review_in_secs_committee: 24 * 60 * 60, + networks: { + BitShares: { + core_asset: "BTS", + address_prefix: "BTS", + chain_id: + "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8" + }, + Muse: { + core_asset: "MUSE", + address_prefix: "MUSE", + chain_id: + "45ad2d3f9ef92a49b55c2227eb06123f613bb35dd08bd876f2aea21925a67a67" + }, + Test: { + core_asset: "TEST", + address_prefix: "TEST", + chain_id: + "39f5e2ede1f8bc1a3a54a7914414e3779e33193f1f5693510e73cb7a87617447" + }, + Obelisk: { + core_asset: "GOV", + address_prefix: "FEW", + chain_id: + "1cfde7c388b9e8ac06462d68aadbd966b58f88797637d9af805b4560b0e9661e" + } + }, + + /** Set a few properties for known chain IDs. */ + setChainId: chain_id => { + let result = Object.entries(config.networks).find( + ([network_name, network]) => { + if (network.chain_id === chain_id) { + config.network_name = network_name; + + if (network.address_prefix) { + config.address_prefix = network.address_prefix; + } + return true; + } + } + ); + + if (result) return {network_name: result[0], network: result[1]}; + else console.log("Unknown chain id (this may be a testnet)", chain_id); + }, + + reset: () => { + config.core_asset = "CORE"; + config.address_prefix = "GPH"; + config.expire_in_secs = 15; + config.expire_in_secs_proposal = 24 * 60 * 60; + + console.log("Chain config reset"); + }, + + setPrefix: (prefix = "GPH") => (config.address_prefix = prefix) +}; + +export default config; diff --git a/packages/bitsharesjs-ws/src/ChainWebSocket.js b/packages/bitsharesjs-ws/src/ChainWebSocket.js new file mode 100644 index 00000000..2e2f4a5b --- /dev/null +++ b/packages/bitsharesjs-ws/src/ChainWebSocket.js @@ -0,0 +1,272 @@ +import WebSocket from "isomorphic-ws"; + +const SOCKET_DEBUG = false; +const MAX_SEND_LIFE = 5; +const MAX_RECV_LIFE = MAX_SEND_LIFE * 2; + +class ChainWebSocket { + constructor( + ws_server, + statusCb, + connectTimeout = 5000, + autoReconnect = true, + keepAliveCb = null + ) { + this.url = ws_server; + this.statusCb = statusCb; + + this.current_reject = null; + this.on_reconnect = null; + this.closed = false; + this.send_life = MAX_SEND_LIFE; + this.recv_life = MAX_RECV_LIFE; + this.keepAliveCb = keepAliveCb; + + this.cbId = 0; + this.responseCbId = 0; + this.cbs = {}; + this.subs = {}; + this.unsub = {}; + + this.connect_promise = this.connect(ws_server, connectTimeout); + } + + connect = (server, connectTimeout) => + new Promise((resolve, reject) => { + this.current_reject = reject; + this.current_resolve = resolve; + + try { + this.ws = new WebSocket(server); + } catch (error) { + this.ws = {readyState: 3, close: () => {}}; // DISCONNECTED + reject(new Error("Invalid url", server, " closed")); + // return this.close().then(() => { + // console.log("Invalid url", ws_server, " closed"); + // // throw new Error("Invalid url", ws_server, " closed") + // // return this.current_reject(Error("Invalid websocket url: " + ws_server)); + // }) + } + + this.ws.onopen = this.onOpen; + this.ws.onerror = this.onError; + this.ws.onmessage = this.onMessage; + this.ws.onclose = this.onClose; + + this.connectionTimeout = setTimeout(() => { + if (this.current_reject) { + this.current_reject = null; + this.close(); + reject( + new Error( + "Connection attempt timed out after " + + connectTimeout / 1000 + + "s" + ) + ); + } + }, connectTimeout); + }); + + onOpen = () => { + clearTimeout(this.connectionTimeout); + if (this.statusCb) this.statusCb("open"); + if (this.on_reconnect) this.on_reconnect(); + this.keepalive_timer = setInterval(() => { + this.recv_life--; + if (this.recv_life == 0) { + console.error(this.url + " connection is dead, terminating ws"); + this.close(); + // clearInterval(this.keepalive_timer); + // this.keepalive_timer = undefined; + return; + } + this.send_life--; + if (this.send_life == 0) { + // this.ws.ping('', false, true); + if (this.keepAliveCb) { + this.keepAliveCb(this.closed); + } + this.send_life = MAX_SEND_LIFE; + } + }, 5000); + this.current_reject = null; + this.current_resolve(); + }; + + onError = error => { + if (this.keepalive_timer) { + clearInterval(this.keepalive_timer); + this.keepalive_timer = undefined; + } + clearTimeout(this.connectionTimeout); + if (this.statusCb) this.statusCb("error"); + + if (this.current_reject) { + this.current_reject(error); + } + }; + + onMessage = message => { + this.recv_life = MAX_RECV_LIFE; + this.listener(JSON.parse(message.data)); + }; + + onClose = () => { + this.closed = true; + if (this.keepalive_timer) { + clearInterval(this.keepalive_timer); + this.keepalive_timer = undefined; + } + + for (var cbId = this.responseCbId + 1; cbId <= this.cbId; cbId += 1) + this.cbs[cbId].reject(new Error("connection closed")); + + this.statusCb && this.statusCb("closed"); + this._closeCb && this._closeCb(); + this.on_close && this.on_close(); + }; + + call = params => { + if (this.ws.readyState !== 1) { + return Promise.reject( + new Error("websocket state error:" + this.ws.readyState) + ); + } + let method = params[1]; + if (SOCKET_DEBUG) + console.log( + '[ChainWebSocket] >---- call -----> "id":' + (this.cbId + 1), + JSON.stringify(params) + ); + + this.cbId += 1; + + if ( + [ + "set_subscribe_callback", + "subscribe_to_market", + "broadcast_transaction_with_callback", + "set_pending_transaction_callback" + ].includes(method) + ) { + // Store callback in subs map + this.subs[this.cbId] = { + callback: params[2][0] + }; + + // Replace callback with the callback id + params[2][0] = this.cbId; + } + + if ( + ["unsubscribe_from_market", "unsubscribe_from_accounts"].includes( + method + ) + ) { + if (typeof params[2][0] !== "function") { + throw new Error( + "First parameter of unsub must be the original callback" + ); + } + + let unSubCb = params[2].splice(0, 1)[0]; + + // Find the corresponding subscription + for (let id in this.subs) { + if (this.subs[id].callback === unSubCb) { + this.unsub[this.cbId] = id; + break; + } + } + } + + var request = { + method: "call", + params: params + }; + request.id = this.cbId; + this.send_life = MAX_SEND_LIFE; + + return new Promise((resolve, reject) => { + this.cbs[this.cbId] = { + time: new Date(), + resolve: resolve, + reject: reject + }; + this.ws.send(JSON.stringify(request)); + }); + }; + + listener = response => { + if (SOCKET_DEBUG) + console.log( + "[ChainWebSocket] <---- reply ----<", + JSON.stringify(response) + ); + + let sub = false, + callback = null; + + if (response.method === "notice") { + sub = true; + response.id = response.params[0]; + } + + if (!sub) { + callback = this.cbs[response.id]; + this.responseCbId = response.id; + } else { + callback = this.subs[response.id].callback; + } + + if (callback && !sub) { + if (response.error) { + callback.reject(response.error); + } else { + callback.resolve(response.result); + } + delete this.cbs[response.id]; + + if (this.unsub[response.id]) { + delete this.subs[this.unsub[response.id]]; + delete this.unsub[response.id]; + } + } else if (callback && sub) { + callback(response.params[1]); + } else { + console.log("Warning: unknown websocket response: ", response); + } + }; + + login = (user, password) => + this.connect_promise.then(() => + this.call([1, "login", [user, password]]) + ); + + close = () => + new Promise(res => { + clearInterval(this.keepalive_timer); + this.keepalive_timer = undefined; + + this._closeCb = () => { + res(); + this._closeCb = null; + }; + + if (!this.ws) { + console.log("Websocket already cleared", this); + return res(); + } + + if (this.ws.terminate) { + this.ws.terminate(); + } else { + this.ws.close(); + } + + if (this.ws.readyState === 3) res(); + }); +} + +export default ChainWebSocket; diff --git a/packages/bitsharesjs-ws/src/ConnectionManager.js b/packages/bitsharesjs-ws/src/ConnectionManager.js new file mode 100644 index 00000000..70db7f13 --- /dev/null +++ b/packages/bitsharesjs-ws/src/ConnectionManager.js @@ -0,0 +1,168 @@ +import * as Apis from "./ApiInstances"; +import ChainWebSocket from "./ChainWebSocket"; + +class Manager { + constructor({ + url, + urls, + autoFallback, + closeCb, + optionalApis, + urlChangeCallback + }) { + this.url = url; + this.urls = urls.filter(a => a !== url); + this.autoFallback = autoFallback; + this.closeCb = closeCb; + this.optionalApis = optionalApis || {}; + this.isConnected = false; + this.urlChangeCallback = urlChangeCallback; + } + + setCloseCb = cb => { + this.closeCb = cb; + }; + + static close() { + return Apis.close(); + } + + logFailure = (method, url, err) => { + let message = err && err.message ? err.message : ""; + console.error( + method, + "Failed to connect to " + + url + + (message ? " Error: " + JSON.stringify(message) : "") + ); + }; + + _onClose = () => { + this.isConnected = false; + + if (this.closeCb) { + this.closeCb(); + this.setCloseCb(null); + } + + this.autoFallback && this.connectWithFallback(); + }; + + connect = async (connect = true, url = this.url) => { + try { + let res = await Apis.instance( + url, + connect, + undefined, + this.optionalApis, + this._onClose + ).init_promise; + + this.url = url; + this.isConnected = true; + + return res; + } catch (err) { + await Apis.close(); + throw err; + } + }; + + connectWithFallback = async ( + connect = true, + url = this.url, + index = 0, + resolve = null, + reject = null + ) => { + if (index > this.urls.length) + return reject( + new Error( + "Tried " + + index + + " connections, none of which worked: " + + JSON.stringify(this.urls.concat(this.url)) + ) + ); + + try { + return await this.connect(connect, url); + } catch (err) { + if (this.urlChangeCallback) + this.urlChangeCallback(this.urls[index]); + return this.connectWithFallback( + connect, + this.urls[index], + index + 1, + resolve, + reject + ); + } + }; + + checkConnections = async ( + rpc_user = "", + rpc_password = "", + resolve, + reject + ) => { + let connectionStartTimes = {}; + + let fullList = this.urls.concat(this.url); + let connectionPromises = fullList.map(async url => { + /* Use default timeout and no reconnecting-websocket */ + let conn = new ChainWebSocket(url, () => {}, undefined, false); + connectionStartTimes[url] = new Date().getTime(); + + try { + await conn.login(rpc_user, rpc_password); + + let result = { + [url]: new Date().getTime() - connectionStartTimes[url] + }; + await conn.close(); + + return result; + } catch (err) { + this.logFailure("checkConnections", url, err); + if (url === this.url) { + this.url = this.urls[0]; + } else { + this.urls = this.urls.filter(a => a !== url); + } + await conn.close(); + return; + } + }); + + try { + let res = await Promise.all(connectionPromises); + + let final = res + .filter(a => !!a) + .sort((a, b) => { + return Object.values(a)[0] - Object.values(b)[0]; + }) + .reduce((f, a) => { + let key = Object.keys(a)[0]; + f[key] = a[key]; + return f; + }, {}); + + console.log( + `Checked ${res.length} connections, ${res.length - + Object.keys(final).length} failed` + ); + return final; + } catch (err) { + return this.checkConnections( + rpc_user, + rpc_password, + resolve, + reject + ); + } + }; +} + +export default Manager; diff --git a/packages/bitsharesjs-ws/src/GrapheneApi.js b/packages/bitsharesjs-ws/src/GrapheneApi.js new file mode 100644 index 00000000..2ebc5fab --- /dev/null +++ b/packages/bitsharesjs-ws/src/GrapheneApi.js @@ -0,0 +1,24 @@ +class GrapheneApi { + constructor(ws_rpc, api_name) { + this.ws_rpc = ws_rpc; + this.api_name = api_name; + } + + init() { + var self = this; + return this.ws_rpc.call([1, this.api_name, []]).then(response => { + //console.log("[GrapheneApi.js:11] ----- GrapheneApi.init ----->", this.api_name, response); + self.api_id = response; + return self; + }); + } + + exec(method, params) { + return this.ws_rpc.call([this.api_id, method, params]).catch(error => { + // console.log("!!! GrapheneApi error: ", method, params, error, JSON.stringify(error)); + throw error; + }); + } +} + +export default GrapheneApi; diff --git a/packages/bitsharesjs-ws/src/index.js b/packages/bitsharesjs-ws/src/index.js new file mode 100644 index 00000000..2712e7e6 --- /dev/null +++ b/packages/bitsharesjs-ws/src/index.js @@ -0,0 +1,5 @@ +import * as Apis from "./ApiInstances"; +import Manager from "./ConnectionManager"; +import ChainConfig from "./ChainConfig"; + +export {Apis, ChainConfig, Manager}; diff --git a/packages/bitsharesjs-ws/test/Api.js b/packages/bitsharesjs-ws/test/Api.js new file mode 100644 index 00000000..7ddb93ee --- /dev/null +++ b/packages/bitsharesjs-ws/test/Api.js @@ -0,0 +1,543 @@ +import assert from "assert"; +import {Apis} from "../lib"; + +var coreAsset; +var default_api = "wss://eu.openledger.info/ws"; + +describe("Api", () => { + let cs = default_api; + + describe("Subscriptions", function() { + beforeEach(function() { + return Apis.instance(cs, true) + .init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + }) + .catch(() => {}); + }); + + afterEach(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + it("Set subscribe callback", function() { + return new Promise(function(resolve) { + Apis.instance() + .db_api() + .exec("set_subscribe_callback", [callback, true]) + .then(function(sub) { + if (sub === null) { + resolve(); + } else { + reject(new Error("Expected sub to equal null")); + } + }); + + function callback(obj) { + console.log("callback obj:", obj); + resolve(); + } + }); + }); + + it("Market subscription", function() { + return new Promise(function(resolve) { + Apis.instance() + .db_api() + .exec("subscribe_to_market", [callback, "1.3.0", "1.3.19"]) + .then(function(sub) { + if (sub === null) { + resolve(); + } else { + reject(new Error("Expected sub to equal null")); + } + }); + + function callback() { + resolve(); + } + }); + }); + + it("Market unsubscribe", function() { + this.timeout(10000); + return new Promise(function(resolve) { + Apis.instance() + .db_api() + .exec("subscribe_to_market", [callback, "1.3.0", "1.3.19"]) + .then(function() { + Apis.instance() + .db_api() + .exec("unsubscribe_from_market", [ + callback, + "1.3.0", + "1.3.19" + ]) + .then(function(unsub) { + if (unsub === null) { + resolve(); + } else { + reject( + new Error( + "Expected unsub to equal null" + ) + ); + } + }); + }); + + function callback() { + resolve(); + } + }); + }); + }); + + describe("Database API", function() { + // Connect once for all tests + before(function() { + return Apis.instance(cs, true).init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + }); + }); + + after(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + it("Get object", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .db_api() + .exec("get_objects", [["2.0.0"]]) + .then(function(objects) { + if (objects[0].id === "2.0.0") { + resolve(); + } else { + reject(new Error("Expected object with id 2.0.0")); + } + }); + }); + }); + + it("Get object (short)", function() { + return new Promise(function(resolve, reject) { + Apis.db.get_objects(["2.0.0"]).then(function(objects) { + if (objects[0].id === "2.0.0") { + resolve(); + } else { + reject(new Error("Expected object with id 2.0.0")); + } + }); + }); + }); + + it("Get account by name", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .db_api() + .exec("get_account_by_name", ["committee-account"]) + .then(function(account) { + if ( + account.id === "1.2.0" && + account.name === "committee-account" + ) { + resolve(); + } else { + reject( + new Error( + "Expected object with id 1.2.0 and name committee-account" + ) + ); + } + }); + }); + }); + + it("Get account by name (short)", function() { + return new Promise(function(resolve, reject) { + Apis.db + .get_account_by_name("committee-account") + .then(function(account) { + if ( + account.id === "1.2.0" && + account.name === "committee-account" + ) { + resolve(); + } else { + reject( + new Error( + "Expected object with id 1.2.0 and name committee-account" + ) + ); + } + }); + }); + }); + + it("Get block", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .db_api() + .exec("get_block", [1]) + .then(function(block) { + if ( + block.previous === + "0000000000000000000000000000000000000000" + ) { + resolve(); + } else { + reject( + new Error( + "Expected block with previous value of 0000000000000000000000000000000000000000" + ) + ); + } + }); + }); + }); + + it("Get block (short)", function() { + return new Promise(function(resolve, reject) { + Apis.db.get_block(1).then(function(block) { + if ( + block.previous === + "0000000000000000000000000000000000000000" + ) { + resolve(); + } else { + reject( + new Error( + "Expected block with previous value of 0000000000000000000000000000000000000000" + ) + ); + } + }); + }); + }); + + it("Get full accounts", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .db_api() + .exec("get_full_accounts", [ + ["committee-account", "1.2.0"], + true + ]) + .then(function(accounts) { + let byName = accounts[0][1]; + let byId = accounts[1][1]; + if ( + byName.account.id === "1.2.0" && + byId.account.name === "committee-account" + ) { + resolve(); + } else { + reject( + new Error( + "Expected objects with id 1.2.0 and name committee-account" + ) + ); + } + }); + }); + }); + + it("Get full accounts (short)", function() { + return new Promise(function(resolve, reject) { + Apis.db + .get_full_accounts(["committee-account", "1.2.0"], true) + .then(function(accounts) { + let byName = accounts[0][1]; + let byId = accounts[1][1]; + if ( + byName.account.id === "1.2.0" && + byId.account.name === "committee-account" + ) { + resolve(); + } else { + reject( + new Error( + "Expected objects with id 1.2.0 and name committee-account" + ) + ); + } + }); + }); + }); + + it("Lookup assets by symbol", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .db_api() + .exec("lookup_asset_symbols", [[coreAsset, coreAsset]]) + .then(function(assets) { + if ( + assets[0].symbol === coreAsset && + assets[1].symbol === coreAsset + ) { + resolve(); + } else { + reject( + new Error( + "Expected assets with symbol " + coreAsset + ) + ); + } + }); + }); + }); + + it("Lookup assets by symbol (short)", function() { + return new Promise(function(resolve, reject) { + Apis.db + .lookup_asset_symbols([coreAsset, coreAsset]) + .then(function(assets) { + if ( + assets[0].symbol === coreAsset && + assets[1].symbol === coreAsset + ) { + resolve(); + } else { + reject( + new Error( + "Expected assets with symbol " + coreAsset + ) + ); + } + }); + }); + }); + + it("List assets", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .db_api() + .exec("list_assets", ["A", 5]) + .then(function(assets) { + if (assets.length > 0) { + resolve(); + } else { + reject( + new Error( + "Expected assets with symbol " + coreAsset + ) + ); + } + }); + }); + }); + + it("List assets (short)", function() { + return new Promise(function(resolve, reject) { + Apis.db.list_assets("A", 5).then(function(assets) { + if (assets.length > 0) { + resolve(); + } else { + reject( + new Error( + "Expected assets with symbol " + coreAsset + ) + ); + } + }); + }); + }); + }); + + describe("History API", function() { + // Connect once for all tests + before(function() { + return Apis.instance(cs, true).init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + }); + }); + + after(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + it("Get market data", function() { + return new Promise(function(resolve, reject) { + if (coreAsset !== "BTS") { + reject( + new Error( + "This test will only work when connected to a BTS api" + ) + ); + } + Apis.instance() + .history_api() + .exec("get_fill_order_history", ["1.3.121", "1.3.0", 10]) + .then(function(history) { + if (history.length > 0) { + resolve(); + } else { + reject( + new Error( + "Expected market history of at least one entry" + ) + ); + } + }); + }); + }); + + it("Get market data (short)", function() { + return new Promise(function(resolve, reject) { + if (coreAsset !== "BTS") { + reject( + new Error( + "This test will only work when connected to a BTS api" + ) + ); + } + Apis.history + .get_fill_order_history("1.3.121", "1.3.0", 10) + .then(function(history) { + if (history.length > 0) { + resolve(); + } else { + reject( + new Error( + "Expected market history of at least one entry" + ) + ); + } + }); + }); + }); + }); + + describe("Crypto API", function() { + // Connect once for all tests + before(function() { + return Apis.instance(cs, true, 5000, { + enableCrypto: true + }).init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + }); + }); + + after(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + it("Initializes the crypto api", function() { + assert(!!Apis.instance().crypto_api()); + }); + + it("Initializes the crypto api (short)", function() { + assert(!!Apis.crypto); + }); + }); + + describe("Orders API", function() { + // Connect once for all tests + before(function() { + return Apis.instance(cs, true, 5000, { + enableOrders: true + }).init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + }); + }); + + after(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + it("Initializes the orders api", function() { + assert(!!Apis.instance().orders_api()); + }); + + it("Initializes the orders api (short)", function() { + assert(!!Apis.orders); + }); + + it("Get tracked groups config", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .orders_api() + .exec("get_tracked_groups", []) + .then(function(trackedGroups) { + if (trackedGroups.length > 0) { + resolve(); + } else { + reject(new Error("Get tracked groups error")); + } + }) + .catch(err => { + reject(err); + }); + }); + }); + + it("Get tracked groups config (short)", function() { + return new Promise(function(resolve, reject) { + Apis.orders + .get_tracked_groups() + .then(function(trackedGroups) { + if (trackedGroups.length > 0) { + resolve(); + } else { + reject(new Error("Get tracked groups error")); + } + }) + .catch(err => { + reject(err); + }); + }); + }); + + it("Get ordered groups", function() { + return new Promise(function(resolve, reject) { + Apis.instance() + .orders_api() + .exec("get_grouped_limit_orders", [ + "1.3.113", + "1.3.0", + 10, + null, + 1 + ]) + .then(function(groups) { + if (groups.length > 0) { + resolve(); + } else { + reject(new Error("Get groups error")); + } + }) + .catch(err => { + reject(err); + }); + }); + }); + + it("Get ordered groups (short)", function() { + return new Promise(function(resolve, reject) { + Apis.orders + .get_grouped_limit_orders("1.3.113", "1.3.0", 10, null, 1) + .then(function(groups) { + if (groups.length > 0) { + resolve(); + } else { + reject(new Error("Get groups error")); + } + }) + .catch(err => { + reject(err); + }); + }); + }); + }); +}); diff --git a/packages/bitsharesjs-ws/test/Connection.js b/packages/bitsharesjs-ws/test/Connection.js new file mode 100644 index 00000000..73f9abd4 --- /dev/null +++ b/packages/bitsharesjs-ws/test/Connection.js @@ -0,0 +1,115 @@ +import assert from "assert"; +import {Apis} from "../lib"; + +var coreAsset; +var default_api = "wss://eu.nodes.bitshares.ws"; + +describe("Connection", () => { + afterEach(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + // it("Connect to localhost", function() { + // return new Promise( function(resolve) { + // Apis.instance("ws://localhost:8090").init_promise.then(function (result) { + // coreAsset = result[0].network.core_asset; + // + // if (typeof coreAsset === "string") { + // resolve(); + // } else { + // reject(new Error("Expected coreAsset to be a string")); + // } + // }); + // }); + // }); + + it("Connect to Mainnet", function() { + return new Promise(function(resolve, reject) { + Apis.instance(default_api, true) + .init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + assert(coreAsset === "BTS"); + resolve(); + }) + .catch(reject); + }); + }); + + it("Connect to Testnet", function() { + return new Promise(function(resolve, reject) { + Apis.instance("wss://node.testnet.bitshares.eu", true) + .init_promise.then(function(result) { + coreAsset = result[0].network.core_asset; + assert(coreAsset === "TEST"); + resolve(); + }) + .catch(reject); + }); + }); + + it("Times out properly", function() { + return new Promise(function(resolve, reject) { + /* 1ms connection timeout */ + Apis.instance(default_api, true, 1) + .init_promise.then(function() { + reject(); + }) + .catch(function(err) { + assert( + err.message.search("Connection attempt timed out") !== + -1 + ); + resolve(); + }); + }); + }); + + it("Can be closed", function() { + return new Promise(function(resolve, reject) { + Apis.instance(default_api, true).init_promise.then(function( + result + ) { + coreAsset = result[0].network.core_asset; + assert(coreAsset === "BTS"); + Apis.instance() + .close() + .then(function() { + resolve(); + }) + .catch(reject); + }); + }); + }); +}); + +describe("Connection reset", () => { + afterEach(function() { + return new Promise(function(res) { + Apis.close().then(res); + }); + }); + + it("Resets between chains", function() { + return new Promise(function(resolve, reject) { + Apis.instance(default_api, true).init_promise.then(function( + result + ) { + coreAsset = result[0].network.core_asset; + assert(coreAsset === "BTS"); + Apis.reset("wss://node.testnet.bitshares.eu", true).then( + instance => { + instance.init_promise + .then(function(result) { + coreAsset = result[0].network.core_asset; + assert(coreAsset === "TEST"); + resolve(); + }) + .catch(reject); + } + ); + }); + }); + }); +}); diff --git a/packages/bitsharesjs-ws/test/Manager.js b/packages/bitsharesjs-ws/test/Manager.js new file mode 100644 index 00000000..d1595e0a --- /dev/null +++ b/packages/bitsharesjs-ws/test/Manager.js @@ -0,0 +1,352 @@ +import assert from "assert"; +import {Manager, Apis} from "../lib"; + +var defaultUrl = "wss://eu.nodes.bitshares.ws"; + +var faultyNodeList = [ + { + url: "wss://bitsqsdqsdhares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + { + url: "wss://bitazdazdshares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + { + url: "wss://bitshaazdzares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + {url: "wss://bit.btzadazdsabc.org/ws", location: "Hong Kong"}, + {url: "ws://127.0.0.1:8091", location: "Hangzhou, China"}, + {url: "wss://bitshares.openledger.info/ws", location: "Nuremberg, Germany"}, + {url: "wss://secure.freedomledger.com/ws", location: "Toronto, Canada"}, + { + url: "wss://node.testnet.bitshares.eu", + location: "Public Testnet Server (Frankfurt, Germany)" + } +]; + +var noWorkingNodes = [ + { + url: "wss://bitsqsdqsdhares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + { + url: "wss://bitazdazdshares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + { + url: "wss://bitshaazdzares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + {url: "wss://bit.btzadazdsabc.org/ws", location: "Hong Kong"}, + {url: "ws://127.23230.0.1:8091", location: "Hangzhou, China"}, + { + url: "wss://bitshasdares.dacplay.org:8089/ws", + location: "Hangzhou, China" + }, + {url: "wss://secuasdre.freedomledger.com/ws", location: "Toronto, Canada"}, + { + url: "wss://testnet.bitshares.eu/wqsdsqs", + location: "Public Testnet Server (Frankfurt, Germany)" + } +]; + +var goodNodeList = [ + {url: "wss://bitshares.openledger.info/ws", location: "Nuremberg, Germany"}, + {url: "wss://bit.btsabc.org/ws", location: "Hong Kong"}, + {url: "wss://bts.transwiser.com/ws", location: "Hangzhou, China"}, + {url: "wss://bitshares.dacplay.org:8089/ws", location: "Hangzhou, China"}, + {url: "wss://openledger.hk/ws", location: "Hong Kong"}, + {url: "wss://secure.freedomledger.com/ws", location: "Toronto, Canada"}, + { + url: "wss://node.testnet.bitshares.eu", + location: "Public Testnet Server (Frankfurt, Germany)" + } +]; + +var fullNodeList = [ + { + url: "wss://fake.automatic-selection.com", + location: {translate: "settings.api_closest"} + }, + {url: "ws://127.0.0.1:8090", location: "Locally hosted"}, + { + url: "wss://bitshares.openledger.info/ws", + location: "Nuremberg, Germany" + }, + {url: "wss://eu.openledger.info/ws", location: "Berlin, Germany"}, + {url: "wss://bitshares.nu/ws", location: "Stockholm, Sweden"}, + {url: "wss://bit.btsabc.org/ws", location: "Hong Kong"}, + {url: "wss://node.btscharts.com/ws", location: "Hong Kong"}, + {url: "wss://bitshares.apasia.tech/ws", location: "Bangkok, Thailand"}, + {url: "wss://japan.bitshares.apasia.tech/ws", location: "Tokyo, Japan"}, + {url: "wss://bitshares.dacplay.org/ws", location: "Hangzhou, China"}, + {url: "wss://bitshares-api.wancloud.io/ws", location: "China"}, + {url: "wss://openledger.hk/ws", location: "Hong Kong"}, + {url: "wss://bitshares.crypto.fans/ws", location: "Munich, Germany"}, + {url: "wss://ws.gdex.io", location: "Japan"}, + {url: "wss://ws.gdex.top", location: "China"}, + {url: "wss://dex.rnglab.org", location: "Netherlands"}, + {url: "wss://dexnode.net/ws", location: "Dallas, USA"}, + {url: "wss://la.dexnode.net/ws", location: "LA, USA"}, + {url: "wss://kc-us-dex.xeldal.com/ws", location: "Kansas City, USA"}, + {url: "wss://btsza.co.za:8091/ws", location: "Cape Town, South Africa"}, + {url: "wss://api.bts.blckchnd.com", location: "Falkenstein, Germany"}, + {url: "wss://api-ru.bts.blckchnd.com", location: "Moscow, Russia"}, + {url: "wss://node.market.rudex.org", location: "Germany"}, + { + url: "wss://eu.nodes.bitshares.ws", + location: "Central Europe - BitShares Infrastructure Program" + }, + { + url: "wss://us.nodes.bitshares.ws", + location: "U.S. West Coast - BitShares Infrastructure Program" + }, + { + url: "wss://sg.nodes.bitshares.ws", + location: "Singapore - BitShares Infrastructure Program" + }, + {url: "wss://ws.winex.pro", location: "Singapore"}, + {url: "wss://api.bts.mobi/ws", location: "VA, USA"}, + { + url: "wss://api.btsxchng.com", + location: + "Global (Asia Pacific (Singapore) / US East (N. Virginia) / EU (London))" + }, + {url: "wss://api.bts.network", location: "East Coast, USA"}, + {url: "wss://btsws.roelandp.nl/ws", location: "Finland"}, + {url: "wss://api.bitshares.bhuz.info/ws", location: "Europe"}, + {url: "wss://bts-api.lafona.net/ws", location: "USA"}, + {url: "wss://kimziv.com/ws", location: "Singapore"}, + {url: "wss://api.btsgo.net/ws", location: "Singapore"}, + {url: "wss://bts.proxyhosts.info/wss", location: "Germany"}, + {url: "wss://bts.open.icowallet.net/ws", location: "Hangzhou, China"}, + {url: "wss://blockzms.xyz/ws", location: "USA"}, + {url: "wss://crazybit.online", location: "China"}, + {url: "wss://freedom.bts123.cc:15138/", location: "China"}, + {url: "wss://bitshares.bts123.cc:15138/", location: "China"}, + {url: "wss://api.bts.ai/", location: "Beijing, China"}, + {url: "wss://ws.hellobts.com/", location: "Japan"}, + {url: "wss://bitshares.cyberit.io/", location: "Hong Kong"}, + {url: "wss://bts-seoul.clockwork.gr/", location: "Seoul, Korea"}, + {url: "wss://bts.to0l.cn:4443/ws", location: "China"}, + // Testnet + { + url: "wss://node.testnet.bitshares.eu", + location: "TESTNET - BitShares Europe (Frankfurt, Germany)" + }, + { + url: "wss://testnet.nodes.bitshares.ws", + location: "TESTNET - BitShares Infrastructure Program" + } +]; + +/* This node currently throws an API error for the crypto API */ +var failedInitNodes = [ + {url: "wss://bitshares.crypto.fans/ws", location: "Munich"} +]; + +describe("Connection Manager", function() { + afterEach(function() { + return new Promise(function(res) { + Manager.close().then(res); + }); + }); + + it("Instantiates", function() { + let man = new Manager({ + url: defaultUrl, + urls: faultyNodeList.map(a => a.url) + }); + assert.equal(man.url, defaultUrl); + }); + + it("Instantiates with crypto api", function() { + let man = new Manager({ + url: "wss://eu.openledger.info/ws", + urls: [], + optionalApis: {enableCrypto: true} + }); + return new Promise(function(resolve, reject) { + man.connect().then(() => { + assert(!!Apis.instance().crypto_api()); + resolve(); + }); + }); + }); + + it("Instantiates with orders api", function() { + let man = new Manager({ + url: "wss://eu.openledger.info/ws", + urls: [], + optionalApis: {enableCrypto: true, enableOrders: true} + }); + return new Promise(function(resolve, reject) { + man.connect().then(() => { + assert(!!Apis.instance().orders_api()); + resolve(); + }); + }); + }); + + it("Tries to connect default url", function() { + this.timeout(3000); + let man = new Manager({ + url: defaultUrl, + urls: faultyNodeList.map(a => a.url) + }); + return new Promise(function(resolve, reject) { + man + .connect() + .then(resolve) + .catch(reject); + }); + }); + + it("Tries to connect to fallback and updates current url on connection success", function() { + this.timeout(15000); + let man = new Manager({ + url: "ws://127.0.0.1:8092", + urls: faultyNodeList.map(a => a.url) + }); + return new Promise(function(resolve, reject) { + man + .connectWithFallback() + .then(function() { + assert.equal(man.url, "wss://bitshares.openledger.info/ws"); + resolve(); + }) + .catch(reject); + }); + }); + + it("Tries to connect to fallback and can call a callback when falling back to new url", function() { + this.timeout(15000); + let url = "ws://127.0.0.1:8092"; + let callbackCalled = false; + let urlChangeCallback = function(newUrl) { + callbackCalled = !!newUrl; + }; + let man = new Manager({ + url, + urls: faultyNodeList.map(a => a.url), + urlChangeCallback + }); + return new Promise(function(resolve, reject) { + man + .connectWithFallback() + .then(function() { + assert(callbackCalled); + resolve(); + }) + .catch(reject); + }); + }); + + it("Rejects if no connections are successful ", function() { + this.timeout(15000); + let man = new Manager({ + url: "ws://127.0.0.1:8092", + urls: noWorkingNodes.map(a => a.url) + }); + return new Promise(function(resolve, reject) { + man + .connectWithFallback() + .then(reject) + .catch(resolve); + }); + }); + + it("Can automatically fallback when closed", function() { + this.timeout(20000); + let man = new Manager({ + url: "wss://eu.nodes.bitshares.ws", + urls: [ + "wss://eu.nodes.bitshares.ws", + "wss://bitshares.openledger.info/ws" + ], + autoFallback: true + }); + + return new Promise(function(resolve, reject) { + man.connectWithFallback().then(function() { + // Assign faulty url to simulate faulty connection + man.url = faultyNodeList[0].url; + Apis.instance().ws_rpc.ws.close(); + setTimeout(function() { + if (man.isConnected) { + resolve(); + /* Set autoFallback to false here to prevent permanent reconnections*/ + man.autoFallback = false; + } else reject(); + }, 2000); + }); + }); + }); + + it("Can call a fallbackCb when closed", function() { + this.timeout(20000); + return new Promise(function(resolve, reject) { + let man = new Manager({ + url: "wss://eu.nodes.bitshares.ws", + urls: [ + "wss://eu.nodes.bitshares.ws", + "wss://eu.openledger.info/ws" + ], + closeCb: function() { + resolve(); + } + }); + + man.connectWithFallback().then(function() { + Apis.instance().ws_rpc.ws.close(); + }); + }); + }); + + it("Can check connection times for all connections", function() { + this.timeout(20000); + let man = new Manager({ + url: "ws://127.0.0.1:8090", + urls: fullNodeList.map(a => a.url) + }); + return new Promise(function(resolve, reject) { + man + .checkConnections() + .then(latencies => { + resolve(); + }) + .catch(reject); + }); + }); + + it("Checks connections for url and urls", function() { + this.timeout(20000); + let man = new Manager({ + url: "wss://eu.nodes.bitshares.ws", + urls: ["wss://bts.open.icowallet.net/ws"] + }); + return new Promise(function(resolve, reject) { + man + .checkConnections() + .then(latencies => { + assert.equal(Object.keys(latencies).length, 2); + resolve(); + }) + .catch(reject); + }); + }); + + // it("Throws an error if an API fails to initialize", function() { + // this.timeout(5000); + // let man = new Manager({url: failedInitNodes[0].url, urls: []}); + // return new Promise(function(resolve, reject) { + // man.connect(undefined, undefined, true).then(function(res) { + // reject(); + // }).catch(function(err) { + // resolve(); + // }); + // }); + // }); +}); diff --git a/packages/bitsharesjs-ws/test/README.md b/packages/bitsharesjs-ws/test/README.md new file mode 100644 index 00000000..fca88127 --- /dev/null +++ b/packages/bitsharesjs-ws/test/README.md @@ -0,0 +1,4 @@ +# Tests + +`npm run test` +`npm run test:manager` diff --git a/packages/bitsharesjs-ws/tools/es2015Preset.js b/packages/bitsharesjs-ws/tools/es2015Preset.js new file mode 100644 index 00000000..25859d63 --- /dev/null +++ b/packages/bitsharesjs-ws/tools/es2015Preset.js @@ -0,0 +1,13 @@ +const BABEL_ENV = process.env.BABEL_ENV; + +module.exports = { + presets: [ + [ + "env", + { + loose: true, + modules: BABEL_ENV === "es" ? false : "commonjs" + } + ] + ] +}; diff --git a/packages/ecc/.babelrc b/packages/ecc/.babelrc new file mode 100644 index 00000000..d3d9fc2e --- /dev/null +++ b/packages/ecc/.babelrc @@ -0,0 +1,13 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "targets": { + "browsers": "> 5%", + "node": "10" + } + } + ] + ] +} diff --git a/packages/ecc/.gitignore b/packages/ecc/.gitignore new file mode 100644 index 00000000..5e8f7ef0 --- /dev/null +++ b/packages/ecc/.gitignore @@ -0,0 +1,10 @@ +.npmrc +npm-debug.log +node_modules +cjs +es +*.swp +browser-test/browser-test.js +build +package-lock.json +lib diff --git a/packages/ecc/package.json b/packages/ecc/package.json new file mode 100644 index 00000000..471011ae --- /dev/null +++ b/packages/ecc/package.json @@ -0,0 +1,28 @@ +{ + "name": "ecc", + "version": "1.0.0", + "description": "", + "main": "lib/index.js", + "scripts": { + "build": "babel src -d lib" + }, + "license": "MIT", + "devDependencies": { + "@babel/cli": "^7.2.3", + "@babel/core": "^7.3.3", + "@babel/preset-env": "^7.3.1" + }, + "dependencies": { + "assert": "^1.4.1", + "bigi": "^1.4.2", + "bitsharesjs-ws": "^1.5.5", + "bs58": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "crypto-js": "^3.1.9-1", + "deep-equal": "^1.0.1", + "ecurve": "^1.0.6", + "safe-buffer": "^5.1.2", + "secure-random": "^1.1.1" + } +} diff --git a/packages/ecc/src/BrainKey.js b/packages/ecc/src/BrainKey.js new file mode 100644 index 00000000..a7ead0ec --- /dev/null +++ b/packages/ecc/src/BrainKey.js @@ -0,0 +1,7 @@ +export default function normalize(brainKey) { + if (typeof brainKey !== "string") { + throw new Error("string required for brainKey"); + } + brainKey = brainKey.trim(); + return brainKey.split(/[\t\n\v\f\r ]+/).join(" "); +} diff --git a/packages/ecc/src/KeyUtils.js b/packages/ecc/src/KeyUtils.js new file mode 100644 index 00000000..8c0e931b --- /dev/null +++ b/packages/ecc/src/KeyUtils.js @@ -0,0 +1,225 @@ +import PrivateKey from "./PrivateKey"; +import PublicKey from "./PublicKey"; +import Address from "./address"; +import Aes from "./aes"; +import {sha256, sha512} from "./hash"; +// import dictionary from './dictionary_en'; +import secureRandom from "secure-random"; +import {ChainConfig} from "bitsharesjs-ws"; +const Buffer = require("safe-buffer").Buffer; + +// hash for .25 second +var HASH_POWER_MILLS = 250; + +const key = { + /** Uses 1 second of hashing power to create a key/password checksum. An + implementation can re-call this method with the same password to re-match + the strength of the CPU (either after moving from a desktop to a mobile, + mobile to desktop, or N years from now when CPUs are presumably stronger). + + A salt is used for all the normal reasons... + + @return object { + aes_private: Aes, + checksum: "{hash_iteration_count},{salt},{checksum}" + } + */ + aes_checksum(password) { + if (!(typeof password === "string")) { + throw new "password string required"(); + } + var salt = secureRandom.randomBuffer(4).toString("hex"); + var iterations = 0; + var secret = salt + password; + // hash for .1 second + var start_t = Date.now(); + while (Date.now() - start_t < HASH_POWER_MILLS) { + secret = sha256(secret); + iterations += 1; + } + + var checksum = sha256(secret); + var checksum_string = [ + iterations, + salt.toString("hex"), + checksum.slice(0, 4).toString("hex") + ].join(","); + + return { + aes_private: Aes.fromSeed(secret), + checksum: checksum_string + }; + }, + + /** Provide a matching password and key_checksum. A "wrong password" + error is thrown if the password does not match. If this method takes + much more or less than 1 second to return, one should consider updating + all encyrpted fields using a new key.key_checksum. + */ + aes_private(password, key_checksum) { + var [iterations, salt, checksum] = key_checksum.split(","); + var secret = salt + password; + for ( + var i = 0; + 0 < iterations ? i < iterations : i > iterations; + 0 < iterations ? i++ : i++ + ) { + secret = sha256(secret); + } + var new_checksum = sha256(secret); + if (!(new_checksum.slice(0, 4).toString("hex") === checksum)) { + throw new Error("wrong password"); + } + return Aes.fromSeed(secret); + }, + + /** + A week random number generator can run out of entropy. This should ensure even the worst random number implementation will be reasonably safe. + + @param1 string entropy of at least 32 bytes + */ + random32ByteBuffer(entropy = this.browserEntropy()) { + if (!(typeof entropy === "string")) { + throw new Error("string required for entropy"); + } + + if (entropy.length < 32) { + throw new Error("expecting at least 32 bytes of entropy"); + } + + var start_t = Date.now(); + + while (Date.now() - start_t < HASH_POWER_MILLS) + entropy = sha256(entropy); + + var hash_array = []; + hash_array.push(entropy); + + // Hashing for 1 second may helps the computer is not low on entropy (this method may be called back-to-back). + hash_array.push(secureRandom.randomBuffer(32)); + + return sha256(Buffer.concat(hash_array)); + }, + + suggest_brain_key: function( + dictionary = ",", + entropy = this.browserEntropy() + ) { + var randomBuffer = this.random32ByteBuffer(entropy); + + var word_count = 16; + var dictionary_lines = dictionary.split(","); + + if (!(dictionary_lines.length === 49744)) { + throw new Error( + `expecting ${49744} but got ${ + dictionary_lines.length + } dictionary words` + ); + } + + var brainkey = []; + var end = word_count * 2; + + for (let i = 0; i < end; i += 2) { + // randomBuffer has 256 bits / 16 bits per word == 16 words + var num = (randomBuffer[i] << 8) + randomBuffer[i + 1]; + + // convert into a number between 0 and 1 (inclusive) + var rndMultiplier = num / Math.pow(2, 16); + var wordIndex = Math.round(dictionary_lines.length * rndMultiplier); + + brainkey.push(dictionary_lines[wordIndex]); + } + return this.normalize_brainKey(brainkey.join(" ")); + }, + + get_random_key(entropy) { + return PrivateKey.fromBuffer(this.random32ByteBuffer(entropy)); + }, + + get_brainPrivateKey(brainKey, sequence = 0) { + if (sequence < 0) { + throw new Error("invalid sequence"); + } + if (brainKey.trim() === "") { + throw new Error("empty brain key"); + } + brainKey = key.normalize_brainKey(brainKey); + return PrivateKey.fromBuffer(sha256(sha512(brainKey + " " + sequence))); + }, + + // Turn invisible space like characters into a single space + normalize_brainKey(brainKey) { + if (!(typeof brainKey === "string")) { + throw new Error("string required for brainKey"); + } + + brainKey = brainKey.trim(); + if (brainKey === "") { + throw new Error("empty brain key"); + } + return brainKey.split(/[\t\n\v\f\r ]+/).join(" "); + }, + + browserEntropy() { + var entropyStr = ""; + try { + entropyStr = + new Date().toString() + + " " + + window.screen.height + + " " + + window.screen.width + + " " + + window.screen.colorDepth + + " " + + " " + + window.screen.availHeight + + " " + + window.screen.availWidth + + " " + + window.screen.pixelDepth + + navigator.language + + " " + + window.location + + " " + + window.history.length; + + for (var i = 0, mimeType; i < navigator.mimeTypes.length; i++) { + mimeType = navigator.mimeTypes[i]; + entropyStr += + mimeType.description + + " " + + mimeType.type + + " " + + mimeType.suffixes + + " "; + } + console.log("INFO\tbrowserEntropy gathered"); + } catch (error) { + //nodejs:ReferenceError: window is not defined + entropyStr = sha256(new Date().toString()); + } + + var b = Buffer.from(entropyStr); + entropyStr += b.toString("binary") + " " + new Date().toString(); + return entropyStr; + }, + + // @return array of 5 legacy addresses for a pubkey string parameter. + addresses(pubkey, address_prefix = ChainConfig.address_prefix) { + var public_key = PublicKey.fromPublicKeyString(pubkey, address_prefix); + // S L O W + var address_string = [ + Address.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed + Address.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed + Address.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed + Address.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed + public_key.toAddressString(address_prefix) // bts_short, most recent format + ]; + return address_string; + } +}; + +export default key; diff --git a/packages/ecc/src/PrivateKey.js b/packages/ecc/src/PrivateKey.js new file mode 100644 index 00000000..50df9ddb --- /dev/null +++ b/packages/ecc/src/PrivateKey.js @@ -0,0 +1,180 @@ +import {Point, getCurveByName} from "ecurve"; +import BigInteger from "bigi"; +import {encode, decode} from "bs58"; +import {sha256, sha512} from "./hash"; +import PublicKey from "./PublicKey"; +import deepEqual from "deep-equal"; +import assert from "assert"; + +const secp256k1 = getCurveByName("secp256k1"); +const {n} = secp256k1; +const Buffer = require("safe-buffer").Buffer; + +class PrivateKey { + /** + @private see static functions + @param {BigInteger} + */ + constructor(d) { + this.d = d; + } + + static fromBuffer(buf) { + if (!Buffer.isBuffer(buf)) { + throw new Error("Expecting paramter to be a Buffer type"); + } + if (32 !== buf.length) { + console.log( + `WARN: Expecting 32 bytes, instead got ${ + buf.length + }, stack trace:`, + new Error().stack + ); + } + if (buf.length === 0) { + throw new Error("Empty buffer"); + } + return new PrivateKey(BigInteger.fromBuffer(buf)); + } + + /** @arg {string} seed - any length string. This is private, the same seed produces the same private key every time. */ + static fromSeed(seed) { + // generate_private_key + if (!(typeof seed === "string")) { + throw new Error("seed must be of type string"); + } + return PrivateKey.fromBuffer(sha256(seed)); + } + + /** @return {string} Wallet Import Format (still a secret, Not encrypted) */ + static fromWif(_private_wif) { + var private_wif = Buffer.from(decode(_private_wif)); + var version = private_wif.readUInt8(0); + assert.equal( + 0x80, + version, + `Expected version ${0x80}, instead got ${version}` + ); + // checksum includes the version + var private_key = private_wif.slice(0, -4); + var checksum = private_wif.slice(-4); + var new_checksum = sha256(private_key); + new_checksum = sha256(new_checksum); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + private_key = private_key.slice(1); + return PrivateKey.fromBuffer(private_key); + } + + toWif() { + var private_key = this.toBuffer(); + // checksum includes the version + private_key = Buffer.concat([Buffer.from([0x80]), private_key]); + var checksum = sha256(private_key); + checksum = sha256(checksum); + checksum = checksum.slice(0, 4); + var private_wif = Buffer.concat([private_key, checksum]); + return encode(private_wif); + } + + /** + @return {Point} + */ + toPublicKeyPoint() { + return secp256k1.G.multiply(this.d); + } + + toPublicKey() { + if (this.public_key) { + return this.public_key; + } + return (this.public_key = PublicKey.fromPoint(this.toPublicKeyPoint())); + } + + toBuffer() { + return this.d.toBuffer(32); + } + + /** ECIES */ + get_shared_secret(public_key, legacy = false) { + public_key = toPublic(public_key); + let KB = public_key.toUncompressed().toBuffer(); + let KBP = Point.fromAffine( + secp256k1, + BigInteger.fromBuffer(KB.slice(1, 33)), // x + BigInteger.fromBuffer(KB.slice(33, 65)) // y + ); + let r = this.toBuffer(); + let P = KBP.multiply(BigInteger.fromBuffer(r)); + let S = P.affineX.toBuffer({size: 32}); + /* + the input to sha512 must be exactly 32-bytes, to match the c++ implementation + of get_shared_secret. Right now S will be shorter if the most significant + byte(s) is zero. Pad it back to the full 32-bytes + */ + if (!legacy && S.length < 32) { + let pad = Buffer.alloc(32 - S.length).fill(0); + S = Buffer.concat([pad, S]); + } + + // SHA512 used in ECIES + return sha512(S); + } + + // /** ECIES (does not always match the Point.fromAffine version above) */ + // get_shared_secret(public_key){ + // public_key = toPublic(public_key) + // var P = public_key.Q.multiply( this.d ); + // var S = P.affineX.toBuffer({size: 32}); + // // ECIES, adds an extra sha512 + // return sha512(S); + // } + + /** @throws {Error} - overflow of the key could not be derived */ + child(offset) { + offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]); + offset = sha256(offset); + let c = BigInteger.fromBuffer(offset); + + if (c.compareTo(n) >= 0) + throw new Error("Child offset went out of bounds, try again"); + + let derived = this.d.add(c); //.mod(n) + + if (derived.signum() === 0) + throw new Error( + "Child offset derived to an invalid key, try again" + ); + + return new PrivateKey(derived); + } + + /* */ + + toByteBuffer() { + var b = new ByteBuffer( + ByteBuffer.DEFAULT_CAPACITY, + ByteBuffer.LITTLE_ENDIAN + ); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + + static fromHex(hex) { + return PrivateKey.fromBuffer(new Buffer(hex, "hex")); + } + + toHex() { + return this.toBuffer().toString("hex"); + } + + /* */ +} + +export default PrivateKey; + +let toPublic = data => + data == null ? data : data.Q ? data : PublicKey.fromStringOrThrow(data); diff --git a/packages/ecc/src/PublicKey.js b/packages/ecc/src/PublicKey.js new file mode 100644 index 00000000..767b97f8 --- /dev/null +++ b/packages/ecc/src/PublicKey.js @@ -0,0 +1,193 @@ +import BigInteger from "bigi"; +import {Point, getCurveByName} from "ecurve"; +const secp256k1 = getCurveByName("secp256k1"); +import {encode, decode} from "bs58"; +import {sha256, sha512, ripemd160} from "./hash"; +import {ChainConfig} from "bitsharesjs-ws"; +import assert from "assert"; +import deepEqual from "deep-equal"; +const Buffer = require("safe-buffer").Buffer; +const {G, n} = secp256k1; + +class PublicKey { + /** @param {Point} public key */ + constructor(Q) { + this.Q = Q; + } + + static fromBinary(bin) { + return PublicKey.fromBuffer(Buffer.from(bin, "binary")); + } + + static fromBuffer(buffer) { + if ( + buffer.toString("hex") === + "000000000000000000000000000000000000000000000000000000000000000000" + ) + return new PublicKey(null); + return new PublicKey(Point.decodeFrom(secp256k1, buffer)); + } + + toBuffer(compressed = this.Q ? this.Q.compressed : null) { + if (this.Q === null) + return Buffer.from( + "000000000000000000000000000000000000000000000000000000000000000000", + "hex" + ); + return this.Q.getEncoded(compressed); + } + + static fromPoint(point) { + return new PublicKey(point); + } + + toUncompressed() { + var buf = this.Q.getEncoded(false); + var point = Point.decodeFrom(secp256k1, buf); + return PublicKey.fromPoint(point); + } + + /** bts::blockchain::address (unique but not a full public key) */ + toBlockchainAddress() { + var pub_buf = this.toBuffer(); + var pub_sha = sha512(pub_buf); + return ripemd160(pub_sha); + } + + /** Alias for {@link toPublicKeyString} */ + toString(address_prefix = ChainConfig.address_prefix) { + return this.toPublicKeyString(address_prefix); + } + + /** + Full public key + {return} string + */ + toPublicKeyString(address_prefix = ChainConfig.address_prefix) { + var pub_buf = this.toBuffer(); + var checksum = ripemd160(pub_buf); + var addy = Buffer.concat([pub_buf, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } + + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @return PublicKey or `null` (if the public_key string is invalid) + */ + static fromPublicKeyString( + public_key, + address_prefix = ChainConfig.address_prefix + ) { + try { + return PublicKey.fromStringOrThrow(public_key, address_prefix); + } catch (e) { + return null; + } + } + + /** + @arg {string} public_key - like GPHXyz... + @arg {string} address_prefix - like GPH + @throws {Error} if public key is invalid + @return PublicKey + */ + static fromStringOrThrow( + public_key, + address_prefix = ChainConfig.address_prefix + ) { + if (public_key.Q === null) + public_key = + address_prefix + "1111111111111111111111111111111114T1Anm"; // null key + var prefix = public_key.slice(0, address_prefix.length); + assert.equal( + address_prefix, + prefix, + `Expecting key to begin with ${address_prefix}, instead got ${prefix}` + ); + public_key = public_key.slice(address_prefix.length); + + public_key = Buffer.from(decode(public_key), "binary"); + var checksum = public_key.slice(-4); + public_key = public_key.slice(0, -4); + var new_checksum = ripemd160(public_key); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + return PublicKey.fromBuffer(public_key); + } + + toAddressString(address_prefix = ChainConfig.address_prefix) { + var pub_buf = this.toBuffer(); + var pub_sha = sha512(pub_buf); + var addy = ripemd160(pub_sha); + var checksum = ripemd160(addy); + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } + + toPtsAddy() { + var pub_buf = this.toBuffer(); + var pub_sha = sha256(pub_buf); + var addy = ripemd160(pub_sha); + addy = Buffer.concat([Buffer.from([0x38]), addy]); //version 56(decimal) + + var checksum = sha256(addy); + checksum = sha256(checksum); + + addy = Buffer.concat([addy, checksum.slice(0, 4)]); + return encode(addy); + } + + child(offset) { + assert(Buffer.isBuffer(offset), "Buffer required: offset"); + assert.equal(offset.length, 32, "offset length"); + + offset = Buffer.concat([this.toBuffer(), offset]); + offset = sha256(offset); + + let c = BigInteger.fromBuffer(offset); + + if (c.compareTo(n) >= 0) + throw new Error("Child offset went out of bounds, try again"); + + let cG = G.multiply(c); + let Qprime = this.Q.add(cG); + + if (secp256k1.isInfinity(Qprime)) + throw new Error( + "Child offset derived to an invalid key, try again" + ); + + return PublicKey.fromPoint(Qprime); + } + + /* */ + + toByteBuffer() { + var b = new ByteBuffer( + ByteBuffer.DEFAULT_CAPACITY, + ByteBuffer.LITTLE_ENDIAN + ); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + + static fromHex(hex) { + return PublicKey.fromBuffer(Buffer.from(hex, "hex")); + } + + toHex() { + return this.toBuffer().toString("hex"); + } + + static fromPublicKeyStringHex(hex) { + return PublicKey.fromPublicKeyString(Buffer.from(hex, "hex")); + } + + /* */ +} + +export default PublicKey; diff --git a/packages/ecc/src/address.js b/packages/ecc/src/address.js new file mode 100644 index 00000000..81c4e357 --- /dev/null +++ b/packages/ecc/src/address.js @@ -0,0 +1,65 @@ +import assert from "assert"; +import {ChainConfig} from "bitsharesjs-ws"; +import {sha256, sha512, ripemd160} from "./hash"; +import {encode, decode} from "bs58"; +import deepEqual from "deep-equal"; +const Buffer = require("safe-buffer").Buffer; + +/** Addresses are shortened non-reversable hashes of a public key. The full PublicKey is preferred. + */ +class Address { + constructor(addy) { + this.addy = addy; + } + + static fromBuffer(buffer) { + var _hash = sha512(buffer); + var addy = ripemd160(_hash); + return new Address(addy); + } + + static fromString(string, address_prefix = ChainConfig.address_prefix) { + var prefix = string.slice(0, address_prefix.length); + assert.equal( + address_prefix, + prefix, + `Expecting key to begin with ${address_prefix}, instead got ${prefix}` + ); + var addy = string.slice(address_prefix.length); + addy = new Buffer(decode(addy), "binary"); + var checksum = addy.slice(-4); + addy = addy.slice(0, -4); + var new_checksum = ripemd160(addy); + new_checksum = new_checksum.slice(0, 4); + var isEqual = deepEqual(checksum, new_checksum); //, 'Invalid checksum' + if (!isEqual) { + throw new Error("Checksum did not match"); + } + return new Address(addy); + } + + /** @return Address - Compressed PTS format (by default) */ + static fromPublic(public_key, compressed = true, version = 56) { + var sha2 = sha256(public_key.toBuffer(compressed)); + var rep = ripemd160(sha2); + var versionBuffer = Buffer.alloc(1); + versionBuffer.writeUInt8(0xff & version, 0); + var addr = Buffer.concat([versionBuffer, rep]); + var check = sha256(addr); + check = sha256(check); + var buffer = Buffer.concat([addr, check.slice(0, 4)]); + return new Address(ripemd160(buffer)); + } + + toBuffer() { + return this.addy; + } + + toString(address_prefix = ChainConfig.address_prefix) { + var checksum = ripemd160(this.addy); + var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]); + return address_prefix + encode(addy); + } +} + +export default Address; diff --git a/packages/ecc/src/aes.js b/packages/ecc/src/aes.js new file mode 100644 index 00000000..a6510a9b --- /dev/null +++ b/packages/ecc/src/aes.js @@ -0,0 +1,272 @@ +// https://code.google.com/p/crypto-js +import AES from "crypto-js/aes"; +import encHex from "crypto-js/enc-hex"; +import encBase64 from "crypto-js/enc-base64"; +import assert from "assert"; +import {sha256, sha512} from "./hash"; +const Buffer = require("safe-buffer").Buffer; + +/** Provides symetric encrypt and decrypt via AES. */ +class Aes { + /** @private */ + constructor(iv, key) { + (this.iv = iv), (this.key = key); + } + + /** This is an excellent way to ensure that all references to Aes can not operate anymore (example: a wallet becomes locked). An application should ensure there is only one Aes object instance for a given secret `seed`. */ + clear() { + return (this.iv = this.key = undefined); + } + + /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */ + static fromSeed(seed) { + if (seed === undefined) { + throw new Error("seed is required"); + } + var _hash = sha512(seed); + _hash = _hash.toString("hex"); + // DEBUG console.log('... fromSeed _hash',_hash) + return Aes.fromSha512(_hash); + } + + /** @arg {string} hash - A 128 byte hex string, typically one would call {@link fromSeed} instead. */ + static fromSha512(hash) { + assert.equal( + hash.length, + 128, + `A Sha512 in HEX should be 128 characters long, instead got ${ + hash.length + }` + ); + var iv = encHex.parse(hash.substring(64, 96)); + var key = encHex.parse(hash.substring(0, 64)); + return new Aes(iv, key); + } + + static fromBuffer(buf) { + assert(Buffer.isBuffer(buf), "Expecting Buffer"); + assert.equal( + buf.length, + 64, + `A Sha512 Buffer should be 64 characters long, instead got ${ + buf.length + }` + ); + return Aes.fromSha512(buf.toString("hex")); + } + /** + @throws {Error} - "Invalid Key, ..." + @arg {PrivateKey} private_key - required and used for decryption + @arg {PublicKey} public_key - required and used to calcualte the shared secret + @arg {string} [nonce = ""] optional but should always be provided and be unique when re-using the same private/public keys more than once. This nonce is not a secret. + @arg {string|Buffer} message - Encrypted message containing a checksum + @return {Buffer} + */ + static decrypt_with_checksum( + private_key, + public_key, + nonce, + message, + legacy = false + ) { + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string + if (nonce == null) + // null or undefined + nonce = ""; + + if (!Buffer.isBuffer(message)) { + message = new Buffer(message, "hex"); + } + + var S = private_key.get_shared_secret(public_key, legacy); + // D E B U G + // console.log('decrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString(), + // pub: public_key.toPublicKeyString(), + // nonce: nonce, + // message: message.length, + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed( + Buffer.concat([ + // A null or empty string nonce will not effect the hash + Buffer.from("" + nonce), + Buffer.from(S.toString("hex")) + ]) + ); + + var planebuffer = aes.decrypt(message); + if (!(planebuffer.length >= 4)) { + throw new Error("Invalid key, could not decrypt message(1)"); + } + + // DEBUG console.log('... planebuffer',planebuffer) + var checksum = planebuffer.slice(0, 4); + var plaintext = planebuffer.slice(4); + + // console.log('... checksum',checksum.toString('hex')) + // console.log('... plaintext',plaintext.toString()) + + var new_checksum = sha256(plaintext); + new_checksum = new_checksum.slice(0, 4); + new_checksum = new_checksum.toString("hex"); + + if (!(checksum.toString("hex") === new_checksum)) { + throw new Error("Invalid key, could not decrypt message(2)"); + } + + return plaintext; + } + + /** Identical to {@link decrypt_with_checksum} but used to encrypt. Should not throw an error. + @return {Buffer} message - Encrypted message which includes a checksum + */ + static encrypt_with_checksum(private_key, public_key, nonce, message) { + // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string + + if (nonce == null) + // null or undefined + nonce = ""; + + if (!Buffer.isBuffer(message)) { + message = new Buffer(message, "binary"); + } + + var S = private_key.get_shared_secret(public_key); + + // D E B U G + // console.log('encrypt_with_checksum', { + // priv_to_pub: private_key.toPublicKey().toString() + // pub: public_key.toPublicKeyString() + // nonce: nonce + // message: message.length + // S: S.toString('hex') + // }) + + var aes = Aes.fromSeed( + Buffer.concat([ + // A null or empty string nonce will not effect the hash + Buffer.from("" + nonce), + Buffer.from(S.toString("hex")) + ]) + ); + // DEBUG console.log('... S',S.toString('hex')) + var checksum = sha256(message).slice(0, 4); + var payload = Buffer.concat([checksum, message]); + // DEBUG console.log('... payload',payload.toString()) + return aes.encrypt(payload); + } + + /** @private */ + _decrypt_word_array(cipher) { + // https://code.google.com/p/crypto-js/#Custom_Key_and_IV + // see wallet_records.cpp master_key::decrypt_key + return AES.decrypt({ciphertext: cipher, salt: null}, this.key, { + iv: this.iv + }); + } + + /** @private */ + _encrypt_word_array(plaintext) { + //https://code.google.com/p/crypto-js/issues/detail?id=85 + var cipher = AES.encrypt(plaintext, this.key, {iv: this.iv}); + return encBase64.parse(cipher.toString()); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} ciphertext + @return {Buffer} binary + */ + decrypt(ciphertext) { + if (typeof ciphertext === "string") { + ciphertext = new Buffer(ciphertext, "binary"); + } + if (!Buffer.isBuffer(ciphertext)) { + throw new Error("buffer required"); + } + assert(ciphertext, "Missing cipher text"); + // hex is the only common format + var hex = this.decryptHex(ciphertext.toString("hex")); + return new Buffer(hex, "hex"); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plaintext + @return {Buffer} binary + */ + encrypt(plaintext) { + if (typeof plaintext === "string") { + plaintext = new Buffer(plaintext, "binary"); + } + if (!Buffer.isBuffer(plaintext)) { + throw new Error("buffer required"); + } + //assert plaintext, "Missing plain text" + // hex is the only common format + var hex = this.encryptHex(plaintext.toString("hex")); + return new Buffer(hex, "hex"); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string|Buffer} plaintext + @return {string} hex + */ + encryptToHex(plaintext) { + if (typeof plaintext === "string") { + plaintext = new Buffer(plaintext, "binary"); + } + if (!Buffer.isBuffer(plaintext)) { + throw new Error("buffer required"); + } + //assert plaintext, "Missing plain text" + // hex is the only common format + return this.encryptHex(plaintext.toString("hex")); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {string} binary (could easily be readable text) + */ + decryptHex(cipher) { + assert(cipher, "Missing cipher text"); + // Convert data into word arrays (used by Crypto) + var cipher_array = encHex.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + return encHex.stringify(plainwords); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @return {Buffer} encoded as specified by the parameter + */ + decryptHexToBuffer(cipher) { + assert(cipher, "Missing cipher text"); + // Convert data into word arrays (used by Crypto) + var cipher_array = encHex.parse(cipher); + var plainwords = this._decrypt_word_array(cipher_array); + var plainhex = encHex.stringify(plainwords); + return new Buffer(plainhex, "hex"); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} cipher - hex + @arg {string} [encoding = 'binary'] - a valid Buffer encoding + @return {String} encoded as specified by the parameter + */ + decryptHexToText(cipher, encoding = "binary") { + return this.decryptHexToBuffer(cipher).toString(encoding); + } + + /** This method does not use a checksum, the returned data must be validated some other way. + @arg {string} plainhex - hex format + @return {String} hex + */ + encryptHex(plainhex) { + var plain_array = encHex.parse(plainhex); + var cipher_array = this._encrypt_word_array(plain_array); + return encHex.stringify(cipher_array); + } +} + +export default Aes; diff --git a/packages/ecc/src/ecdsa.js b/packages/ecc/src/ecdsa.js new file mode 100644 index 00000000..872804a8 --- /dev/null +++ b/packages/ecc/src/ecdsa.js @@ -0,0 +1,226 @@ +import assert from "assert"; // from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa +import {sha256, HmacSHA256} from "./hash"; +import enforceType from "./enforce_types"; + +import BigInteger from "bigi"; +import ECSignature from "./ecsignature"; +const Buffer = require("safe-buffer").Buffer; + +// https://tools.ietf.org/html/rfc6979#section-3.2 +function deterministicGenerateK(curve, hash, d, checkSig, nonce) { + enforceType("Buffer", hash); + enforceType(BigInteger, d); + + if (nonce) { + hash = sha256(Buffer.concat([hash, Buffer.alloc(nonce)])); + } + + // sanity check + assert.equal(hash.length, 32, "Hash must be 256 bit"); + + var x = d.toBuffer(32); + var k = Buffer.alloc(32); + var v = Buffer.alloc(32); + + // Step B + v.fill(1); + + // Step C + k.fill(0); + + // Step D + k = HmacSHA256(Buffer.concat([v, new Buffer([0]), x, hash]), k); + + // Step E + v = HmacSHA256(v, k); + + // Step F + k = HmacSHA256(Buffer.concat([v, new Buffer([1]), x, hash]), k); + + // Step G + v = HmacSHA256(v, k); + + // Step H1/H2a, ignored as tlen === qlen (256 bit) + // Step H2b + v = HmacSHA256(v, k); + + var T = BigInteger.fromBuffer(v); + + // Step H3, repeat until T is within the interval [1, n - 1] + while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) { + k = HmacSHA256(Buffer.concat([v, new Buffer([0])]), k); + v = HmacSHA256(v, k); + + // Step H1/H2a, again, ignored as tlen === qlen (256 bit) + // Step H2b again + v = HmacSHA256(v, k); + + T = BigInteger.fromBuffer(v); + } + + return T; +} + +function sign(curve, hash, d, nonce) { + const e = BigInteger.fromBuffer(hash); + const n = curve.n; + const G = curve.G; + + let r, s; + + deterministicGenerateK( + curve, + hash, + d, + function(k) { + // find canonically valid signature + let Q = G.multiply(k); + + if (curve.isInfinity(Q)) return false; + + r = Q.affineX.mod(n); + if (r.signum() === 0) return false; + + s = k + .modInverse(n) + .multiply(e.add(d.multiply(r))) + .mod(n); + if (s.signum() === 0) return false; + + return true; + }, + nonce + ); + + let N_OVER_TWO = n.shiftRight(1); + + // enforce low S values, see bip62: 'low s values in signatures' + if (s.compareTo(N_OVER_TWO) > 0) { + s = n.subtract(s); + } + + return new ECSignature(r, s); +} + +function verifyRaw(curve, e, signature, Q) { + var n = curve.n; + var G = curve.G; + + var r = signature.r; + var s = signature.s; + + // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] + if (r.signum() <= 0 || r.compareTo(n) >= 0) return false; + if (s.signum() <= 0 || s.compareTo(n) >= 0) return false; + + // c = s^-1 mod n + var c = s.modInverse(n); + + // 1.4.4 Compute u1 = es^−1 mod n + // u2 = rs^−1 mod n + var u1 = e.multiply(c).mod(n); + var u2 = r.multiply(c).mod(n); + + // 1.4.5 Compute R = (xR, yR) = u1G + u2Q + var R = G.multiplyTwo(u1, Q, u2); + + // 1.4.5 (cont.) Enforce R is not at infinity + if (curve.isInfinity(R)) return false; + + // 1.4.6 Convert the field element R.x to an integer + var xR = R.affineX; + + // 1.4.7 Set v = xR mod n + var v = xR.mod(n); + + // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" + return v.equals(r); +} + +function verify(curve, hash, signature, Q) { + // 1.4.2 H = Hash(M), already done by the user + // 1.4.3 e = H + var e = BigInteger.fromBuffer(hash); + return verifyRaw(curve, e, signature, Q); +} + +/** + * Recover a public key from a signature. + * + * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public + * Key Recovery Operation". + * + * http://www.secg.org/download/aid-780/sec1-v2.pdf + */ +function recoverPubKey(curve, e, signature, i) { + assert.strictEqual(i & 3, i, "Recovery param is more than two bits"); + + var n = curve.n; + var G = curve.G; + + var r = signature.r; + var s = signature.s; + + assert(r.signum() > 0 && r.compareTo(n) < 0, "Invalid r value"); + assert(s.signum() > 0 && s.compareTo(n) < 0, "Invalid s value"); + + // A set LSB signifies that the y-coordinate is odd + var isYOdd = i & 1; + + // The more significant bit specifies whether we should use the + // first or second candidate key. + var isSecondKey = i >> 1; + + // 1.1 Let x = r + jn + var x = isSecondKey ? r.add(n) : r; + var R = curve.pointFromX(isYOdd, x); + + // 1.4 Check that nR is at infinity + var nR = R.multiply(n); + assert(curve.isInfinity(nR), "nR is not a valid curve point"); + + // Compute -e from e + var eNeg = e.negate().mod(n); + + // 1.6.1 Compute Q = r^-1 (sR - eG) + // Q = r^-1 (sR + -eG) + var rInv = r.modInverse(n); + + var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv); + curve.validate(Q); + + return Q; +} + +/** + * Calculate pubkey extraction parameter. + * + * When extracting a pubkey from a signature, we have to + * distinguish four different cases. Rather than putting this + * burden on the verifier, Bitcoin includes a 2-bit value with the + * signature. + * + * This function simply tries all four cases and returns the value + * that resulted in a successful pubkey recovery. + */ +function calcPubKeyRecoveryParam(curve, e, signature, Q) { + for (var i = 0; i < 4; i++) { + var Qprime = recoverPubKey(curve, e, signature, i); + + // 1.6.2 Verify Q + if (Qprime.equals(Q)) { + return i; + } + } + + throw new Error("Unable to find valid recovery factor"); +} + +export { + calcPubKeyRecoveryParam, + deterministicGenerateK, + recoverPubKey, + sign, + verify, + verifyRaw +}; diff --git a/packages/ecc/src/ecsignature.js b/packages/ecc/src/ecsignature.js new file mode 100644 index 00000000..a683ab78 --- /dev/null +++ b/packages/ecc/src/ecsignature.js @@ -0,0 +1,130 @@ +import assert from "assert"; // from https://github.com/bitcoinjs/bitcoinjs-lib +import enforceType from "./enforce_types"; +import BigInteger from "bigi"; +const Buffer = require("safe-buffer").Buffer; + +function ECSignature(r, s) { + enforceType(BigInteger, r); + enforceType(BigInteger, s); + + this.r = r; + this.s = s; +} + +// Import operations +ECSignature.parseCompact = function(buffer) { + assert.equal(buffer.length, 65, "Invalid signature length"); + var i = buffer.readUInt8(0) - 27; + + // At most 3 bits + assert.equal(i, i & 7, "Invalid signature parameter"); + var compressed = !!(i & 4); + + // Recovery param only + i = i & 3; + + var r = BigInteger.fromBuffer(buffer.slice(1, 33)); + var s = BigInteger.fromBuffer(buffer.slice(33)); + + return { + compressed: compressed, + i: i, + signature: new ECSignature(r, s) + }; +}; + +ECSignature.fromDER = function(buffer) { + assert.equal(buffer.readUInt8(0), 0x30, "Not a DER sequence"); + assert.equal( + buffer.readUInt8(1), + buffer.length - 2, + "Invalid sequence length" + ); + assert.equal(buffer.readUInt8(2), 0x02, "Expected a DER integer"); + + var rLen = buffer.readUInt8(3); + assert(rLen > 0, "R length is zero"); + + var offset = 4 + rLen; + assert.equal(buffer.readUInt8(offset), 0x02, "Expected a DER integer (2)"); + + var sLen = buffer.readUInt8(offset + 1); + assert(sLen > 0, "S length is zero"); + + var rB = buffer.slice(4, offset); + var sB = buffer.slice(offset + 2); + offset += 2 + sLen; + + if (rLen > 1 && rB.readUInt8(0) === 0x00) { + assert(rB.readUInt8(1) & 0x80, "R value excessively padded"); + } + + if (sLen > 1 && sB.readUInt8(0) === 0x00) { + assert(sB.readUInt8(1) & 0x80, "S value excessively padded"); + } + + assert.equal(offset, buffer.length, "Invalid DER encoding"); + var r = BigInteger.fromDERInteger(rB); + var s = BigInteger.fromDERInteger(sB); + + assert(r.signum() >= 0, "R value is negative"); + assert(s.signum() >= 0, "S value is negative"); + + return new ECSignature(r, s); +}; + +// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, importing Transaction causes a circular dependency +ECSignature.parseScriptSignature = function(buffer) { + var hashType = buffer.readUInt8(buffer.length - 1); + var hashTypeMod = hashType & ~0x80; + + assert(hashTypeMod > 0x00 && hashTypeMod < 0x04, "Invalid hashType"); + + return { + signature: ECSignature.fromDER(buffer.slice(0, -1)), + hashType: hashType + }; +}; + +// Export operations +ECSignature.prototype.toCompact = function(i, compressed) { + if (compressed) i += 4; + i += 27; + + var buffer = Buffer.alloc(65); + buffer.writeUInt8(i, 0); + + this.r.toBuffer(32).copy(buffer, 1); + this.s.toBuffer(32).copy(buffer, 33); + + return buffer; +}; + +ECSignature.prototype.toDER = function() { + var rBa = this.r.toDERInteger(); + var sBa = this.s.toDERInteger(); + + var sequence = []; + + // INTEGER + sequence.push(0x02, rBa.length); + sequence = sequence.concat(rBa); + + // INTEGER + sequence.push(0x02, sBa.length); + sequence = sequence.concat(sBa); + + // SEQUENCE + sequence.unshift(0x30, sequence.length); + + return Buffer.from(sequence); +}; + +ECSignature.prototype.toScriptSignature = function(hashType) { + var hashTypeBuffer = Buffer.alloc(1); + hashTypeBuffer.writeUInt8(hashType, 0); + + return Buffer.concat([this.toDER(), hashTypeBuffer]); +}; + +export default ECSignature; diff --git a/packages/ecc/src/enforce_types.js b/packages/ecc/src/enforce_types.js new file mode 100644 index 00000000..dfeeba7b --- /dev/null +++ b/packages/ecc/src/enforce_types.js @@ -0,0 +1,43 @@ +export default function enforce(type, value) { + // Copied from https://github.com/bitcoinjs/bitcoinjs-lib + switch (type) { + case "Array": { + if (Array.isArray(value)) return; + break; + } + + case "Boolean": { + if (typeof value === "boolean") return; + break; + } + + case "Buffer": { + if (Buffer.isBuffer(value)) return; + break; + } + + case "Number": { + if (typeof value === "number") return; + break; + } + + case "String": { + if (typeof value === "string") return; + break; + } + + default: { + if (getName(value.constructor) === getName(type)) return; + } + } + + throw new TypeError( + "Expected " + (getName(type) || type) + ", got " + value + ); +} + +function getName(fn) { + // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property + var match = fn.toString().match(/function (.*?)\(/); + return match ? match[1] : null; +} diff --git a/packages/ecc/src/hash.js b/packages/ecc/src/hash.js new file mode 100644 index 00000000..ce674d8f --- /dev/null +++ b/packages/ecc/src/hash.js @@ -0,0 +1,59 @@ +import createHash from "create-hash"; +import createHmac from "create-hmac"; + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha1(data, encoding) { + return createHash("sha1") + .update(data) + .digest(encoding); +} + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha256(data, encoding) { + return createHash("sha256") + .update(data) + .digest(encoding); +} + +/** @arg {string|Buffer} data + @arg {string} [digest = null] - 'hex', 'binary' or 'base64' + @return {string|Buffer} - Buffer when digest is null, or string +*/ +function sha512(data, encoding) { + return createHash("sha512") + .update(data) + .digest(encoding); +} + +function HmacSHA256(buffer, secret) { + return createHmac("sha256", secret) + .update(buffer) + .digest(); +} + +function ripemd160(data) { + return createHash("rmd160") + .update(data) + .digest(); +} + +// function hash160(buffer) { +// return ripemd160(sha256(buffer)) +// } +// +// function hash256(buffer) { +// return sha256(sha256(buffer)) +// } + +// +// function HmacSHA512(buffer, secret) { +// return crypto.createHmac('sha512', secret).update(buffer).digest() +// } + +export {sha1, sha256, sha512, HmacSHA256, ripemd160}; diff --git a/packages/ecc/src/index.js b/packages/ecc/src/index.js new file mode 100644 index 00000000..001ad8fc --- /dev/null +++ b/packages/ecc/src/index.js @@ -0,0 +1,10 @@ +import Address from "./address"; +import Aes from "./aes"; +import PrivateKey from "./PrivateKey"; +import PublicKey from "./PublicKey"; +import Signature from "./signature"; +import brainKey from "./BrainKey"; +import * as hash from "./hash"; +import key from "./KeyUtils"; + +export {Address, Aes, PrivateKey, PublicKey, Signature, brainKey, hash, key}; diff --git a/packages/ecc/src/signature.js b/packages/ecc/src/signature.js new file mode 100644 index 00000000..558203d2 --- /dev/null +++ b/packages/ecc/src/signature.js @@ -0,0 +1,167 @@ +import {sign, recoverPubKey, verify, calcPubKeyRecoveryParam} from "./ecdsa"; +import {sha256} from "./hash"; +import {getCurveByName} from "ecurve"; +var secp256k1 = getCurveByName("secp256k1"); +import assert from "assert"; +import BigInteger from "bigi"; +import PublicKey from "./PublicKey"; +const Buffer = require("safe-buffer").Buffer; + +class Signature { + constructor(r1, s1, i1) { + this.r = r1; + this.s = s1; + this.i = i1; + assert.equal(this.r != null, true, "Missing parameter"); + assert.equal(this.s != null, true, "Missing parameter"); + assert.equal(this.i != null, true, "Missing parameter"); + } + + static fromBuffer(buf) { + var i, r, s; + assert.equal(buf.length, 65, "Invalid signature length"); + i = buf.readUInt8(0); + assert.equal(i - 27, (i - 27) & 7, "Invalid signature parameter"); + r = BigInteger.fromBuffer(buf.slice(1, 33)); + s = BigInteger.fromBuffer(buf.slice(33)); + return new Signature(r, s, i); + } + + toBuffer() { + var buf; + buf = Buffer.alloc(65); + buf.writeUInt8(this.i, 0); + this.r.toBuffer(32).copy(buf, 1); + this.s.toBuffer(32).copy(buf, 33); + return buf; + } + + recoverPublicKeyFromBuffer(buffer) { + return this.recoverPublicKey(sha256(buffer)); + } + + /** + @return {PublicKey} + */ + recoverPublicKey(sha256_buffer) { + let Q, e, i; + e = BigInteger.fromBuffer(sha256_buffer); + i = this.i; + i -= 27; + i = i & 3; + Q = recoverPubKey(secp256k1, e, this, i); + return PublicKey.fromPoint(Q); + } + + /** + @param {Buffer} buf + @param {PrivateKey} private_key + @return {Signature} + */ + static signBuffer(buf, private_key) { + var _hash = sha256(buf); + return Signature.signBufferSha256(_hash, private_key); + } + + /** Sign a buffer of exactally 32 bytes in size (sha256(text)) + @param {Buffer} buf - 32 bytes binary + @param {PrivateKey} private_key + @return {Signature} + */ + static signBufferSha256(buf_sha256, private_key) { + if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) + throw new Error("buf_sha256: 32 byte buffer requred"); + var der, e, ecsignature, i, lenR, lenS, nonce; + i = null; + nonce = 0; + e = BigInteger.fromBuffer(buf_sha256); + while (true) { + ecsignature = sign(secp256k1, buf_sha256, private_key.d, nonce++); + der = ecsignature.toDER(); + lenR = der[3]; + lenS = der[5 + lenR]; + if (lenR === 32 && lenS === 32) { + i = calcPubKeyRecoveryParam( + secp256k1, + e, + ecsignature, + private_key.toPublicKey().Q + ); + i += 4; // compressed + i += 27; // compact // 24 or 27 :( forcing odd-y 2nd key candidate) + break; + } + if (nonce % 10 === 0) { + console.log( + "WARN: " + nonce + " attempts to find canonical signature" + ); + } + } + return new Signature(ecsignature.r, ecsignature.s, i); + } + + static sign(string, private_key) { + return Signature.signBuffer(Buffer.from(string), private_key); + } + + /** + @param {Buffer} un-hashed + @param {./PublicKey} + @return {boolean} + */ + verifyBuffer(buf, public_key) { + var _hash = sha256(buf); + return this.verifyHash(_hash, public_key); + } + + verifyHash(hash, public_key) { + assert.equal( + hash.length, + 32, + "A SHA 256 should be 32 bytes long, instead got " + hash.length + ); + return verify( + secp256k1, + hash, + { + r: this.r, + s: this.s + }, + public_key.Q + ); + } + + /* */ + + toByteBuffer() { + var b; + b = new ByteBuffer( + ByteBuffer.DEFAULT_CAPACITY, + ByteBuffer.LITTLE_ENDIAN + ); + this.appendByteBuffer(b); + return b.copy(0, b.offset); + } + + static fromHex(hex) { + return Signature.fromBuffer(Buffer.from(hex, "hex")); + } + + toHex() { + return this.toBuffer().toString("hex"); + } + + static signHex(hex, private_key) { + var buf; + buf = Buffer.from(hex, "hex"); + return Signature.signBuffer(buf, private_key); + } + + verifyHex(hex, public_key) { + var buf; + buf = Buffer.from(hex, "hex"); + return this.verifyBuffer(buf, public_key); + } +} + +export default Signature;