UNPKG

22.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const client_common_1 = require("@neo-one/client-common");
5const node_core_1 = require("@neo-one/node-core");
6const utils_1 = require("@neo-one/utils");
7const bignumber_js_1 = tslib_1.__importDefault(require("bignumber.js"));
8const lodash_1 = tslib_1.__importDefault(require("lodash"));
9const common_1 = require("./common");
10const context_1 = require("./context");
11const createMinerTransaction = async ({ node, feeAddress, transactions, nonce, }) => {
12 const networkFee = await node_core_1.Block.calculateNetworkFee(node.blockchain.feeContext, transactions);
13 const outputs = networkFee.isZero()
14 ? []
15 : [
16 new node_core_1.Output({
17 asset: node.blockchain.settings.utilityToken.hash,
18 value: networkFee,
19 address: feeAddress,
20 }),
21 ];
22 return new node_core_1.MinerTransaction({
23 nonce: nonce.mod(node_core_1.utils.UINT_MAX.addn(1)).toNumber(),
24 outputs,
25 });
26};
27const requestChangeView = ({ context: contextIn, node, privateKey, consensusContext, }) => {
28 let context = contextIn;
29 context = context.cloneExpectedView({
30 expectedView: common_1.incrementExpectedView(context),
31 });
32 common_1.signAndRelayChangeView({ context, node, privateKey });
33 const viewNumber = context.expectedView[context.myIndex];
34 if (common_1.checkExpectedView({ context, viewNumber })) {
35 return common_1.initializeConsensusInitial({
36 blockchain: node.blockchain,
37 context,
38 viewNumber,
39 consensusContext,
40 });
41 }
42 const { secondsPerBlock } = node.blockchain.settings;
43 return {
44 context,
45 // tslint:disable-next-line no-bitwise
46 timerSeconds: secondsPerBlock << (viewNumber + 1),
47 };
48};
49exports.runConsensus = async ({ context, node, options: { privateKey, feeAddress, privateNet }, consensusContext, }) => {
50 if (context.type === 'primary' && !(context instanceof context_1.RequestSentContext)) {
51 let requestSentContext;
52 if (context instanceof context_1.SignatureSentContext) {
53 requestSentContext = context.cloneRequestSent();
54 }
55 else {
56 const nonce = node_core_1.utils.randomUInt64();
57 let mutableTransactions = Object.values(node.memPool);
58 const minerTransaction = await createMinerTransaction({
59 node,
60 feeAddress,
61 transactions: mutableTransactions,
62 nonce,
63 });
64 if (mutableTransactions.length >= node.blockchain.settings.maxTransactionsPerBlock) {
65 const mutableNetworkFees = await Promise.all(mutableTransactions.map(async (transaction) => {
66 const networkFee = await transaction.getNetworkFee(node.blockchain.feeContext);
67 return [transaction, new bignumber_js_1.default(networkFee.toString(10))];
68 }));
69 mutableNetworkFees.sort(([first, a], [second, b]) => b.div(second.size).comparedTo(a.div(first.size)));
70 mutableTransactions = lodash_1.default.take(mutableNetworkFees, node.blockchain.settings.maxTransactionsPerBlock - 1)
71 // tslint:disable-next-line no-unused
72 .map(([transaction, _unused]) => transaction);
73 }
74 mutableTransactions.unshift(minerTransaction);
75 const [previousHeader, validators] = await Promise.all([
76 node.blockchain.header.get({ hashOrIndex: context.previousHash }),
77 node.blockchain.getValidators(mutableTransactions),
78 ]);
79 const newContext = new context_1.RequestSentContext({
80 viewNumber: context.viewNumber,
81 myIndex: context.myIndex,
82 primaryIndex: context.primaryIndex,
83 expectedView: context.expectedView,
84 validators: context.validators,
85 blockReceivedTimeSeconds: context.blockReceivedTimeSeconds,
86 transactions: mutableTransactions.reduce((acc, transaction) => (Object.assign({}, acc, { [transaction.hashHex]: transaction })), {}),
87 signatures: [],
88 header: {
89 type: 'new',
90 previousHash: context.previousHash,
91 transactionHashes: mutableTransactions.map((transaction) => transaction.hashHex),
92 blockIndex: context.blockIndex,
93 nonce,
94 timestamp: Math.max(consensusContext.nowSeconds(), previousHeader.timestamp + 1),
95 nextConsensus: client_common_1.crypto.getConsensusAddress(validators),
96 },
97 });
98 const mutableSignatures = [];
99 mutableSignatures[newContext.myIndex] = client_common_1.crypto.sign({
100 message: newContext.header.message,
101 privateKey,
102 });
103 requestSentContext = newContext.cloneSignatures({ signatures: mutableSignatures });
104 }
105 if (privateNet) {
106 return common_1.checkSignatures({ node, context: requestSentContext });
107 }
108 common_1.signAndRelay({
109 context: requestSentContext,
110 node,
111 privateKey,
112 consensusMessage: new node_core_1.PrepareRequestConsensusMessage({
113 viewNumber: requestSentContext.viewNumber,
114 nonce: requestSentContext.header.consensusData,
115 nextConsensus: requestSentContext.header.nextConsensus,
116 transactionHashes: requestSentContext.transactionHashes.map((hash) => client_common_1.common.hexToUInt256(hash)),
117 minerTransaction: utils_1.utils.nullthrows(requestSentContext.transactions[requestSentContext.transactionHashes[0]]),
118 signature: utils_1.utils.nullthrows(requestSentContext.signatures[requestSentContext.myIndex]),
119 }),
120 });
121 const { secondsPerBlock } = node.blockchain.settings;
122 return {
123 context: requestSentContext,
124 // tslint:disable-next-line no-bitwise
125 timerSeconds: secondsPerBlock << (requestSentContext.viewNumber + 1),
126 };
127 }
128 if (context instanceof context_1.RequestSentContext || context.type === 'backup') {
129 return requestChangeView({
130 context,
131 node,
132 privateKey,
133 consensusContext,
134 });
135 }
136 return { context };
137};
138
139//# sourceMappingURL=data:application/json;charset=utf8;base64,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QUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDckQ7Z0JBQ3JCLFNBQVMsRUFBRSxhQUFXLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUM3RixDQUFDO1NBQ0gsQ0FBQyxDQUFDO1FBRUgsTUFBTSxFQUFFLGVBQWUsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO1FBRXJELE9BQU87WUFDTCxPQUFPLEVBQUUsa0JBQWtCO1lBQzNCLHNDQUFzQztZQUN0QyxZQUFZLEVBQUUsZUFBZSxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztTQUNyRSxDQUFDO0tBQ0g7SUFFRCxJQUFJLE9BQU8sWUFBWSw0QkFBa0IsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtRQUN0RSxPQUFPLGlCQUFpQixDQUFDO1lBQ3ZCLE9BQU87WUFDUCxJQUFJO1lBQ0osVUFBVTtZQUNWLGdCQUFnQjtTQUNqQixDQUFDLENBQUM7S0FDSjtJQUVELE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUNyQixDQUFDLENBQUMiLCJmaWxlIjoibmVvLW9uZS1ub2RlLWNvbnNlbnN1cy9zcmMvcnVuQ29uc2Vuc3VzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29tbW9uLCBjcnlwdG8sIFByaXZhdGVLZXksIFVJbnQxNjAgfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29tbW9uJztcbmltcG9ydCB7XG4gIEJsb2NrLFxuICBNaW5lclRyYW5zYWN0aW9uLFxuICBOb2RlLFxuICBPdXRwdXQsXG4gIFByZXBhcmVSZXF1ZXN0Q29uc2Vuc3VzTWVzc2FnZSxcbiAgVHJhbnNhY3Rpb24sXG4gIHV0aWxzLFxufSBmcm9tICdAbmVvLW9uZS9ub2RlLWNvcmUnO1xuaW1wb3J0IHsgdXRpbHMgYXMgY29tbW9uVXRpbHMgfSBmcm9tICdAbmVvLW9uZS91dGlscyc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgQk4gZnJvbSAnYm4uanMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7XG4gIGNoZWNrRXhwZWN0ZWRWaWV3LFxuICBjaGVja1NpZ25hdHVyZXMsXG4gIGluY3JlbWVudEV4cGVjdGVkVmlldyxcbiAgaW5pdGlhbGl6ZUNvbnNlbnN1c0luaXRpYWwsXG4gIHNpZ25BbmRSZWxheSxcbiAgc2lnbkFuZFJlbGF5Q2hhbmdlVmlldyxcbn0gZnJvbSAnLi9jb21tb24nO1xuaW1wb3J0IHsgSW50ZXJuYWxPcHRpb25zIH0gZnJvbSAnLi9Db25zZW5zdXMnO1xuaW1wb3J0IHsgQ29uc2Vuc3VzQ29udGV4dCB9IGZyb20gJy4vQ29uc2Vuc3VzQ29udGV4dCc7XG5pbXBvcnQgeyBDb250ZXh0LCBSZXF1ZXN0U2VudENvbnRleHQsIFNpZ25hdHVyZVNlbnRDb250ZXh0IH0gZnJvbSAnLi9jb250ZXh0JztcbmltcG9ydCB7IFJlc3VsdCB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBjcmVhdGVNaW5lclRyYW5zYWN0aW9uID0gYXN5bmMgKHtcbiAgbm9kZSxcbiAgZmVlQWRkcmVzcyxcbiAgdHJhbnNhY3Rpb25zLFxuICBub25jZSxcbn06IHtcbiAgcmVhZG9ubHkgbm9kZTogTm9kZTtcbiAgcmVhZG9ubHkgZmVlQWRkcmVzczogVUludDE2MDtcbiAgcmVhZG9ubHkgdHJhbnNhY3Rpb25zOiBSZWFkb25seUFycmF5PFRyYW5zYWN0aW9uPjtcbiAgcmVhZG9ubHkgbm9uY2U6IEJOO1xufSkgPT4ge1xuICBjb25zdCBuZXR3b3JrRmVlID0gYXdhaXQgQmxvY2suY2FsY3VsYXRlTmV0d29ya0ZlZShub2RlLmJsb2NrY2hhaW4uZmVlQ29udGV4dCwgdHJhbnNhY3Rpb25zKTtcblxuICBjb25zdCBvdXRwdXRzID0gbmV0d29ya0ZlZS5pc1plcm8oKVxuICAgID8gW11cbiAgICA6IFtcbiAgICAgICAgbmV3IE91dHB1dCh7XG4gICAgICAgICAgYXNzZXQ6IG5vZGUuYmxvY2tjaGFpbi5zZXR0aW5ncy51dGlsaXR5VG9rZW4uaGFzaCxcbiAgICAgICAgICB2YWx1ZTogbmV0d29ya0ZlZSxcbiAgICAgICAgICBhZGRyZXNzOiBmZWVBZGRyZXNzLFxuICAgICAgICB9KSxcbiAgICAgIF07XG5cbiAgcmV0dXJuIG5ldyBNaW5lclRyYW5zYWN0aW9uKHtcbiAgICBub25jZTogbm9uY2UubW9kKHV0aWxzLlVJTlRfTUFYLmFkZG4oMSkpLnRvTnVtYmVyKCksXG4gICAgb3V0cHV0cyxcbiAgfSk7XG59O1xuXG5jb25zdCByZXF1ZXN0Q2hhbmdlVmlldyA9ICh7XG4gIGNvbnRleHQ6IGNvbnRleHRJbixcbiAgbm9kZSxcbiAgcHJpdmF0ZUtleSxcbiAgY29uc2Vuc3VzQ29udGV4dCxcbn06IHtcbiAgcmVhZG9ubHkgY29udGV4dDogQ29udGV4dDtcbiAgcmVhZG9ubHkgbm9kZTogTm9kZTtcbiAgcmVhZG9ubHkgcHJpdmF0ZUtleTogUHJpdmF0ZUtleTtcbiAgcmVhZG9ubHkgY29uc2Vuc3VzQ29udGV4dDogQ29uc2Vuc3VzQ29udGV4dDtcbn0pOiBSZXN1bHQ8Q29udGV4dD4gPT4ge1xuICBsZXQgY29udGV4dCA9IGNvbnRleHRJbjtcblxuICBjb250ZXh0ID0gY29udGV4dC5jbG9uZUV4cGVjdGVkVmlldyh7XG4gICAgZXhwZWN0ZWRWaWV3OiBpbmNyZW1lbnRFeHBlY3RlZFZpZXcoY29udGV4dCksXG4gIH0pO1xuXG4gIHNpZ25BbmRSZWxheUNoYW5nZVZpZXcoeyBjb250ZXh0LCBub2RlLCBwcml2YXRlS2V5IH0pO1xuXG4gIGNvbnN0IHZpZXdOdW1iZXIgPSBjb250ZXh0LmV4cGVjdGVkVmlld1tjb250ZXh0Lm15SW5kZXhdO1xuICBpZiAoY2hlY2tFeHBlY3RlZFZpZXcoeyBjb250ZXh0LCB2aWV3TnVtYmVyIH0pKSB7XG4gICAgcmV0dXJuIGluaXRpYWxpemVDb25zZW5zdXNJbml0aWFsKHtcbiAgICAgIGJsb2NrY2hhaW46IG5vZGUuYmxvY2tjaGFpbixcbiAgICAgIGNvbnRleHQsXG4gICAgICB2aWV3TnVtYmVyLFxuICAgICAgY29uc2Vuc3VzQ29udGV4dCxcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IHsgc2Vjb25kc1BlckJsb2NrIH0gPSBub2RlLmJsb2NrY2hhaW4uc2V0dGluZ3M7XG5cbiAgcmV0dXJuIHtcbiAgICBjb250ZXh0LFxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgdGltZXJTZWNvbmRzOiBzZWNvbmRzUGVyQmxvY2sgPDwgKHZpZXdOdW1iZXIgKyAxKSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBydW5Db25zZW5zdXMgPSBhc3luYyAoe1xuICBjb250ZXh0LFxuICBub2RlLFxuICBvcHRpb25zOiB7IHByaXZhdGVLZXksIGZlZUFkZHJlc3MsIHByaXZhdGVOZXQgfSxcbiAgY29uc2Vuc3VzQ29udGV4dCxcbn06IHtcbiAgcmVhZG9ubHkgY29udGV4dDogQ29udGV4dDtcbiAgcmVhZG9ubHkgbm9kZTogTm9kZTtcbiAgcmVhZG9ubHkgb3B0aW9uczogSW50ZXJuYWxPcHRpb25zO1xuICByZWFkb25seSBjb25zZW5zdXNDb250ZXh0OiBDb25zZW5zdXNDb250ZXh0O1xufSk6IFByb21pc2U8UmVzdWx0PENvbnRleHQ+PiA9PiB7XG4gIGlmIChjb250ZXh0LnR5cGUgPT09ICdwcmltYXJ5JyAmJiAhKGNvbnRleHQgaW5zdGFuY2VvZiBSZXF1ZXN0U2VudENvbnRleHQpKSB7XG4gICAgbGV0IHJlcXVlc3RTZW50Q29udGV4dDogUmVxdWVzdFNlbnRDb250ZXh0O1xuICAgIGlmIChjb250ZXh0IGluc3RhbmNlb2YgU2lnbmF0dXJlU2VudENvbnRleHQpIHtcbiAgICAgIHJlcXVlc3RTZW50Q29udGV4dCA9IGNvbnRleHQuY2xvbmVSZXF1ZXN0U2VudCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBub25jZSA9IHV0aWxzLnJhbmRvbVVJbnQ2NCgpO1xuICAgICAgbGV0IG11dGFibGVUcmFuc2FjdGlvbnMgPSBPYmplY3QudmFsdWVzKG5vZGUubWVtUG9vbCk7XG4gICAgICBjb25zdCBtaW5lclRyYW5zYWN0aW9uID0gYXdhaXQgY3JlYXRlTWluZXJUcmFuc2FjdGlvbih7XG4gICAgICAgIG5vZGUsXG4gICAgICAgIGZlZUFkZHJlc3MsXG4gICAgICAgIHRyYW5zYWN0aW9uczogbXV0YWJsZVRyYW5zYWN0aW9ucyxcbiAgICAgICAgbm9uY2UsXG4gICAgICB9KTtcblxuICAgICAgaWYgKG11dGFibGVUcmFuc2FjdGlvbnMubGVuZ3RoID49IG5vZGUuYmxvY2tjaGFpbi5zZXR0aW5ncy5tYXhUcmFuc2FjdGlvbnNQZXJCbG9jaykge1xuICAgICAgICBjb25zdCBtdXRhYmxlTmV0d29ya0ZlZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBtdXRhYmxlVHJhbnNhY3Rpb25zLm1hcDxQcm9taXNlPFtUcmFuc2FjdGlvbiwgQmlnTnVtYmVyXT4+KGFzeW5jICh0cmFuc2FjdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV0d29ya0ZlZSA9IGF3YWl0IHRyYW5zYWN0aW9uLmdldE5ldHdvcmtGZWUobm9kZS5ibG9ja2NoYWluLmZlZUNvbnRleHQpO1xuXG4gICAgICAgICAgICByZXR1cm4gW3RyYW5zYWN0aW9uLCBuZXcgQmlnTnVtYmVyKG5ldHdvcmtGZWUudG9TdHJpbmcoMTApKV07XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgbXV0YWJsZU5ldHdvcmtGZWVzLnNvcnQoKFtmaXJzdCwgYV0sIFtzZWNvbmQsIGJdKSA9PiBiLmRpdihzZWNvbmQuc2l6ZSkuY29tcGFyZWRUbyhhLmRpdihmaXJzdC5zaXplKSkpO1xuICAgICAgICBtdXRhYmxlVHJhbnNhY3Rpb25zID0gXy50YWtlKG11dGFibGVOZXR3b3JrRmVlcywgbm9kZS5ibG9ja2NoYWluLnNldHRpbmdzLm1heFRyYW5zYWN0aW9uc1BlckJsb2NrIC0gMSlcbiAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkXG4gICAgICAgICAgLm1hcCgoW3RyYW5zYWN0aW9uLCBfdW51c2VkXSkgPT4gdHJhbnNhY3Rpb24pO1xuICAgICAgfVxuICAgICAgbXV0YWJsZVRyYW5zYWN0aW9ucy51bnNoaWZ0KG1pbmVyVHJhbnNhY3Rpb24pO1xuICAgICAgY29uc3QgW3ByZXZpb3VzSGVhZGVyLCB2YWxpZGF0b3JzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgbm9kZS5ibG9ja2NoYWluLmhlYWRlci5nZXQoeyBoYXNoT3JJbmRleDogY29udGV4dC5wcmV2aW91c0hhc2ggfSksXG4gICAgICAgIG5vZGUuYmxvY2tjaGFpbi5nZXRWYWxpZGF0b3JzKG11dGFibGVUcmFuc2FjdGlvbnMpLFxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IG5ld0NvbnRleHQgPSBuZXcgUmVxdWVzdFNlbnRDb250ZXh0KHtcbiAgICAgICAgdmlld051bWJlcjogY29udGV4dC52aWV3TnVtYmVyLFxuICAgICAgICBteUluZGV4OiBjb250ZXh0Lm15SW5kZXgsXG4gICAgICAgIHByaW1hcnlJbmRleDogY29udGV4dC5wcmltYXJ5SW5kZXgsXG4gICAgICAgIGV4cGVjdGVkVmlldzogY29udGV4dC5leHBlY3RlZFZpZXcsXG4gICAgICAgIHZhbGlkYXRvcnM6IGNvbnRleHQudmFsaWRhdG9ycyxcbiAgICAgICAgYmxvY2tSZWNlaXZlZFRpbWVTZWNvbmRzOiBjb250ZXh0LmJsb2NrUmVjZWl2ZWRUaW1lU2Vjb25kcyxcbiAgICAgICAgdHJhbnNhY3Rpb25zOiBtdXRhYmxlVHJhbnNhY3Rpb25zLnJlZHVjZTx7IFtrZXk6IHN0cmluZ106IFRyYW5zYWN0aW9uIH0+KFxuICAgICAgICAgIChhY2MsIHRyYW5zYWN0aW9uKSA9PiAoe1xuICAgICAgICAgICAgLi4uYWNjLFxuICAgICAgICAgICAgW3RyYW5zYWN0aW9uLmhhc2hIZXhdOiB0cmFuc2FjdGlvbixcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7fSxcbiAgICAgICAgKSxcbiAgICAgICAgc2lnbmF0dXJlczogW10sXG4gICAgICAgIGhlYWRlcjoge1xuICAgICAgICAgIHR5cGU6ICduZXcnLFxuICAgICAgICAgIHByZXZpb3VzSGFzaDogY29udGV4dC5wcmV2aW91c0hhc2gsXG4gICAgICAgICAgdHJhbnNhY3Rpb25IYXNoZXM6IG11dGFibGVUcmFuc2FjdGlvbnMubWFwKCh0cmFuc2FjdGlvbikgPT4gdHJhbnNhY3Rpb24uaGFzaEhleCksXG5cbiAgICAgICAgICBibG9ja0luZGV4OiBjb250ZXh0LmJsb2NrSW5kZXgsXG4gICAgICAgICAgbm9uY2UsXG4gICAgICAgICAgdGltZXN0YW1wOiBNYXRoLm1heChjb25zZW5zdXNDb250ZXh0Lm5vd1NlY29uZHMoKSwgcHJldmlvdXNIZWFkZXIudGltZXN0YW1wICsgMSksXG5cbiAgICAgICAgICBuZXh0Q29uc2Vuc3VzOiBjcnlwdG8uZ2V0Q29uc2Vuc3VzQWRkcmVzcyh2YWxpZGF0b3JzKSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBtdXRhYmxlU2lnbmF0dXJlcyA9IFtdO1xuICAgICAgbXV0YWJsZVNpZ25hdHVyZXNbbmV3Q29udGV4dC5teUluZGV4XSA9IGNyeXB0by5zaWduKHtcbiAgICAgICAgbWVzc2FnZTogbmV3Q29udGV4dC5oZWFkZXIubWVzc2FnZSxcbiAgICAgICAgcHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuXG4gICAgICByZXF1ZXN0U2VudENvbnRleHQgPSBuZXdDb250ZXh0LmNsb25lU2lnbmF0dXJlcyh7IHNpZ25hdHVyZXM6IG11dGFibGVTaWduYXR1cmVzIH0pO1xuICAgIH1cblxuICAgIGlmIChwcml2YXRlTmV0KSB7XG4gICAgICByZXR1cm4gY2hlY2tTaWduYXR1cmVzKHsgbm9kZSwgY29udGV4dDogcmVxdWVzdFNlbnRDb250ZXh0IH0pO1xuICAgIH1cblxuICAgIHNpZ25BbmRSZWxheSh7XG4gICAgICBjb250ZXh0OiByZXF1ZXN0U2VudENvbnRleHQsXG4gICAgICBub2RlLFxuICAgICAgcHJpdmF0ZUtleSxcbiAgICAgIGNvbnNlbnN1c01lc3NhZ2U6IG5ldyBQcmVwYXJlUmVxdWVzdENvbnNlbnN1c01lc3NhZ2Uoe1xuICAgICAgICB2aWV3TnVtYmVyOiByZXF1ZXN0U2VudENvbnRleHQudmlld051bWJlcixcbiAgICAgICAgbm9uY2U6IHJlcXVlc3RTZW50Q29udGV4dC5oZWFkZXIuY29uc2Vuc3VzRGF0YSxcbiAgICAgICAgbmV4dENvbnNlbnN1czogcmVxdWVzdFNlbnRDb250ZXh0LmhlYWRlci5uZXh0Q29uc2Vuc3VzLFxuICAgICAgICB0cmFuc2FjdGlvbkhhc2hlczogcmVxdWVzdFNlbnRDb250ZXh0LnRyYW5zYWN0aW9uSGFzaGVzLm1hcCgoaGFzaCkgPT4gY29tbW9uLmhleFRvVUludDI1NihoYXNoKSksXG4gICAgICAgIG1pbmVyVHJhbnNhY3Rpb246IGNvbW1vblV0aWxzLm51bGx0aHJvd3MoXG4gICAgICAgICAgcmVxdWVzdFNlbnRDb250ZXh0LnRyYW5zYWN0aW9uc1tyZXF1ZXN0U2VudENvbnRleHQudHJhbnNhY3Rpb25IYXNoZXNbMF1dLFxuICAgICAgICApIGFzIE1pbmVyVHJhbnNhY3Rpb24sXG4gICAgICAgIHNpZ25hdHVyZTogY29tbW9uVXRpbHMubnVsbHRocm93cyhyZXF1ZXN0U2VudENvbnRleHQuc2lnbmF0dXJlc1tyZXF1ZXN0U2VudENvbnRleHQubXlJbmRleF0pLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBjb25zdCB7IHNlY29uZHNQZXJCbG9jayB9ID0gbm9kZS5ibG9ja2NoYWluLnNldHRpbmdzO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRleHQ6IHJlcXVlc3RTZW50Q29udGV4dCxcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICB0aW1lclNlY29uZHM6IHNlY29uZHNQZXJCbG9jayA8PCAocmVxdWVzdFNlbnRDb250ZXh0LnZpZXdOdW1iZXIgKyAxKSxcbiAgICB9O1xuICB9XG5cbiAgaWYgKGNvbnRleHQgaW5zdGFuY2VvZiBSZXF1ZXN0U2VudENvbnRleHQgfHwgY29udGV4dC50eXBlID09PSAnYmFja3VwJykge1xuICAgIHJldHVybiByZXF1ZXN0Q2hhbmdlVmlldyh7XG4gICAgICBjb250ZXh0LFxuICAgICAgbm9kZSxcbiAgICAgIHByaXZhdGVLZXksXG4gICAgICBjb25zZW5zdXNDb250ZXh0LFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHsgY29udGV4dCB9O1xufTtcbiJdfQ==