@atomicfinance/bitcoin-dlc-provider 2.4.2 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,36 +1,35 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const bitcoin_networks_1 = require("@atomicfinance/bitcoin-networks");
7
- const provider_1 = __importDefault(require("@atomicfinance/provider"));
8
- const types_1 = require("@atomicfinance/types");
9
- const utils_1 = require("@liquality/utils");
10
- const core_1 = require("@node-dlc/core");
11
- const messaging_1 = require("@node-dlc/messaging");
12
- const bitcoin_1 = require("@node-lightning/bitcoin");
13
- const bufio_1 = require("@node-lightning/bufio");
14
- const crypto_1 = require("@node-lightning/crypto");
15
- const assert_1 = __importDefault(require("assert"));
16
- const bignumber_js_1 = __importDefault(require("bignumber.js"));
17
- const bitcoinjs_lib_1 = require("bitcoinjs-lib");
18
- const Utils_1 = require("./utils/Utils");
1
+ Object.defineProperty(exports, "__esModule", {
2
+ value: true
3
+ });
4
+ exports.default = void 0;
5
+ var _bitcoinNetworks = require("@atomicfinance/bitcoin-networks");
6
+ var _provider = _interopRequireDefault(require("@atomicfinance/provider"));
7
+ var _types = require("@atomicfinance/types");
8
+ var _utils = require("@liquality/utils");
9
+ var _core = require("@node-dlc/core");
10
+ var _messaging = require("@node-dlc/messaging");
11
+ var _bitcoin = require("@node-lightning/bitcoin");
12
+ var _bufio = require("@node-lightning/bufio");
13
+ var _crypto = require("@node-lightning/crypto");
14
+ var _assert = _interopRequireDefault(require("assert"));
15
+ var _bignumberJs = _interopRequireDefault(require("bignumber.js"));
16
+ var _bitcoinjsLib = require("bitcoinjs-lib");
17
+ var _utils1 = require("./utils/Utils");
18
+ function _interopRequireDefault(obj) {
19
+ return obj && obj.__esModule ? obj : {
20
+ default: obj
21
+ };
22
+ }
19
23
  const ESTIMATED_SIZE = 312;
20
- class BitcoinDlcProvider extends provider_1.default {
21
- constructor(network, cfdDlcJs) {
22
- super();
23
- this._network = network;
24
- this._cfdDlcJs = cfdDlcJs;
25
- }
24
+ let BitcoinDlcProvider = class BitcoinDlcProvider extends _provider.default {
26
25
  async CfdLoaded() {
27
- while (!this._cfdDlcJs) {
28
- await utils_1.sleep(10);
26
+ while(!this._cfdDlcJs){
27
+ await (0, _utils).sleep(10);
29
28
  }
30
29
  }
31
30
  async GetPrivKeysForInputs(inputs) {
32
31
  const privKeys = [];
33
- for (let i = 0; i < inputs.length; i++) {
32
+ for(let i = 0; i < inputs.length; i++){
34
33
  const input = inputs[i];
35
34
  let derivationPath = input.derivationPath;
36
35
  if (!derivationPath) {
@@ -44,7 +43,7 @@ class BitcoinDlcProvider extends provider_1.default {
44
43
  }
45
44
  async GetCfdNetwork() {
46
45
  const network = await this.getConnectedNetwork();
47
- switch (network.name) {
46
+ switch(network.name){
48
47
  case 'bitcoin_testnet':
49
48
  return 'testnet';
50
49
  case 'bitcoin_regtest':
@@ -54,24 +53,21 @@ class BitcoinDlcProvider extends provider_1.default {
54
53
  }
55
54
  }
56
55
  async GetInputsForAmount(amount, feeRatePerVb, fixedInputs = []) {
57
- if (amount === BigInt(0))
58
- return [];
56
+ if (amount === BigInt(0)) return [];
59
57
  const targets = [
60
58
  {
61
59
  address: BurnAddress,
62
- value: Number(amount) + ESTIMATED_SIZE * (Number(feeRatePerVb) - 1),
63
- },
60
+ value: Number(amount) + ESTIMATED_SIZE * (Number(feeRatePerVb) - 1)
61
+ },
64
62
  ];
65
63
  let inputs;
66
64
  try {
67
65
  const inputsForAmount = await this.getMethod('getInputsForAmount')(targets, Number(feeRatePerVb), fixedInputs);
68
66
  inputs = inputsForAmount.inputs;
69
- }
70
- catch (e) {
67
+ } catch (e) {
71
68
  if (fixedInputs.length === 0) {
72
69
  throw Error('Not enough balance getInputsForAmount');
73
- }
74
- else {
70
+ } else {
75
71
  inputs = fixedInputs;
76
72
  }
77
73
  }
@@ -80,113 +76,156 @@ class BitcoinDlcProvider extends provider_1.default {
80
76
  async Initialize(collateral, feeRatePerVb, fixedInputs) {
81
77
  const network = await this.getConnectedNetwork();
82
78
  const payoutAddress = await this.client.wallet.getUnusedAddress(false);
83
- const payoutSPK = bitcoinjs_lib_1.address.toOutputScript(payoutAddress.address, network);
79
+ const payoutSPK = _bitcoinjsLib.address.toOutputScript(payoutAddress.address, network);
84
80
  const changeAddress = await this.client.wallet.getUnusedAddress(true);
85
- const changeSPK = bitcoinjs_lib_1.address.toOutputScript(changeAddress.address, network);
81
+ const changeSPK = _bitcoinjsLib.address.toOutputScript(changeAddress.address, network);
86
82
  const fundingAddress = await this.client.wallet.getUnusedAddress(false);
87
83
  const fundingPubKey = Buffer.from(fundingAddress.publicKey, 'hex');
88
- if (fundingAddress.address === payoutAddress.address)
89
- throw Error('Address reuse');
84
+ if (fundingAddress.address === payoutAddress.address) throw Error('Address reuse');
90
85
  const inputs = await this.GetInputsForAmount(collateral, feeRatePerVb, fixedInputs);
91
- const fundingInputs = await Promise.all(inputs.map(async (input) => {
86
+ const fundingInputs = await Promise.all(inputs.map(async (input)=>{
92
87
  return this.inputToFundingInput(input);
93
88
  }));
94
- const payoutSerialId = Utils_1.generateSerialId();
95
- const changeSerialId = Utils_1.generateSerialId();
89
+ const payoutSerialId = (0, _utils1).generateSerialId();
90
+ const changeSerialId = (0, _utils1).generateSerialId();
96
91
  return {
97
92
  fundingPubKey,
98
93
  payoutSPK,
99
94
  payoutSerialId,
100
95
  fundingInputs,
101
96
  changeSPK,
102
- changeSerialId,
97
+ changeSerialId
103
98
  };
104
99
  }
105
100
  /**
106
- * TODO: Add GetPayoutFromOutcomes
107
- *
108
- * private GetPayoutsFromOutcomes(
109
- * contractDescriptor: ContractDescriptorV0,
110
- * totalCollateral: bigint,
111
- * ): PayoutRequest[] {}
112
- */
113
- GetPayoutsFromPayoutFunction(_dlcOffer, contractDescriptor, oracleInfo, totalCollateral) {
114
- if (_dlcOffer.type !== messaging_1.MessageType.DlcOfferV0)
115
- throw Error('DlcOffer must be V0');
101
+ * TODO: Add GetPayoutFromOutcomes
102
+ *
103
+ * private GetPayoutsFromOutcomes(
104
+ * contractDescriptor: ContractDescriptorV0,
105
+ * totalCollateral: bigint,
106
+ * ): PayoutRequest[] {}
107
+ */ GetPayoutsFromPayoutFunction(_dlcOffer, contractDescriptor, oracleInfo, totalCollateral) {
108
+ if (_dlcOffer.type !== _messaging.MessageType.DlcOfferV0) throw Error('DlcOffer must be V0');
116
109
  const dlcOffer = _dlcOffer;
117
- if (contractDescriptor.payoutFunction.type !== messaging_1.MessageType.PayoutFunctionV0)
118
- throw Error('PayoutFunction must be V0');
110
+ if (contractDescriptor.payoutFunction.type !== _messaging.MessageType.PayoutFunctionV0) throw Error('PayoutFunction must be V0');
119
111
  const payoutFunction = contractDescriptor.payoutFunction;
120
- if (payoutFunction.pieces.length === 0)
121
- throw Error('PayoutFunction must have at least once PayoutCurvePiece');
122
- if (payoutFunction.pieces.length > 1)
123
- throw Error('More than one PayoutCurvePiece not supported');
124
- const payoutCurvePiece = payoutFunction.pieces[0]
125
- .payoutCurvePiece;
126
- if (payoutCurvePiece.type !== messaging_1.MessageType.HyperbolaPayoutCurvePiece &&
127
- payoutCurvePiece.type !== messaging_1.MessageType.OldHyperbolaPayoutCurvePiece)
128
- throw Error('Must be HyperbolaPayoutCurvePiece');
129
- if (payoutCurvePiece.b !== BigInt(0) || payoutCurvePiece.c !== BigInt(0))
130
- throw Error('b and c HyperbolaPayoutCurvePiece values must be 0');
131
- const eventDescriptor = oracleInfo.announcement.oracleEvent
132
- .eventDescriptor;
133
- if (eventDescriptor.type !== messaging_1.MessageType.DigitDecompositionEventDescriptorV0)
134
- throw Error('Only DigitDecomposition Oracle Events supported');
112
+ if (payoutFunction.pieces.length === 0) throw Error('PayoutFunction must have at least once PayoutCurvePiece');
113
+ if (payoutFunction.pieces.length > 1) throw Error('More than one PayoutCurvePiece not supported');
114
+ const payoutCurvePiece = payoutFunction.pieces[0].payoutCurvePiece;
115
+ if (payoutCurvePiece.type !== _messaging.MessageType.HyperbolaPayoutCurvePiece && payoutCurvePiece.type !== _messaging.MessageType.OldHyperbolaPayoutCurvePiece) throw Error('Must be HyperbolaPayoutCurvePiece');
116
+ if (payoutCurvePiece.b !== BigInt(0) || payoutCurvePiece.c !== BigInt(0)) throw Error('b and c HyperbolaPayoutCurvePiece values must be 0');
117
+ const eventDescriptor = oracleInfo.announcement.oracleEvent.eventDescriptor;
118
+ if (eventDescriptor.type !== _messaging.MessageType.DigitDecompositionEventDescriptorV0) throw Error('Only DigitDecomposition Oracle Events supported');
135
119
  const roundingIntervals = contractDescriptor.roundingIntervals;
136
- const cetPayouts = core_1.HyperbolaPayoutCurve.computePayouts(payoutFunction, totalCollateral, roundingIntervals);
120
+ const cetPayouts = _core.HyperbolaPayoutCurve.computePayouts(payoutFunction, totalCollateral, roundingIntervals);
137
121
  const payoutGroups = [];
138
- cetPayouts.forEach((p) => {
122
+ cetPayouts.forEach((p)=>{
139
123
  payoutGroups.push({
140
124
  payout: p.payout,
141
- groups: core_1.groupByIgnoringDigits(p.indexFrom, p.indexTo, eventDescriptor.base, contractDescriptor.numDigits),
125
+ groups: (0, _core).groupByIgnoringDigits(p.indexFrom, p.indexTo, eventDescriptor.base, contractDescriptor.numDigits)
142
126
  });
143
127
  });
144
128
  const rValuesMessagesList = this.GenerateMessages(oracleInfo);
145
- const { payouts, messagesList } = Utils_1.outputsToPayouts(payoutGroups, rValuesMessagesList, dlcOffer.offerCollateralSatoshis, dlcOffer.contractInfo.totalCollateral - dlcOffer.offerCollateralSatoshis, true);
146
- return { payouts, payoutGroups, messagesList };
129
+ const { payouts , messagesList } = (0, _utils1).outputsToPayouts(payoutGroups, rValuesMessagesList, dlcOffer.offerCollateralSatoshis, dlcOffer.contractInfo.totalCollateral - dlcOffer.offerCollateralSatoshis, true);
130
+ return {
131
+ payouts,
132
+ payoutGroups,
133
+ messagesList
134
+ };
135
+ }
136
+ GetPayoutsFromPolynomialPayoutFunction(_dlcOffer, contractDescriptor, oracleInfo, totalCollateral) {
137
+ if (_dlcOffer.type !== _messaging.MessageType.DlcOfferV0) throw Error('DlcOffer must be V0');
138
+ const dlcOffer = _dlcOffer;
139
+ if (contractDescriptor.payoutFunction.type !== _messaging.MessageType.PayoutFunctionV0) throw Error('PayoutFunction must be V0');
140
+ const payoutFunction = contractDescriptor.payoutFunction;
141
+ if (payoutFunction.pieces.length === 0) throw Error('PayoutFunction must have at least once PayoutCurvePiece');
142
+ for (const piece of payoutFunction.pieces){
143
+ if (piece.payoutCurvePiece.type !== _messaging.MessageType.PolynomialPayoutCurvePiece) throw Error('Must be PolynomialPayoutCurvePiece');
144
+ }
145
+ const eventDescriptor = oracleInfo.announcement.oracleEvent.eventDescriptor;
146
+ if (eventDescriptor.type !== _messaging.MessageType.DigitDecompositionEventDescriptorV0) throw Error('Only DigitDecomposition Oracle Events supported');
147
+ const roundingIntervals = contractDescriptor.roundingIntervals;
148
+ const cetPayouts = _core.PolynomialPayoutCurve.computePayouts(payoutFunction, totalCollateral, roundingIntervals);
149
+ const payoutGroups = [];
150
+ cetPayouts.forEach((p)=>{
151
+ payoutGroups.push({
152
+ payout: p.payout,
153
+ groups: (0, _core).groupByIgnoringDigits(p.indexFrom, p.indexTo, eventDescriptor.base, contractDescriptor.numDigits)
154
+ });
155
+ });
156
+ const rValuesMessagesList = this.GenerateMessages(oracleInfo);
157
+ const { payouts , messagesList } = (0, _utils1).outputsToPayouts(payoutGroups, rValuesMessagesList, dlcOffer.offerCollateralSatoshis, dlcOffer.contractInfo.totalCollateral - dlcOffer.offerCollateralSatoshis, true);
158
+ return {
159
+ payouts,
160
+ payoutGroups,
161
+ messagesList
162
+ };
147
163
  }
148
164
  GetPayouts(_dlcOffer) {
149
- const { dlcOffer } = Utils_1.checkTypes({ _dlcOffer });
165
+ const { dlcOffer } = (0, _utils1).checkTypes({
166
+ _dlcOffer
167
+ });
150
168
  const contractInfo = dlcOffer.contractInfo;
151
169
  const totalCollateral = contractInfo.totalCollateral;
152
170
  const contractOraclePairs = this.GetContractOraclePairs(contractInfo);
153
- const payoutResponses = contractOraclePairs.map(({ contractDescriptor, oracleInfo }) => this.GetPayoutsFromContractDescriptor(dlcOffer, contractDescriptor, oracleInfo, totalCollateral));
171
+ const payoutResponses = contractOraclePairs.map(({ contractDescriptor , oracleInfo })=>this.GetPayoutsFromContractDescriptor(dlcOffer, contractDescriptor, oracleInfo, totalCollateral)
172
+ );
154
173
  return payoutResponses;
155
174
  }
156
175
  FlattenPayouts(payoutResponses) {
157
- return payoutResponses.reduce((acc, { payouts, payoutGroups, messagesList }) => {
176
+ return payoutResponses.reduce((acc, { payouts , payoutGroups , messagesList })=>{
158
177
  return {
159
178
  payouts: acc.payouts.concat(payouts),
160
179
  payoutGroups: acc.payoutGroups.concat(payoutGroups),
161
- messagesList: acc.messagesList.concat(messagesList),
180
+ messagesList: acc.messagesList.concat(messagesList)
162
181
  };
163
182
  });
164
183
  }
165
184
  GetIndicesFromPayouts(payoutResponses) {
166
- return payoutResponses.reduce((prev, acc) => {
185
+ return payoutResponses.reduce((prev, acc)=>{
167
186
  return prev.concat({
168
- startingMessagesIndex: prev[prev.length - 1].startingMessagesIndex +
169
- acc.messagesList.length,
170
- startingPayoutGroupsIndex: prev[prev.length - 1].startingPayoutGroupsIndex +
171
- acc.payoutGroups.length,
187
+ startingMessagesIndex: prev[prev.length - 1].startingMessagesIndex + acc.messagesList.length,
188
+ startingPayoutGroupsIndex: prev[prev.length - 1].startingPayoutGroupsIndex + acc.payoutGroups.length
172
189
  });
173
- }, [{ startingMessagesIndex: 0, startingPayoutGroupsIndex: 0 }]);
190
+ }, [
191
+ {
192
+ startingMessagesIndex: 0,
193
+ startingPayoutGroupsIndex: 0
194
+ }
195
+ ]);
174
196
  }
175
197
  GetPayoutsFromContractDescriptor(dlcOffer, contractDescriptor, oracleInfo, totalCollateral) {
176
- switch (contractDescriptor.type) {
177
- case messaging_1.MessageType.ContractDescriptorV0:
178
- throw Error('ContractDescriptorV0 not yet supported');
179
- case messaging_1.MessageType.ContractDescriptorV1:
180
- // eslint-disable-next-line no-case-declarations
181
- return this.GetPayoutsFromPayoutFunction(dlcOffer, contractDescriptor, oracleInfo, totalCollateral);
198
+ switch(contractDescriptor.type){
199
+ case _messaging.MessageType.ContractDescriptorV0:
200
+ {
201
+ throw Error('ContractDescriptorV0 not yet supported');
202
+ }
203
+ case _messaging.MessageType.ContractDescriptorV1:
204
+ {
205
+ const contractDescriptorV1 = contractDescriptor;
206
+ const payoutFunction = contractDescriptorV1.payoutFunction;
207
+ // TODO: add a better check for this
208
+ const payoutCurvePiece = payoutFunction.pieces[0].payoutCurvePiece;
209
+ switch(payoutCurvePiece.type){
210
+ case _messaging.MessageType.HyperbolaPayoutCurvePiece:
211
+ return this.GetPayoutsFromPayoutFunction(dlcOffer, contractDescriptor, oracleInfo, totalCollateral);
212
+ case _messaging.MessageType.OldHyperbolaPayoutCurvePiece:
213
+ return this.GetPayoutsFromPayoutFunction(dlcOffer, contractDescriptor, oracleInfo, totalCollateral);
214
+ case _messaging.MessageType.PolynomialPayoutCurvePiece:
215
+ return this.GetPayoutsFromPolynomialPayoutFunction(dlcOffer, contractDescriptor, oracleInfo, totalCollateral);
216
+ }
217
+ }
218
+ break;
182
219
  default:
183
- throw Error('ContractDescriptor must be V0 or V1');
220
+ {
221
+ throw Error('ContractDescriptor must be V0 or V1');
222
+ }
184
223
  }
185
224
  }
186
225
  async createDlcTxs(_dlcOffer, _dlcAccept) {
187
- const { dlcOffer, dlcAccept } = Utils_1.checkTypes({
226
+ const { dlcOffer , dlcAccept } = (0, _utils1).checkTypes({
188
227
  _dlcOffer,
189
- _dlcAccept,
228
+ _dlcAccept
190
229
  });
191
230
  const localFundPubkey = dlcOffer.fundingPubKey.toString('hex');
192
231
  const remoteFundPubkey = dlcAccept.fundingPubKey.toString('hex');
@@ -194,18 +233,20 @@ class BitcoinDlcProvider extends provider_1.default {
194
233
  const remoteFinalScriptPubkey = dlcAccept.payoutSPK.toString('hex');
195
234
  const localChangeScriptPubkey = dlcOffer.changeSPK.toString('hex');
196
235
  const remoteChangeScriptPubkey = dlcAccept.changeSPK.toString('hex');
197
- const localInputs = await Promise.all(dlcOffer.fundingInputs.map(async (fundingInput) => {
236
+ const localInputs = await Promise.all(dlcOffer.fundingInputs.map(async (fundingInput)=>{
198
237
  const input = await this.fundingInputToInput(fundingInput, false);
199
238
  return input.toUtxo();
200
239
  }));
201
- const remoteInputs = await Promise.all(dlcAccept.fundingInputs.map(async (fundingInput) => {
240
+ const remoteInputs = await Promise.all(dlcAccept.fundingInputs.map(async (fundingInput)=>{
202
241
  const input = await this.fundingInputToInput(fundingInput, false);
203
242
  return input.toUtxo();
204
243
  }));
205
- const localInputAmount = localInputs.reduce((prev, cur) => prev + cur.amount.GetSatoshiAmount(), 0);
206
- const remoteInputAmount = remoteInputs.reduce((prev, cur) => prev + cur.amount.GetSatoshiAmount(), 0);
244
+ const localInputAmount = localInputs.reduce((prev, cur)=>prev + cur.amount.GetSatoshiAmount()
245
+ , 0);
246
+ const remoteInputAmount = remoteInputs.reduce((prev, cur)=>prev + cur.amount.GetSatoshiAmount()
247
+ , 0);
207
248
  const payoutResponses = this.GetPayouts(dlcOffer);
208
- const { payouts, messagesList } = this.FlattenPayouts(payoutResponses);
249
+ const { payouts , messagesList } = this.FlattenPayouts(payoutResponses);
209
250
  const dlcTxRequest = {
210
251
  payouts,
211
252
  localFundPubkey,
@@ -227,23 +268,26 @@ class BitcoinDlcProvider extends provider_1.default {
227
268
  remoteChangeScriptPubkey,
228
269
  feeRate: Number(dlcOffer.feeRatePerVb),
229
270
  cetLockTime: dlcOffer.cetLocktime,
230
- fundOutputSerialId: dlcOffer.fundOutputSerialId,
271
+ fundOutputSerialId: dlcOffer.fundOutputSerialId
231
272
  };
232
273
  const dlcTxs = await this.CreateDlcTransactions(dlcTxRequest);
233
- const dlcTransactions = new messaging_1.DlcTransactionsV0();
234
- dlcTransactions.fundTx = bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(dlcTxs.fundTxHex));
274
+ const dlcTransactions = new _messaging.DlcTransactionsV0();
275
+ dlcTransactions.fundTx = _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(dlcTxs.fundTxHex));
235
276
  dlcTransactions.fundTxVout = [
236
277
  BigInt(dlcOffer.changeSerialId),
237
278
  BigInt(dlcAccept.changeSerialId),
238
- BigInt(dlcTxRequest.fundOutputSerialId),
239
- ]
240
- .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))
241
- .findIndex((i) => BigInt(i) === BigInt(dlcTxRequest.fundOutputSerialId));
242
- dlcTransactions.refundTx = bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(dlcTxs.refundTxHex));
243
- dlcTransactions.cets = dlcTxs.cetsHex.map((cetHex) => {
244
- return bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(cetHex));
279
+ BigInt(dlcTxRequest.fundOutputSerialId),
280
+ ].sort((a, b)=>a < b ? -1 : a > b ? 1 : 0
281
+ ).findIndex((i)=>BigInt(i) === BigInt(dlcTxRequest.fundOutputSerialId)
282
+ );
283
+ dlcTransactions.refundTx = _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(dlcTxs.refundTxHex));
284
+ dlcTransactions.cets = dlcTxs.cetsHex.map((cetHex)=>{
285
+ return _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(cetHex));
245
286
  });
246
- return { dlcTransactions, messagesList };
287
+ return {
288
+ dlcTransactions,
289
+ messagesList
290
+ };
247
291
  }
248
292
  GenerateEnumMessages(oracleEvent) {
249
293
  throw Error('Only DigitDecomposition Oracle Events supported');
@@ -252,73 +296,76 @@ class BitcoinDlcProvider extends provider_1.default {
252
296
  const oracleNonces = oracleEvent.oracleNonces;
253
297
  const eventDescriptor = oracleEvent.eventDescriptor;
254
298
  const messagesList = [];
255
- oracleNonces.forEach(() => {
299
+ oracleNonces.forEach(()=>{
256
300
  const messages = [];
257
- for (let i = 0; i < eventDescriptor.base; i++) {
301
+ for(let i = 0; i < eventDescriptor.base; i++){
258
302
  const m = i.toString();
259
303
  messages.push(m);
260
304
  }
261
- messagesList.push({ messages });
305
+ messagesList.push({
306
+ messages
307
+ });
262
308
  });
263
309
  return messagesList;
264
310
  }
265
311
  GenerateMessages(oracleInfo) {
266
312
  const oracleEvent = oracleInfo.announcement.oracleEvent;
267
- switch (oracleEvent.eventDescriptor.type) {
268
- case messaging_1.MessageType.EnumEventDescriptorV0:
313
+ switch(oracleEvent.eventDescriptor.type){
314
+ case _messaging.MessageType.EnumEventDescriptorV0:
269
315
  return this.GenerateEnumMessages(oracleEvent);
270
- case messaging_1.MessageType.DigitDecompositionEventDescriptorV0:
316
+ case _messaging.MessageType.DigitDecompositionEventDescriptorV0:
271
317
  return this.GenerateDigitDecompositionMessages(oracleEvent);
272
318
  default:
273
319
  throw Error('EventDescriptor must be Enum or DigitDecomposition');
274
320
  }
275
321
  }
276
322
  GetContractOraclePairs(_contractInfo) {
277
- switch (_contractInfo.type) {
278
- case messaging_1.MessageType.ContractInfoV0: {
279
- const contractInfo = _contractInfo;
280
- return [
281
- {
282
- contractDescriptor: contractInfo.contractDescriptor,
283
- oracleInfo: contractInfo.oracleInfo,
284
- },
285
- ];
286
- }
287
- case messaging_1.MessageType.ContractInfoV1: {
288
- return _contractInfo.contractOraclePairs;
289
- }
323
+ switch(_contractInfo.type){
324
+ case _messaging.MessageType.ContractInfoV0:
325
+ {
326
+ const contractInfo = _contractInfo;
327
+ return [
328
+ {
329
+ contractDescriptor: contractInfo.contractDescriptor,
330
+ oracleInfo: contractInfo.oracleInfo
331
+ },
332
+ ];
333
+ }
334
+ case _messaging.MessageType.ContractInfoV1:
335
+ {
336
+ return _contractInfo.contractOraclePairs;
337
+ }
290
338
  default:
291
339
  throw Error('ContractInfo must be V0 or V1');
292
340
  }
293
341
  }
294
342
  async CreateCetAdaptorAndRefundSigs(_dlcOffer, _dlcAccept, _dlcTxs, messagesList, isOfferer) {
295
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
343
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
296
344
  _dlcOffer,
297
345
  _dlcAccept,
298
- _dlcTxs,
346
+ _dlcTxs
299
347
  });
300
348
  const network = await this.getConnectedNetwork();
301
- const cetsHex = dlcTxs.cets.map((cet) => cet.serialize().toString('hex'));
302
- const fundingSPK = bitcoin_1.Script.p2wpkhLock(crypto_1.hash160(isOfferer ? dlcOffer.fundingPubKey : dlcAccept.fundingPubKey))
303
- .serialize()
304
- .slice(1);
305
- const fundingAddress = bitcoinjs_lib_1.address.fromOutputScript(fundingSPK, network);
306
- const { derivationPath } = await this.getMethod('findAddress')([
307
- fundingAddress,
349
+ const cetsHex = dlcTxs.cets.map((cet)=>cet.serialize().toString('hex')
350
+ );
351
+ const fundingSPK = _bitcoin.Script.p2wpkhLock((0, _crypto).hash160(isOfferer ? dlcOffer.fundingPubKey : dlcAccept.fundingPubKey)).serialize().slice(1);
352
+ const fundingAddress = _bitcoinjsLib.address.fromOutputScript(fundingSPK, network);
353
+ const { derivationPath , } = await this.client.financewallet.quickFindAddress([
354
+ fundingAddress
308
355
  ]);
309
356
  const fundPrivateKeyPair = await this.getMethod('keyPair')(derivationPath);
310
357
  const fundPrivateKey = Buffer.from(fundPrivateKeyPair.__D).toString('hex');
311
358
  const contractOraclePairs = this.GetContractOraclePairs(dlcOffer.contractInfo);
312
359
  const indices = this.GetIndicesFromPayouts(this.GetPayouts(_dlcOffer));
313
360
  const sigs = [];
314
- for (const [index, { oracleInfo }] of contractOraclePairs.entries()) {
361
+ for (const [index, { oracleInfo }] of contractOraclePairs.entries()){
315
362
  const oracleAnnouncement = oracleInfo.announcement;
316
363
  const startingIndex = indices[index].startingMessagesIndex, endingIndex = indices[index + 1].startingMessagesIndex;
317
364
  const oracleEventMessagesList = messagesList.slice(startingIndex, endingIndex);
318
365
  const oracleEventCetsHex = cetsHex.slice(startingIndex, endingIndex);
319
366
  const chunk = 100;
320
367
  const adaptorSigRequestPromises = [];
321
- for (let i = 0, j = oracleEventMessagesList.length; i < j; i += chunk) {
368
+ for(let i = 0, j = oracleEventMessagesList.length; i < j; i += chunk){
322
369
  const tempMessagesList = oracleEventMessagesList.slice(i, i + chunk);
323
370
  const tempCetsHex = oracleEventCetsHex.slice(i, i + chunk);
324
371
  const cetSignRequest = {
@@ -331,18 +378,19 @@ class BitcoinDlcProvider extends provider_1.default {
331
378
  remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex'),
332
379
  fundInputAmount: dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats,
333
380
  oraclePubkey: oracleAnnouncement.oraclePubkey.toString('hex'),
334
- oracleRValues: oracleAnnouncement.oracleEvent.oracleNonces.map((nonce) => nonce.toString('hex')),
381
+ oracleRValues: oracleAnnouncement.oracleEvent.oracleNonces.map((nonce)=>nonce.toString('hex')
382
+ )
335
383
  };
336
- adaptorSigRequestPromises.push((async () => {
384
+ adaptorSigRequestPromises.push((async ()=>{
337
385
  const response = await this.CreateCetAdaptorSignatures(cetSignRequest);
338
386
  return response.adaptorPairs;
339
387
  })());
340
388
  }
341
389
  const adaptorPairs = (await Promise.all(adaptorSigRequestPromises)).flat();
342
- sigs.push(adaptorPairs.map((adaptorPair) => {
390
+ sigs.push(adaptorPairs.map((adaptorPair)=>{
343
391
  return {
344
392
  encryptedSig: Buffer.from(adaptorPair.signature, 'hex'),
345
- dleqProof: Buffer.from(adaptorPair.proof, 'hex'),
393
+ dleqProof: Buffer.from(adaptorPair.proof, 'hex')
346
394
  };
347
395
  }));
348
396
  }
@@ -353,175 +401,174 @@ class BitcoinDlcProvider extends provider_1.default {
353
401
  fundVout: dlcTxs.fundTxVout,
354
402
  localFundPubkey: dlcOffer.fundingPubKey.toString('hex'),
355
403
  remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex'),
356
- fundInputAmount: dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats,
404
+ fundInputAmount: dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats
357
405
  };
358
406
  const refundSignature = Buffer.from((await this.GetRawRefundTxSignature(refundSignRequest)).hex, 'hex');
359
- const cetSignatures = new messaging_1.CetAdaptorSignaturesV0();
407
+ const cetSignatures = new _messaging.CetAdaptorSignaturesV0();
360
408
  cetSignatures.sigs = sigs.flat();
361
- return { cetSignatures, refundSignature };
409
+ return {
410
+ cetSignatures,
411
+ refundSignature
412
+ };
362
413
  }
363
414
  async VerifyCetAdaptorAndRefundSigs(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs, messagesList, isOfferer) {
364
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
415
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
365
416
  _dlcOffer,
366
417
  _dlcAccept,
367
418
  _dlcSign,
368
- _dlcTxs,
419
+ _dlcTxs
369
420
  });
370
- const cetsHex = dlcTxs.cets.map((cet) => cet.serialize().toString('hex'));
421
+ const cetsHex = dlcTxs.cets.map((cet)=>cet.serialize().toString('hex')
422
+ );
371
423
  const chunk = 100;
372
424
  const contractOraclePairs = this.GetContractOraclePairs(dlcOffer.contractInfo);
373
425
  const indices = this.GetIndicesFromPayouts(this.GetPayouts(_dlcOffer));
374
- for (const [index, { oracleInfo }] of contractOraclePairs.entries()) {
426
+ for (const [index, { oracleInfo }] of contractOraclePairs.entries()){
375
427
  const oracleAnnouncement = oracleInfo.announcement;
376
428
  const startingIndex = indices[index].startingMessagesIndex, endingIndex = indices[index + 1].startingMessagesIndex;
377
429
  const oracleEventMessagesList = messagesList.slice(startingIndex, endingIndex);
378
430
  const oracleEventCetsHex = cetsHex.slice(startingIndex, endingIndex);
379
- const oracleEventSigs = (isOfferer
380
- ? dlcAccept.cetSignatures.sigs
381
- : dlcSign.cetSignatures.sigs).slice(startingIndex, endingIndex);
431
+ const oracleEventSigs = (isOfferer ? dlcAccept.cetSignatures.sigs : dlcSign.cetSignatures.sigs).slice(startingIndex, endingIndex);
382
432
  const sigsValidity = [];
383
- for (let i = 0, j = oracleEventMessagesList.length; i < j; i += chunk) {
433
+ for(let i = 0, j = oracleEventMessagesList.length; i < j; i += chunk){
384
434
  const tempMessagesList = oracleEventMessagesList.slice(i, i + chunk);
385
435
  const tempCetsHex = oracleEventCetsHex.slice(i, i + chunk);
386
436
  const tempSigs = oracleEventSigs.slice(i, i + chunk);
387
- const tempAdaptorPairs = tempSigs.map((sig) => {
437
+ const tempAdaptorPairs = tempSigs.map((sig)=>{
388
438
  return {
389
439
  signature: sig.encryptedSig.toString('hex'),
390
- proof: sig.dleqProof.toString('hex'),
440
+ proof: sig.dleqProof.toString('hex')
391
441
  };
392
442
  });
393
443
  const verifyCetAdaptorSignaturesRequest = {
394
444
  cetsHex: tempCetsHex,
395
445
  messagesList: tempMessagesList,
396
446
  oraclePubkey: oracleAnnouncement.oraclePubkey.toString('hex'),
397
- oracleRValues: oracleAnnouncement.oracleEvent.oracleNonces.map((nonce) => nonce.toString('hex')),
447
+ oracleRValues: oracleAnnouncement.oracleEvent.oracleNonces.map((nonce)=>nonce.toString('hex')
448
+ ),
398
449
  adaptorPairs: tempAdaptorPairs,
399
450
  localFundPubkey: dlcOffer.fundingPubKey.toString('hex'),
400
451
  remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex'),
401
452
  fundTxId: dlcTxs.fundTx.txId.toString(),
402
453
  fundVout: dlcTxs.fundTxVout,
403
454
  fundInputAmount: dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats,
404
- verifyRemote: isOfferer,
455
+ verifyRemote: isOfferer
405
456
  };
406
- sigsValidity.push((async () => {
457
+ sigsValidity.push((async ()=>{
407
458
  const response = await this.VerifyCetAdaptorSignatures(verifyCetAdaptorSignaturesRequest);
408
459
  return response.valid;
409
460
  })());
410
461
  }
411
- let areSigsValid = (await Promise.all(sigsValidity)).every((b) => b);
462
+ let areSigsValid = (await Promise.all(sigsValidity)).every((b)=>b
463
+ );
412
464
  const verifyRefundSigRequest = {
413
465
  refundTxHex: dlcTxs.refundTx.serialize().toString('hex'),
414
- signature: isOfferer
415
- ? dlcAccept.refundSignature.toString('hex')
416
- : dlcSign.refundSignature.toString('hex'),
466
+ signature: isOfferer ? dlcAccept.refundSignature.toString('hex') : dlcSign.refundSignature.toString('hex'),
417
467
  localFundPubkey: dlcOffer.fundingPubKey.toString('hex'),
418
468
  remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex'),
419
469
  fundTxId: dlcTxs.fundTx.txId.toString(),
420
470
  fundVout: dlcTxs.fundTxVout,
421
471
  fundInputAmount: dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats,
422
- verifyRemote: isOfferer,
472
+ verifyRemote: isOfferer
423
473
  };
424
- areSigsValid =
425
- areSigsValid &&
426
- (await this.VerifyRefundTxSignature(verifyRefundSigRequest)).valid;
474
+ areSigsValid = areSigsValid && (await this.VerifyRefundTxSignature(verifyRefundSigRequest)).valid;
427
475
  if (!areSigsValid) {
428
476
  throw new Error('Invalid signatures received');
429
477
  }
430
478
  }
431
479
  }
432
480
  async CreateFundingSigs(_dlcOffer, _dlcAccept, _dlcTxs, isOfferer) {
433
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
481
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
434
482
  _dlcOffer,
435
483
  _dlcAccept,
436
- _dlcTxs,
484
+ _dlcTxs
437
485
  });
438
- const fundingInputs = isOfferer
439
- ? dlcOffer.fundingInputs
440
- : dlcAccept.fundingInputs;
441
- const inputs = await Promise.all(fundingInputs.map(async (fundingInput) => {
486
+ const fundingInputs = isOfferer ? dlcOffer.fundingInputs : dlcAccept.fundingInputs;
487
+ const inputs = await Promise.all(fundingInputs.map(async (fundingInput)=>{
442
488
  return this.fundingInputToInput(fundingInput);
443
489
  }));
444
490
  const inputPrivKeys = await this.GetPrivKeysForInputs(inputs);
445
- const fundTxSigs = await Promise.all(inputs.map(async (input, index) => {
491
+ const fundTxSigs = await Promise.all(inputs.map(async (input, index)=>{
446
492
  const fundTxSignRequest = {
447
493
  fundTxHex: dlcTxs.fundTx.serialize().toString('hex'),
448
494
  privkey: inputPrivKeys[index],
449
495
  prevTxId: input.txid,
450
496
  prevVout: input.vout,
451
- amount: input.value,
497
+ amount: input.value
452
498
  };
453
499
  return (await this.GetRawFundTxSignature(fundTxSignRequest)).hex;
454
500
  }));
455
- const inputPubKeys = await Promise.all(inputPrivKeys.map(async (privkey) => {
501
+ const inputPubKeys = await Promise.all(inputPrivKeys.map(async (privkey)=>{
456
502
  const reqPrivKey = {
457
503
  privkey,
458
- isCompressed: true,
504
+ isCompressed: true
459
505
  };
460
- return (await this.getMethod('GetPubkeyFromPrivkey')(reqPrivKey))
461
- .pubkey;
506
+ return (await this.getMethod('GetPubkeyFromPrivkey')(reqPrivKey)).pubkey;
462
507
  }));
463
508
  const witnessElements = [];
464
- for (let i = 0; i < fundTxSigs.length; i++) {
465
- const sigWitness = new messaging_1.ScriptWitnessV0();
509
+ for(let i = 0; i < fundTxSigs.length; i++){
510
+ const sigWitness = new _messaging.ScriptWitnessV0();
466
511
  sigWitness.witness = Buffer.from(fundTxSigs[i], 'hex');
467
- const pubKeyWitness = new messaging_1.ScriptWitnessV0();
512
+ const pubKeyWitness = new _messaging.ScriptWitnessV0();
468
513
  pubKeyWitness.witness = Buffer.from(inputPubKeys[i], 'hex');
469
- witnessElements.push([sigWitness, pubKeyWitness]);
514
+ witnessElements.push([
515
+ sigWitness,
516
+ pubKeyWitness
517
+ ]);
470
518
  }
471
- const fundingSignatures = new messaging_1.FundingSignaturesV0();
519
+ const fundingSignatures = new _messaging.FundingSignaturesV0();
472
520
  fundingSignatures.witnessElements = witnessElements;
473
521
  return fundingSignatures;
474
522
  }
475
523
  async VerifyFundingSigs(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs, isOfferer) {
476
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
524
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
477
525
  _dlcOffer,
478
526
  _dlcAccept,
479
527
  _dlcSign,
480
- _dlcTxs,
528
+ _dlcTxs
481
529
  });
482
530
  const sigsValidity = [];
483
- for (let i = 0; i < dlcSign.fundingSignatures.witnessElements.length; i++) {
531
+ for(let i = 0; i < dlcSign.fundingSignatures.witnessElements.length; i++){
484
532
  const witnessElement = dlcSign.fundingSignatures.witnessElements[i];
485
533
  const signature = witnessElement[0].witness.toString('hex');
486
534
  const pubkey = witnessElement[1].witness.toString('hex');
487
- const fundingInput = isOfferer
488
- ? dlcAccept.fundingInputs[i]
489
- : dlcOffer.fundingInputs[i];
535
+ const fundingInput = isOfferer ? dlcAccept.fundingInputs[i] : dlcOffer.fundingInputs[i];
490
536
  const verifyFundSigRequest = {
491
537
  fundTxHex: dlcTxs.fundTx.serialize().toString('hex'),
492
538
  signature,
493
539
  pubkey,
494
540
  prevTxId: fundingInput.prevTx.txId.toString(),
495
541
  prevVout: fundingInput.prevTxVout,
496
- fundInputAmount: fundingInput.prevTx.outputs[fundingInput.prevTxVout].value.sats,
542
+ fundInputAmount: fundingInput.prevTx.outputs[fundingInput.prevTxVout].value.sats
497
543
  };
498
- sigsValidity.push((async () => {
544
+ sigsValidity.push((async ()=>{
499
545
  const response = await this.VerifyFundTxSignature(verifyFundSigRequest);
500
546
  return response.valid;
501
547
  })());
502
548
  }
503
- const areSigsValid = (await Promise.all(sigsValidity)).every((b) => b);
549
+ const areSigsValid = (await Promise.all(sigsValidity)).every((b)=>b
550
+ );
504
551
  if (!areSigsValid) {
505
552
  throw new Error('Invalid signatures received');
506
553
  }
507
554
  }
508
555
  async CreateFundingTx(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs, fundingSignatures) {
509
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
556
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
510
557
  _dlcOffer,
511
558
  _dlcAccept,
512
559
  _dlcSign,
513
- _dlcTxs,
560
+ _dlcTxs
514
561
  });
515
562
  const witnessElements = [
516
563
  ...dlcSign.fundingSignatures.witnessElements,
517
- ...fundingSignatures.witnessElements,
564
+ ...fundingSignatures.witnessElements,
518
565
  ];
519
566
  const fundingInputs = [
520
567
  ...dlcOffer.fundingInputs,
521
- ...dlcAccept.fundingInputs,
568
+ ...dlcAccept.fundingInputs,
522
569
  ];
523
570
  let fundTxHex = dlcTxs.fundTx.serialize().toString('hex');
524
- await Utils_1.asyncForEach(witnessElements, async (witnessElement, i) => {
571
+ await (0, _utils1).asyncForEach(witnessElements, async (witnessElement, i)=>{
525
572
  const signature = witnessElement[0].witness.toString('hex');
526
573
  const pubkey = witnessElement[1].witness.toString('hex');
527
574
  const fundingInput = fundingInputs[i];
@@ -530,133 +577,185 @@ class BitcoinDlcProvider extends provider_1.default {
530
577
  signature,
531
578
  prevTxId: fundingInput.prevTx.txId.toString(),
532
579
  prevVout: fundingInput.prevTxVout,
533
- pubkey,
580
+ pubkey
534
581
  };
535
- fundTxHex = (await this.AddSignatureToFundTransaction(addSignRequest))
536
- .hex;
582
+ fundTxHex = (await this.AddSignatureToFundTransaction(addSignRequest)).hex;
537
583
  });
538
- const fundTx = bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(fundTxHex));
584
+ const fundTx = _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(fundTxHex));
539
585
  return fundTx;
540
586
  }
541
- async FindOutcomeIndexFromHyperbolaPayoutCurvePiece(_dlcOffer, contractDescriptor, contractOraclePairIndex, hyperbolaPayoutCurvePiece, oracleAttestation, outcome) {
542
- const { dlcOffer } = Utils_1.checkTypes({ _dlcOffer });
543
- const hyperbolaCurve = core_1.HyperbolaPayoutCurve.fromPayoutCurvePiece(hyperbolaPayoutCurvePiece);
544
- const clampBN = (val) => bignumber_js_1.default.max(0, bignumber_js_1.default.min(val, dlcOffer.contractInfo.totalCollateral.toString()));
545
- const payout = clampBN(hyperbolaCurve.getPayout(outcome));
587
+ async FindOutcomeIndexFromPolynomialPayoutCurvePiece(_dlcOffer, contractDescriptor, contractOraclePairIndex, polynomialPayoutCurvePiece, oracleAttestation, outcome1) {
588
+ const { dlcOffer } = (0, _utils1).checkTypes({
589
+ _dlcOffer
590
+ });
591
+ const polynomialCurve = _core.PolynomialPayoutCurve.fromPayoutCurvePiece(polynomialPayoutCurvePiece);
592
+ const clampBN = (val)=>_bignumberJs.default.max(0, _bignumberJs.default.min(val, dlcOffer.contractInfo.totalCollateral.toString()))
593
+ ;
594
+ const payout = clampBN(polynomialCurve.getPayout(outcome1));
546
595
  const payoutResponses = this.GetPayouts(dlcOffer);
547
596
  const payoutIndexOffset = this.GetIndicesFromPayouts(payoutResponses)[contractOraclePairIndex].startingMessagesIndex;
548
- const { payoutGroups } = payoutResponses[contractOraclePairIndex];
597
+ const { payoutGroups } = payoutResponses[contractOraclePairIndex];
549
598
  const intervalsSorted = [
550
- ...contractDescriptor.roundingIntervals.intervals,
551
- ].sort((a, b) => Number(b.beginInterval) - Number(a.beginInterval));
552
- const interval = intervalsSorted.find((interval) => Number(outcome) >= Number(interval.beginInterval));
553
- const roundedPayout = BigInt(clampBN(new bignumber_js_1.default(core_1.roundPayout(payout, interval.roundingMod).toString())).toString());
554
- const outcomesFormatted = oracleAttestation.outcomes.map((outcome) => parseInt(outcome));
599
+ ...contractDescriptor.roundingIntervals.intervals,
600
+ ].sort((a, b)=>Number(b.beginInterval) - Number(a.beginInterval)
601
+ );
602
+ const interval1 = intervalsSorted.find((interval)=>Number(outcome1) >= Number(interval.beginInterval)
603
+ );
604
+ const roundedPayout = BigInt(clampBN(new _bignumberJs.default((0, _core).roundPayout(payout, interval1.roundingMod).toString())).toString());
605
+ const outcomesFormatted = oracleAttestation.outcomes.map((outcome)=>parseInt(outcome)
606
+ );
555
607
  let index = 0;
556
608
  let groupIndex = -1;
557
609
  let groupLength = 0;
558
- for (const payoutGroup of payoutGroups) {
610
+ for (const payoutGroup of payoutGroups){
559
611
  if (payoutGroup.payout === roundedPayout) {
560
- groupIndex = payoutGroup.groups.findIndex((group) => {
561
- return group.every((msg, i) => msg === outcomesFormatted[i]);
612
+ groupIndex = payoutGroup.groups.findIndex((group)=>{
613
+ return group.every((msg, i)=>msg === outcomesFormatted[i]
614
+ );
562
615
  });
563
- if (groupIndex === -1)
564
- throw Error('Failed to Find OutcomeIndex From HyperbolaPayoutCurvePiece. \
616
+ if (groupIndex === -1) throw Error('Failed to Find OutcomeIndex From PolynomialPayoutCurvePiece. \
565
617
  Payout Group found but incorrect group index');
566
618
  index += groupIndex;
567
619
  groupLength = payoutGroup.groups[groupIndex].length;
568
620
  break;
621
+ } else {
622
+ index += payoutGroup.groups.length;
569
623
  }
570
- else {
624
+ }
625
+ if (groupIndex === -1) throw Error('Failed to Find OutcomeIndex From PolynomialPayoutCurvePiece. \
626
+ Payout Group not found');
627
+ return {
628
+ index: payoutIndexOffset + index,
629
+ groupLength
630
+ };
631
+ }
632
+ async FindOutcomeIndexFromHyperbolaPayoutCurvePiece(_dlcOffer, contractDescriptor, contractOraclePairIndex, hyperbolaPayoutCurvePiece, oracleAttestation, outcome2) {
633
+ const { dlcOffer } = (0, _utils1).checkTypes({
634
+ _dlcOffer
635
+ });
636
+ const hyperbolaCurve = _core.HyperbolaPayoutCurve.fromPayoutCurvePiece(hyperbolaPayoutCurvePiece);
637
+ const clampBN = (val)=>_bignumberJs.default.max(0, _bignumberJs.default.min(val, dlcOffer.contractInfo.totalCollateral.toString()))
638
+ ;
639
+ const payout = clampBN(hyperbolaCurve.getPayout(outcome2));
640
+ const payoutResponses = this.GetPayouts(dlcOffer);
641
+ const payoutIndexOffset = this.GetIndicesFromPayouts(payoutResponses)[contractOraclePairIndex].startingMessagesIndex;
642
+ const { payoutGroups } = payoutResponses[contractOraclePairIndex];
643
+ const intervalsSorted = [
644
+ ...contractDescriptor.roundingIntervals.intervals,
645
+ ].sort((a, b)=>Number(b.beginInterval) - Number(a.beginInterval)
646
+ );
647
+ const interval2 = intervalsSorted.find((interval)=>Number(outcome2) >= Number(interval.beginInterval)
648
+ );
649
+ const roundedPayout = BigInt(clampBN(new _bignumberJs.default((0, _core).roundPayout(payout, interval2.roundingMod).toString())).toString());
650
+ const outcomesFormatted = oracleAttestation.outcomes.map((outcome)=>parseInt(outcome)
651
+ );
652
+ let index = 0;
653
+ let groupIndex = -1;
654
+ let groupLength = 0;
655
+ for (const payoutGroup of payoutGroups){
656
+ if (payoutGroup.payout === roundedPayout) {
657
+ groupIndex = payoutGroup.groups.findIndex((group)=>{
658
+ return group.every((msg, i)=>msg === outcomesFormatted[i]
659
+ );
660
+ });
661
+ if (groupIndex === -1) throw Error('Failed to Find OutcomeIndex From HyperbolaPayoutCurvePiece. \
662
+ Payout Group found but incorrect group index');
663
+ index += groupIndex;
664
+ groupLength = payoutGroup.groups[groupIndex].length;
665
+ break;
666
+ } else {
571
667
  index += payoutGroup.groups.length;
572
668
  }
573
669
  }
574
- if (groupIndex === -1)
575
- throw Error('Failed to Find OutcomeIndex From HyperbolaPayoutCurvePiece. \
670
+ if (groupIndex === -1) throw Error('Failed to Find OutcomeIndex From HyperbolaPayoutCurvePiece. \
576
671
  Payout Group not found');
577
- return { index: payoutIndexOffset + index, groupLength };
672
+ return {
673
+ index: payoutIndexOffset + index,
674
+ groupLength
675
+ };
578
676
  }
579
677
  async FindOutcomeIndex(_dlcOffer, oracleAttestation) {
580
- const { dlcOffer } = Utils_1.checkTypes({ _dlcOffer });
678
+ const { dlcOffer } = (0, _utils1).checkTypes({
679
+ _dlcOffer
680
+ });
581
681
  const contractOraclePairs = this.GetContractOraclePairs(dlcOffer.contractInfo);
582
- const contractOraclePairIndex = contractOraclePairs.findIndex(({ oracleInfo }) => oracleInfo.announcement.oracleEvent.eventId ===
583
- oracleAttestation.eventId);
584
- assert_1.default(contractOraclePairIndex !== -1, 'OracleAttestation must be for an existing OracleEvent');
682
+ const contractOraclePairIndex = contractOraclePairs.findIndex(({ oracleInfo })=>oracleInfo.announcement.oracleEvent.eventId === oracleAttestation.eventId
683
+ );
684
+ (0, _assert).default(contractOraclePairIndex !== -1, 'OracleAttestation must be for an existing OracleEvent');
585
685
  const contractOraclePair = contractOraclePairs[contractOraclePairIndex];
586
- const { contractDescriptor: _contractDescriptor, oracleInfo, } = contractOraclePair;
587
- assert_1.default(_contractDescriptor.type === messaging_1.MessageType.ContractDescriptorV1, 'ContractDescriptor must be V1');
686
+ const { contractDescriptor: _contractDescriptor , oracleInfo: oracleInfo1 , } = contractOraclePair;
687
+ (0, _assert).default(_contractDescriptor.type === _messaging.MessageType.ContractDescriptorV1, 'ContractDescriptor must be V1');
588
688
  const contractDescriptor = _contractDescriptor;
589
689
  const _payoutFunction = contractDescriptor.payoutFunction;
590
- assert_1.default(_payoutFunction.type === messaging_1.MessageType.PayoutFunctionV0, 'PayoutFunction must be V0');
591
- const eventDescriptor = oracleInfo.announcement.oracleEvent
592
- .eventDescriptor;
690
+ (0, _assert).default(_payoutFunction.type === _messaging.MessageType.PayoutFunctionV0, 'PayoutFunction must be V0');
691
+ const eventDescriptor = oracleInfo1.announcement.oracleEvent.eventDescriptor;
593
692
  const payoutFunction = _payoutFunction;
594
693
  const base = eventDescriptor.base;
595
- const outcome = [...oracleAttestation.outcomes]
596
- .reverse()
597
- .reduce((acc, val, i) => acc + Number(val) * base ** i, 0);
598
- const piecesSorted = payoutFunction.pieces.sort((a, b) => Number(b.endpoint) - Number(a.endpoint));
599
- const piece = piecesSorted.find((piece) => outcome < piece.endpoint);
600
- switch (piece.payoutCurvePiece.type) {
601
- case messaging_1.MessageType.PolynomialPayoutCurvePiece:
602
- throw Error('Polynomial Curve Piece not yet supported');
603
- case messaging_1.MessageType.HyperbolaPayoutCurvePiece:
604
- return this.FindOutcomeIndexFromHyperbolaPayoutCurvePiece(dlcOffer, contractDescriptor, contractOraclePairIndex, piece.payoutCurvePiece, oracleAttestation, BigInt(outcome));
605
- case messaging_1.MessageType.OldHyperbolaPayoutCurvePiece:
606
- return this.FindOutcomeIndexFromHyperbolaPayoutCurvePiece(dlcOffer, contractDescriptor, contractOraclePairIndex, piece.payoutCurvePiece, oracleAttestation, BigInt(outcome));
694
+ const outcome = [
695
+ ...oracleAttestation.outcomes
696
+ ].reverse().reduce((acc, val, i)=>acc + Number(val) * base ** i
697
+ , 0);
698
+ const piecesSorted = payoutFunction.pieces.sort((a, b)=>Number(a.endpoint) - Number(b.endpoint)
699
+ );
700
+ const piece1 = piecesSorted.find((piece)=>outcome < piece.endpoint
701
+ );
702
+ switch(piece1.payoutCurvePiece.type){
703
+ case _messaging.MessageType.PolynomialPayoutCurvePiece:
704
+ return this.FindOutcomeIndexFromPolynomialPayoutCurvePiece(dlcOffer, contractDescriptor, contractOraclePairIndex, piece1.payoutCurvePiece, oracleAttestation, BigInt(outcome));
705
+ case _messaging.MessageType.HyperbolaPayoutCurvePiece:
706
+ return this.FindOutcomeIndexFromHyperbolaPayoutCurvePiece(dlcOffer, contractDescriptor, contractOraclePairIndex, piece1.payoutCurvePiece, oracleAttestation, BigInt(outcome));
707
+ case _messaging.MessageType.OldHyperbolaPayoutCurvePiece:
708
+ return this.FindOutcomeIndexFromHyperbolaPayoutCurvePiece(dlcOffer, contractDescriptor, contractOraclePairIndex, piece1.payoutCurvePiece, oracleAttestation, BigInt(outcome));
607
709
  default:
608
710
  throw Error('Must be Hyperbola or Polynomial curve piece');
609
711
  }
610
712
  }
611
713
  ValidateEvent(_dlcOffer, oracleAttestation) {
612
- const { dlcOffer } = Utils_1.checkTypes({
613
- _dlcOffer,
714
+ const { dlcOffer } = (0, _utils1).checkTypes({
715
+ _dlcOffer
614
716
  });
615
- switch (dlcOffer.contractInfo.type) {
616
- case messaging_1.MessageType.ContractInfoV0: {
617
- const contractInfo = dlcOffer.contractInfo;
618
- switch (contractInfo.contractDescriptor.type) {
619
- case messaging_1.MessageType.ContractDescriptorV0:
620
- throw Error('ContractDescriptorV0 not yet supported');
621
- case messaging_1.MessageType.ContractDescriptorV1: {
622
- const oracleInfo = contractInfo.oracleInfo;
623
- if (oracleInfo.announcement.oracleEvent.eventId !==
624
- oracleAttestation.eventId)
625
- throw Error('Incorrect Oracle Attestation. Event Id must match.');
626
- break;
717
+ switch(dlcOffer.contractInfo.type){
718
+ case _messaging.MessageType.ContractInfoV0:
719
+ {
720
+ const contractInfo = dlcOffer.contractInfo;
721
+ switch(contractInfo.contractDescriptor.type){
722
+ case _messaging.MessageType.ContractDescriptorV0:
723
+ throw Error('ContractDescriptorV0 not yet supported');
724
+ case _messaging.MessageType.ContractDescriptorV1:
725
+ {
726
+ const oracleInfo = contractInfo.oracleInfo;
727
+ if (oracleInfo.announcement.oracleEvent.eventId !== oracleAttestation.eventId) throw Error('Incorrect Oracle Attestation. Event Id must match.');
728
+ break;
729
+ }
730
+ default:
731
+ throw Error('ConractDescriptor must be V0 or V1');
627
732
  }
628
- default:
629
- throw Error('ConractDescriptor must be V0 or V1');
733
+ break;
734
+ }
735
+ case _messaging.MessageType.ContractInfoV1:
736
+ {
737
+ const contractInfo = dlcOffer.contractInfo;
738
+ const attestedOracleEvent = contractInfo.contractOraclePairs.find(({ oracleInfo })=>oracleInfo.announcement.oracleEvent.eventId === oracleAttestation.eventId
739
+ );
740
+ if (!attestedOracleEvent) throw Error('Oracle event of attestation not found.');
741
+ break;
630
742
  }
631
- break;
632
- }
633
- case messaging_1.MessageType.ContractInfoV1: {
634
- const contractInfo = dlcOffer.contractInfo;
635
- const attestedOracleEvent = contractInfo.contractOraclePairs.find(({ oracleInfo }) => oracleInfo.announcement.oracleEvent.eventId ===
636
- oracleAttestation.eventId);
637
- if (!attestedOracleEvent)
638
- throw Error('Oracle event of attestation not found.');
639
- break;
640
- }
641
743
  default:
642
744
  throw Error('ContractInfo must be V0 or V1');
643
745
  }
644
746
  }
645
747
  async FindAndSignCet(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs, oracleAttestation, isOfferer) {
646
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
748
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
647
749
  _dlcOffer,
648
750
  _dlcAccept,
649
751
  _dlcSign,
650
- _dlcTxs,
752
+ _dlcTxs
651
753
  });
652
- if (isOfferer === undefined)
653
- isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
654
- const { index: outcomeIndex, groupLength } = await this.FindOutcomeIndex(dlcOffer, oracleAttestation);
754
+ if (isOfferer === undefined) isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
755
+ const { index: outcomeIndex , groupLength } = await this.FindOutcomeIndex(dlcOffer, oracleAttestation);
655
756
  const fundPrivateKey = await this.GetFundPrivateKey(dlcOffer, dlcAccept, isOfferer);
656
757
  const sliceIndex = -(oracleAttestation.signatures.length - groupLength);
657
- const oracleSignatures = sliceIndex === 0
658
- ? oracleAttestation.signatures
659
- : oracleAttestation.signatures.slice(0, sliceIndex);
758
+ const oracleSignatures = sliceIndex === 0 ? oracleAttestation.signatures : oracleAttestation.signatures.slice(0, sliceIndex);
660
759
  const signCetRequest = {
661
760
  cetHex: dlcTxs.cets[outcomeIndex].serialize().toString('hex'),
662
761
  fundPrivkey: fundPrivateKey,
@@ -664,26 +763,23 @@ Payout Group not found');
664
763
  fundVout: dlcTxs.fundTxVout,
665
764
  localFundPubkey: dlcOffer.fundingPubKey.toString('hex'),
666
765
  remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex'),
667
- oracleSignatures: oracleSignatures.map((sig) => sig.toString('hex')),
766
+ oracleSignatures: oracleSignatures.map((sig)=>sig.toString('hex')
767
+ ),
668
768
  fundInputAmount: dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats,
669
- adaptorSignature: isOfferer
670
- ? dlcAccept.cetSignatures.sigs[outcomeIndex].encryptedSig.toString('hex')
671
- : dlcSign.cetSignatures.sigs[outcomeIndex].encryptedSig.toString('hex'),
769
+ adaptorSignature: isOfferer ? dlcAccept.cetSignatures.sigs[outcomeIndex].encryptedSig.toString('hex') : dlcSign.cetSignatures.sigs[outcomeIndex].encryptedSig.toString('hex')
672
770
  };
673
771
  const finalCet = (await this.SignCet(signCetRequest)).hex;
674
- return bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(finalCet));
772
+ return _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(finalCet));
675
773
  }
676
774
  async GetFundAddress(dlcOffer, dlcAccept, isOfferer) {
677
775
  const network = await this.getConnectedNetwork();
678
- const fundingSPK = bitcoin_1.Script.p2wpkhLock(crypto_1.hash160(isOfferer ? dlcOffer.fundingPubKey : dlcAccept.fundingPubKey))
679
- .serialize()
680
- .slice(1);
681
- const fundingAddress = bitcoinjs_lib_1.address.fromOutputScript(fundingSPK, network);
776
+ const fundingSPK = _bitcoin.Script.p2wpkhLock((0, _crypto).hash160(isOfferer ? dlcOffer.fundingPubKey : dlcAccept.fundingPubKey)).serialize().slice(1);
777
+ const fundingAddress = _bitcoinjsLib.address.fromOutputScript(fundingSPK, network);
682
778
  return fundingAddress;
683
779
  }
684
780
  async GetFundKeyPair(dlcOffer, dlcAccept, isOfferer) {
685
781
  const fundingAddress = await this.GetFundAddress(dlcOffer, dlcAccept, isOfferer);
686
- const { derivationPath } = await this.getMethod('getWalletAddress')(fundingAddress);
782
+ const { derivationPath } = await this.getMethod('getWalletAddress')(fundingAddress);
687
783
  const keyPair = await this.getMethod('keyPair')(derivationPath);
688
784
  return keyPair;
689
785
  }
@@ -692,57 +788,49 @@ Payout Group not found');
692
788
  return Buffer.from(fundPrivateKeyPair.privateKey).toString('hex');
693
789
  }
694
790
  async CreateCloseRawTxs(_dlcOffer, _dlcAccept, _dlcTxs, closeInputAmount, isOfferer, _dlcCloses = [], fundingInputs, initiatorPayouts) {
695
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
791
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
696
792
  _dlcOffer,
697
793
  _dlcAccept,
698
- _dlcTxs,
794
+ _dlcTxs
699
795
  });
700
796
  const network = await this.getConnectedNetwork();
701
797
  let finalizer;
702
798
  if (_dlcCloses.length === 0) {
703
- finalizer = new core_1.DualClosingTxFinalizer(fundingInputs, dlcOffer.payoutSPK, dlcAccept.payoutSPK, dlcOffer.feeRatePerVb);
799
+ finalizer = new _core.DualClosingTxFinalizer(fundingInputs, dlcOffer.payoutSPK, dlcAccept.payoutSPK, dlcOffer.feeRatePerVb);
704
800
  }
705
801
  const rawTransactionRequestPromises = [];
706
802
  const rawCloseTxs = [];
707
803
  const numPayouts = _dlcCloses.length === 0 ? initiatorPayouts.length : _dlcCloses.length;
708
- for (let i = 0; i < numPayouts; i++) {
804
+ for(let i = 0; i < numPayouts; i++){
709
805
  let offerPayoutValue = BigInt(0);
710
806
  let acceptPayoutValue = BigInt(0);
711
807
  if (_dlcCloses.length === 0) {
712
808
  const payout = initiatorPayouts[i];
713
- const payoutMinusOfferFees = finalizer.offerInitiatorFees > payout
714
- ? BigInt(0)
715
- : payout - finalizer.offerInitiatorFees;
716
- const collateralMinusPayout = payout > dlcOffer.contractInfo.totalCollateral
717
- ? BigInt(0)
718
- : dlcOffer.contractInfo.totalCollateral - payout;
719
- offerPayoutValue = isOfferer
720
- ? closeInputAmount + payoutMinusOfferFees
721
- : collateralMinusPayout;
722
- acceptPayoutValue = isOfferer
723
- ? collateralMinusPayout
724
- : closeInputAmount + payoutMinusOfferFees;
725
- }
726
- else {
727
- const dlcClose = Utils_1.checkTypes({ _dlcClose: _dlcCloses[i] }).dlcClose;
809
+ const payoutMinusOfferFees = finalizer.offerInitiatorFees > payout ? BigInt(0) : payout - finalizer.offerInitiatorFees;
810
+ const collateralMinusPayout = payout > dlcOffer.contractInfo.totalCollateral ? BigInt(0) : dlcOffer.contractInfo.totalCollateral - payout;
811
+ offerPayoutValue = isOfferer ? closeInputAmount + payoutMinusOfferFees : collateralMinusPayout;
812
+ acceptPayoutValue = isOfferer ? collateralMinusPayout : closeInputAmount + payoutMinusOfferFees;
813
+ } else {
814
+ const dlcClose = (0, _utils1).checkTypes({
815
+ _dlcClose: _dlcCloses[i]
816
+ }).dlcClose;
728
817
  offerPayoutValue = dlcClose.offerPayoutSatoshis;
729
818
  acceptPayoutValue = dlcClose.acceptPayoutSatoshis;
730
819
  }
731
820
  const txOuts = [];
732
821
  if (Number(offerPayoutValue) > 0) {
733
822
  txOuts.push({
734
- address: bitcoinjs_lib_1.address.fromOutputScript(dlcOffer.payoutSPK, network),
735
- amount: Number(offerPayoutValue),
823
+ address: _bitcoinjsLib.address.fromOutputScript(dlcOffer.payoutSPK, network),
824
+ amount: Number(offerPayoutValue)
736
825
  });
737
826
  }
738
827
  if (Number(acceptPayoutValue) > 0) {
739
828
  txOuts.push({
740
- address: bitcoinjs_lib_1.address.fromOutputScript(dlcAccept.payoutSPK, network),
741
- amount: Number(acceptPayoutValue),
829
+ address: _bitcoinjsLib.address.fromOutputScript(dlcAccept.payoutSPK, network),
830
+ amount: Number(acceptPayoutValue)
742
831
  });
743
832
  }
744
- if (dlcOffer.payoutSerialId > dlcAccept.payoutSerialId)
745
- txOuts.reverse();
833
+ if (dlcOffer.payoutSerialId > dlcAccept.payoutSerialId) txOuts.reverse();
746
834
  const rawTransactionRequest = {
747
835
  version: 2,
748
836
  locktime: 0,
@@ -750,12 +838,12 @@ Payout Group not found');
750
838
  {
751
839
  txid: dlcTxs.fundTx.txId.serialize().reverse().toString('hex'),
752
840
  vout: dlcTxs.fundTxVout,
753
- sequence: 0,
754
- },
841
+ sequence: 0
842
+ },
755
843
  ],
756
- txouts: txOuts,
844
+ txouts: txOuts
757
845
  };
758
- rawTransactionRequestPromises.push((async () => {
846
+ rawTransactionRequestPromises.push((async ()=>{
759
847
  const response = await this.getMethod('CreateRawTransaction')(rawTransactionRequest);
760
848
  return response.hex;
761
849
  })());
@@ -765,27 +853,31 @@ Payout Group not found');
765
853
  return rawCloseTxs.flat();
766
854
  }
767
855
  async CreateSignatureHashes(_dlcOffer, _dlcAccept, _dlcTxs, rawCloseTxs) {
768
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
856
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
769
857
  _dlcOffer,
770
858
  _dlcAccept,
771
- _dlcTxs,
859
+ _dlcTxs
772
860
  });
773
861
  const network = await this.getConnectedNetwork();
774
- const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1
775
- ? [dlcOffer.fundingPubKey, dlcAccept.fundingPubKey]
776
- : [dlcAccept.fundingPubKey, dlcOffer.fundingPubKey];
777
- const p2ms = bitcoinjs_lib_1.payments.p2ms({
862
+ const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1 ? [
863
+ dlcOffer.fundingPubKey,
864
+ dlcAccept.fundingPubKey
865
+ ] : [
866
+ dlcAccept.fundingPubKey,
867
+ dlcOffer.fundingPubKey
868
+ ];
869
+ const p2ms = _bitcoinjsLib.payments.p2ms({
778
870
  m: 2,
779
871
  pubkeys: fundingPubKeys,
780
- network,
872
+ network
781
873
  });
782
- const paymentVariant = bitcoinjs_lib_1.payments.p2wsh({
874
+ const paymentVariant = _bitcoinjsLib.payments.p2wsh({
783
875
  redeem: p2ms,
784
- network,
876
+ network
785
877
  });
786
878
  const sigHashRequestPromises = [];
787
879
  const sigHashes = [];
788
- for (let i = 0; i < rawCloseTxs.length; i++) {
880
+ for(let i = 0; i < rawCloseTxs.length; i++){
789
881
  const rawTx = rawCloseTxs[i];
790
882
  const sigHashRequest = {
791
883
  tx: rawTx,
@@ -794,15 +886,15 @@ Payout Group not found');
794
886
  vout: dlcTxs.fundTxVout,
795
887
  keyData: {
796
888
  hex: paymentVariant.redeem.output.toString('hex'),
797
- type: 'redeem_script',
889
+ type: 'redeem_script'
798
890
  },
799
891
  amount: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats),
800
892
  hashType: 'p2wsh',
801
893
  sighashType: 'all',
802
- sighashAnyoneCanPay: false,
803
- },
894
+ sighashAnyoneCanPay: false
895
+ }
804
896
  };
805
- sigHashRequestPromises.push((async () => {
897
+ sigHashRequestPromises.push((async ()=>{
806
898
  const response = await this.getMethod('CreateSignatureHash')(sigHashRequest);
807
899
  return response.sighash;
808
900
  })());
@@ -814,18 +906,18 @@ Payout Group not found');
814
906
  async CalculateEcSignatureHashes(sigHashes, privKey) {
815
907
  const cfdNetwork = await this.GetCfdNetwork();
816
908
  const sigsRequestPromises = [];
817
- for (let i = 0; i < sigHashes.length; i++) {
909
+ for(let i = 0; i < sigHashes.length; i++){
818
910
  const sigHash = sigHashes[i];
819
911
  const calculateEcSignatureRequest = {
820
912
  sighash: sigHash,
821
913
  privkeyData: {
822
914
  privkey: privKey,
823
915
  wif: false,
824
- network: cfdNetwork,
916
+ network: cfdNetwork
825
917
  },
826
- isGrindR: true,
918
+ isGrindR: true
827
919
  };
828
- sigsRequestPromises.push((async () => {
920
+ sigsRequestPromises.push((async ()=>{
829
921
  const response = await this.getMethod('CalculateEcSignature')(calculateEcSignatureRequest);
830
922
  return response.signature;
831
923
  })());
@@ -834,28 +926,35 @@ Payout Group not found');
834
926
  return sigs.flat();
835
927
  }
836
928
  async VerifySignatures(_dlcOffer, _dlcAccept, _dlcTxs, _dlcCloses, rawCloseTxs, isOfferer) {
837
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
929
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
838
930
  _dlcOffer,
839
931
  _dlcAccept,
840
- _dlcTxs,
932
+ _dlcTxs
841
933
  });
842
- const dlcCloses = _dlcCloses.map((_dlcClose) => Utils_1.checkTypes({ _dlcClose }).dlcClose);
934
+ const dlcCloses = _dlcCloses.map((_dlcClose)=>(0, _utils1).checkTypes({
935
+ _dlcClose
936
+ }).dlcClose
937
+ );
843
938
  const network = await this.getConnectedNetwork();
844
- const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1
845
- ? [dlcOffer.fundingPubKey, dlcAccept.fundingPubKey]
846
- : [dlcAccept.fundingPubKey, dlcOffer.fundingPubKey];
847
- const p2ms = bitcoinjs_lib_1.payments.p2ms({
939
+ const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1 ? [
940
+ dlcOffer.fundingPubKey,
941
+ dlcAccept.fundingPubKey
942
+ ] : [
943
+ dlcAccept.fundingPubKey,
944
+ dlcOffer.fundingPubKey
945
+ ];
946
+ const p2ms = _bitcoinjsLib.payments.p2ms({
848
947
  m: 2,
849
948
  pubkeys: fundingPubKeys,
850
- network,
949
+ network
851
950
  });
852
- const paymentVariant = bitcoinjs_lib_1.payments.p2wsh({
951
+ const paymentVariant = _bitcoinjsLib.payments.p2wsh({
853
952
  redeem: p2ms,
854
- network,
953
+ network
855
954
  });
856
955
  const pubkey = isOfferer ? dlcAccept.fundingPubKey : dlcOffer.fundingPubKey;
857
956
  const sigsValidity = [];
858
- for (let i = 0; i < rawCloseTxs.length; i++) {
957
+ for(let i = 0; i < rawCloseTxs.length; i++){
859
958
  const rawTx = rawCloseTxs[i];
860
959
  const dlcClose = dlcCloses[i];
861
960
  const verifySignatureRequest = {
@@ -869,67 +968,64 @@ Payout Group not found');
869
968
  hashType: 'p2wsh',
870
969
  sighashType: 'all',
871
970
  sighashAnyoneCanPay: false,
872
- amount: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats),
873
- },
971
+ amount: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats)
972
+ }
874
973
  };
875
- sigsValidity.push((async () => {
974
+ sigsValidity.push((async ()=>{
876
975
  const response = await this.getMethod('VerifySignature')(verifySignatureRequest);
877
976
  return response.success;
878
977
  })());
879
978
  }
880
- const areSigsValid = (await Promise.all(sigsValidity)).every((b) => b);
979
+ const areSigsValid = (await Promise.all(sigsValidity)).every((b)=>b
980
+ );
881
981
  return areSigsValid;
882
982
  }
883
983
  /**
884
- * Check whether wallet is offerer of DlcOffer or DlcAccept
885
- * @param dlcOffer Dlc Offer Message
886
- * @param dlcAccept Dlc Accept Message
887
- * @returns {Promise<boolean>}
888
- */
889
- async isOfferer(_dlcOffer, _dlcAccept) {
890
- const { dlcOffer, dlcAccept } = Utils_1.checkTypes({
984
+ * Check whether wallet is offerer of DlcOffer or DlcAccept
985
+ * @param dlcOffer Dlc Offer Message
986
+ * @param dlcAccept Dlc Accept Message
987
+ * @returns {Promise<boolean>}
988
+ */ async isOfferer(_dlcOffer, _dlcAccept) {
989
+ const { dlcOffer , dlcAccept } = (0, _utils1).checkTypes({
891
990
  _dlcOffer,
892
- _dlcAccept,
991
+ _dlcAccept
893
992
  });
894
993
  const network = await this.getConnectedNetwork();
895
- const offerFundingSPK = bitcoin_1.Script.p2wpkhLock(crypto_1.hash160(dlcOffer.fundingPubKey))
896
- .serialize()
897
- .slice(1);
898
- const acceptFundingSPK = bitcoin_1.Script.p2wpkhLock(crypto_1.hash160(dlcAccept.fundingPubKey))
899
- .serialize()
900
- .slice(1);
901
- const offerFundingAddress = bitcoinjs_lib_1.address.fromOutputScript(offerFundingSPK, network);
902
- const acceptFundingAddress = bitcoinjs_lib_1.address.fromOutputScript(acceptFundingSPK, network);
903
- let walletAddress = await this.getMethod('findAddress')([
904
- offerFundingAddress,
994
+ const offerFundingSPK = _bitcoin.Script.p2wpkhLock((0, _crypto).hash160(dlcOffer.fundingPubKey)).serialize().slice(1);
995
+ const acceptFundingSPK = _bitcoin.Script.p2wpkhLock((0, _crypto).hash160(dlcAccept.fundingPubKey)).serialize().slice(1);
996
+ const offerFundingAddress = _bitcoinjsLib.address.fromOutputScript(offerFundingSPK, network);
997
+ const acceptFundingAddress = _bitcoinjsLib.address.fromOutputScript(acceptFundingSPK, network);
998
+ let walletAddress = await this.client.financewallet.quickFindAddress([
999
+ offerFundingAddress
905
1000
  ]);
906
- if (walletAddress)
907
- return true;
908
- walletAddress = await this.getMethod('findAddress')([acceptFundingAddress]);
909
- if (walletAddress)
910
- return false;
1001
+ if (walletAddress) return true;
1002
+ walletAddress = await this.client.financewallet.quickFindAddress([
1003
+ acceptFundingAddress,
1004
+ ]);
1005
+ if (walletAddress) return false;
911
1006
  throw Error('Wallet Address not found for DlcOffer or DlcAccept');
912
1007
  }
913
1008
  /**
914
- * Create DLC Offer Message
915
- * @param contractInfo ContractInfo TLV (V0 or V1)
916
- * @param offerCollateralSatoshis Amount DLC Initiator is putting into the contract
917
- * @param feeRatePerVb Fee rate in satoshi per virtual byte that both sides use to compute fees in funding tx
918
- * @param cetLocktime The nLockTime to be put on CETs
919
- * @param refundLocktime The nLockTime to be put on the refund transaction
920
- * @returns {Promise<DlcOffer>}
921
- */
922
- async createDlcOffer(contractInfo, offerCollateralSatoshis, feeRatePerVb, cetLocktime, refundLocktime, fixedInputs) {
1009
+ * Create DLC Offer Message
1010
+ * @param contractInfo ContractInfo TLV (V0 or V1)
1011
+ * @param offerCollateralSatoshis Amount DLC Initiator is putting into the contract
1012
+ * @param feeRatePerVb Fee rate in satoshi per virtual byte that both sides use to compute fees in funding tx
1013
+ * @param cetLocktime The nLockTime to be put on CETs
1014
+ * @param refundLocktime The nLockTime to be put on the refund transaction
1015
+ * @returns {Promise<DlcOffer>}
1016
+ */ async createDlcOffer(contractInfo, offerCollateralSatoshis, feeRatePerVb, cetLocktime, refundLocktime, fixedInputs) {
923
1017
  contractInfo.validate();
924
1018
  const network = await this.getConnectedNetwork();
925
- const dlcOffer = new messaging_1.DlcOfferV0();
926
- const { fundingPubKey, payoutSPK, payoutSerialId, fundingInputs: _fundingInputs, changeSPK, changeSerialId, } = await this.Initialize(offerCollateralSatoshis, feeRatePerVb, fixedInputs);
927
- _fundingInputs.forEach((input) => assert_1.default(input.type === messaging_1.MessageType.FundingInputV0, 'FundingInput must be V0'));
928
- const fundingInputs = _fundingInputs.map((input) => input);
929
- const fundOutputSerialId = Utils_1.generateSerialId();
930
- assert_1.default(changeSerialId !== fundOutputSerialId, 'changeSerialId cannot equal the fundOutputSerialId');
1019
+ const dlcOffer = new _messaging.DlcOfferV0();
1020
+ const { fundingPubKey , payoutSPK , payoutSerialId , fundingInputs: _fundingInputs , changeSPK , changeSerialId , } = await this.Initialize(offerCollateralSatoshis, feeRatePerVb, fixedInputs);
1021
+ _fundingInputs.forEach((input)=>(0, _assert).default(input.type === _messaging.MessageType.FundingInputV0, 'FundingInput must be V0')
1022
+ );
1023
+ const fundingInputs = _fundingInputs.map((input)=>input
1024
+ );
1025
+ const fundOutputSerialId = (0, _utils1).generateSerialId();
1026
+ (0, _assert).default(changeSerialId !== fundOutputSerialId, 'changeSerialId cannot equal the fundOutputSerialId');
931
1027
  dlcOffer.contractFlags = Buffer.from('00', 'hex');
932
- dlcOffer.chainHash = bitcoin_networks_1.chainHashFromNetwork(network);
1028
+ dlcOffer.chainHash = (0, _bitcoinNetworks).chainHashFromNetwork(network);
933
1029
  dlcOffer.contractInfo = contractInfo;
934
1030
  dlcOffer.fundingPubKey = fundingPubKey;
935
1031
  dlcOffer.payoutSPK = payoutSPK;
@@ -942,9 +1038,9 @@ Payout Group not found');
942
1038
  dlcOffer.feeRatePerVb = feeRatePerVb;
943
1039
  dlcOffer.cetLocktime = cetLocktime;
944
1040
  dlcOffer.refundLocktime = refundLocktime;
945
- assert_1.default((() => {
946
- const finalizer = new core_1.DualFundingTxFinalizer(dlcOffer.fundingInputs, dlcOffer.payoutSPK, dlcOffer.changeSPK, null, null, null, dlcOffer.feeRatePerVb);
947
- const funding = fundingInputs.reduce((total, input) => {
1041
+ (0, _assert).default((()=>{
1042
+ const finalizer = new _core.DualFundingTxFinalizer(dlcOffer.fundingInputs, dlcOffer.payoutSPK, dlcOffer.changeSPK, null, null, null, dlcOffer.feeRatePerVb);
1043
+ const funding = fundingInputs.reduce((total, input)=>{
948
1044
  return total + input.prevTx.outputs[input.prevTxVout].value.sats;
949
1045
  }, BigInt(0));
950
1046
  return funding >= offerCollateralSatoshis + finalizer.offerFees;
@@ -953,24 +1049,25 @@ Payout Group not found');
953
1049
  return dlcOffer;
954
1050
  }
955
1051
  /**
956
- * Accept DLC Offer
957
- * @param _dlcOffer Dlc Offer Message
958
- * @param fixedInputs Optional inputs to use for Funding Inputs
959
- * @returns {Promise<AcceptDlcOfferResponse}
960
- */
961
- async acceptDlcOffer(_dlcOffer, fixedInputs) {
962
- const { dlcOffer } = Utils_1.checkTypes({ _dlcOffer });
1052
+ * Accept DLC Offer
1053
+ * @param _dlcOffer Dlc Offer Message
1054
+ * @param fixedInputs Optional inputs to use for Funding Inputs
1055
+ * @returns {Promise<AcceptDlcOfferResponse}
1056
+ */ async acceptDlcOffer(_dlcOffer, fixedInputs) {
1057
+ const { dlcOffer } = (0, _utils1).checkTypes({
1058
+ _dlcOffer
1059
+ });
963
1060
  dlcOffer.validate();
964
1061
  const acceptCollateralSatoshis = dlcOffer.contractInfo.totalCollateral - dlcOffer.offerCollateralSatoshis;
965
- assert_1.default(acceptCollateralSatoshis ===
966
- dlcOffer.contractInfo.totalCollateral -
967
- dlcOffer.offerCollateralSatoshis, 'acceptCollaterialSatoshis should equal totalCollateral - offerCollateralSatoshis');
968
- const { fundingPubKey, payoutSPK, payoutSerialId, fundingInputs: _fundingInputs, changeSPK, changeSerialId, } = await this.Initialize(acceptCollateralSatoshis, dlcOffer.feeRatePerVb, fixedInputs);
969
- assert_1.default(Buffer.compare(dlcOffer.fundingPubKey, fundingPubKey) !== 0, 'DlcOffer and DlcAccept FundingPubKey cannot be the same');
970
- _fundingInputs.forEach((input) => assert_1.default(input.type === messaging_1.MessageType.FundingInputV0, 'FundingInput must be V0'));
971
- const fundingInputs = _fundingInputs.map((input) => input);
972
- const dlcAccept = new messaging_1.DlcAcceptV0();
973
- dlcAccept.tempContractId = crypto_1.sha256(dlcOffer.serialize());
1062
+ (0, _assert).default(acceptCollateralSatoshis === dlcOffer.contractInfo.totalCollateral - dlcOffer.offerCollateralSatoshis, 'acceptCollaterialSatoshis should equal totalCollateral - offerCollateralSatoshis');
1063
+ const { fundingPubKey , payoutSPK , payoutSerialId , fundingInputs: _fundingInputs , changeSPK , changeSerialId , } = await this.Initialize(acceptCollateralSatoshis, dlcOffer.feeRatePerVb, fixedInputs);
1064
+ (0, _assert).default(Buffer.compare(dlcOffer.fundingPubKey, fundingPubKey) !== 0, 'DlcOffer and DlcAccept FundingPubKey cannot be the same');
1065
+ _fundingInputs.forEach((input)=>(0, _assert).default(input.type === _messaging.MessageType.FundingInputV0, 'FundingInput must be V0')
1066
+ );
1067
+ const fundingInputs = _fundingInputs.map((input)=>input
1068
+ );
1069
+ const dlcAccept = new _messaging.DlcAcceptV0();
1070
+ dlcAccept.tempContractId = (0, _crypto).sha256(dlcOffer.serialize());
974
1071
  dlcAccept.acceptCollateralSatoshis = acceptCollateralSatoshis;
975
1072
  dlcAccept.fundingPubKey = fundingPubKey;
976
1073
  dlcAccept.payoutSPK = payoutSPK;
@@ -978,81 +1075,85 @@ Payout Group not found');
978
1075
  dlcAccept.fundingInputs = fundingInputs;
979
1076
  dlcAccept.changeSPK = changeSPK;
980
1077
  dlcAccept.changeSerialId = dlcAccept.changeSerialId = changeSerialId;
981
- assert_1.default(dlcAccept.changeSerialId !== dlcOffer.fundOutputSerialId, 'changeSerialId cannot equal the fundOutputSerialId');
982
- assert_1.default(dlcOffer.payoutSerialId !== dlcAccept.payoutSerialId, 'offer.payoutSerialId cannot equal accept.payoutSerialId');
983
- assert_1.default((() => {
1078
+ (0, _assert).default(dlcAccept.changeSerialId !== dlcOffer.fundOutputSerialId, 'changeSerialId cannot equal the fundOutputSerialId');
1079
+ (0, _assert).default(dlcOffer.payoutSerialId !== dlcAccept.payoutSerialId, 'offer.payoutSerialId cannot equal accept.payoutSerialId');
1080
+ (0, _assert).default((()=>{
984
1081
  const ids = [
985
1082
  dlcOffer.changeSerialId,
986
1083
  dlcAccept.changeSerialId,
987
- dlcOffer.fundOutputSerialId,
1084
+ dlcOffer.fundOutputSerialId,
988
1085
  ];
989
1086
  return new Set(ids).size === ids.length;
990
1087
  })(), 'offer.changeSerialID, accept.changeSerialId and fundOutputSerialId must be unique');
991
1088
  dlcAccept.validate();
992
- assert_1.default((() => {
993
- const finalizer = new core_1.DualFundingTxFinalizer(dlcOffer.fundingInputs, dlcOffer.payoutSPK, dlcOffer.changeSPK, dlcAccept.fundingInputs, dlcAccept.payoutSPK, dlcAccept.changeSPK, dlcOffer.feeRatePerVb);
994
- const funding = fundingInputs.reduce((total, input) => {
1089
+ (0, _assert).default((()=>{
1090
+ const finalizer = new _core.DualFundingTxFinalizer(dlcOffer.fundingInputs, dlcOffer.payoutSPK, dlcOffer.changeSPK, dlcAccept.fundingInputs, dlcAccept.payoutSPK, dlcAccept.changeSPK, dlcOffer.feeRatePerVb);
1091
+ const funding = fundingInputs.reduce((total, input)=>{
995
1092
  return total + input.prevTx.outputs[input.prevTxVout].value.sats;
996
1093
  }, BigInt(0));
997
1094
  return funding >= acceptCollateralSatoshis + finalizer.acceptFees;
998
1095
  })(), 'fundingInputs for dlcAccept must be greater than acceptCollateralSatoshis plus acceptFees');
999
- const { dlcTransactions, messagesList } = await this.createDlcTxs(dlcOffer, dlcAccept);
1000
- const { cetSignatures, refundSignature, } = await this.CreateCetAdaptorAndRefundSigs(dlcOffer, dlcAccept, dlcTransactions, messagesList, false);
1001
- assert_1.default(dlcTransactions.type === messaging_1.MessageType.DlcTransactionsV0, 'DlcTransactions must be V0');
1096
+ const { dlcTransactions , messagesList } = await this.createDlcTxs(dlcOffer, dlcAccept);
1097
+ const { cetSignatures , refundSignature , } = await this.CreateCetAdaptorAndRefundSigs(dlcOffer, dlcAccept, dlcTransactions, messagesList, false);
1098
+ (0, _assert).default(dlcTransactions.type === _messaging.MessageType.DlcTransactionsV0, 'DlcTransactions must be V0');
1002
1099
  const _dlcTransactions = dlcTransactions;
1003
- const contractId = crypto_1.xor(_dlcTransactions.fundTx.txId.serialize(), dlcAccept.tempContractId);
1100
+ const contractId = (0, _crypto).xor(_dlcTransactions.fundTx.txId.serialize(), dlcAccept.tempContractId);
1004
1101
  _dlcTransactions.contractId = contractId;
1005
1102
  dlcAccept.cetSignatures = cetSignatures;
1006
1103
  dlcAccept.refundSignature = refundSignature;
1007
- dlcAccept.negotiationFields = new messaging_1.NegotiationFieldsV0();
1008
- return { dlcAccept, dlcTransactions: _dlcTransactions };
1104
+ dlcAccept.negotiationFields = new _messaging.NegotiationFieldsV0();
1105
+ return {
1106
+ dlcAccept,
1107
+ dlcTransactions: _dlcTransactions
1108
+ };
1009
1109
  }
1010
1110
  /**
1011
- * Sign Dlc Accept Message
1012
- * @param _dlcOffer Dlc Offer Message
1013
- * @param _dlcAccept Dlc Accept Message
1014
- * @returns {Promise<SignDlcAcceptResponse}
1015
- */
1016
- async signDlcAccept(_dlcOffer, _dlcAccept) {
1017
- const { dlcOffer, dlcAccept } = Utils_1.checkTypes({
1111
+ * Sign Dlc Accept Message
1112
+ * @param _dlcOffer Dlc Offer Message
1113
+ * @param _dlcAccept Dlc Accept Message
1114
+ * @returns {Promise<SignDlcAcceptResponse}
1115
+ */ async signDlcAccept(_dlcOffer, _dlcAccept) {
1116
+ const { dlcOffer , dlcAccept } = (0, _utils1).checkTypes({
1018
1117
  _dlcOffer,
1019
- _dlcAccept,
1118
+ _dlcAccept
1020
1119
  });
1021
1120
  dlcOffer.validate();
1022
1121
  dlcAccept.validate();
1023
- assert_1.default(Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) !== 0, 'DlcOffer and DlcAccept FundingPubKey cannot be the same');
1024
- const dlcSign = new messaging_1.DlcSignV0();
1025
- const { dlcTransactions, messagesList } = await this.createDlcTxs(dlcOffer, dlcAccept);
1122
+ (0, _assert).default(Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) !== 0, 'DlcOffer and DlcAccept FundingPubKey cannot be the same');
1123
+ const dlcSign = new _messaging.DlcSignV0();
1124
+ const { dlcTransactions , messagesList } = await this.createDlcTxs(dlcOffer, dlcAccept);
1026
1125
  await this.VerifyCetAdaptorAndRefundSigs(dlcOffer, dlcAccept, dlcSign, dlcTransactions, messagesList, true);
1027
- const { cetSignatures, refundSignature, } = await this.CreateCetAdaptorAndRefundSigs(dlcOffer, dlcAccept, dlcTransactions, messagesList, true);
1126
+ const { cetSignatures , refundSignature , } = await this.CreateCetAdaptorAndRefundSigs(dlcOffer, dlcAccept, dlcTransactions, messagesList, true);
1028
1127
  const fundingSignatures = await this.CreateFundingSigs(dlcOffer, dlcAccept, dlcTransactions, true);
1029
1128
  const dlcTxs = dlcTransactions;
1030
- const contractId = crypto_1.xor(dlcTxs.fundTx.txId.serialize(), dlcAccept.tempContractId);
1031
- assert_1.default(Buffer.compare(contractId, crypto_1.xor(dlcTxs.fundTx.txId.serialize(), dlcAccept.tempContractId)) === 0, 'contractId must be the xor of funding txid, fundingOutputIndex and the tempContractId');
1129
+ const contractId = (0, _crypto).xor(dlcTxs.fundTx.txId.serialize(), dlcAccept.tempContractId);
1130
+ (0, _assert).default(Buffer.compare(contractId, (0, _crypto).xor(dlcTxs.fundTx.txId.serialize(), dlcAccept.tempContractId)) === 0, 'contractId must be the xor of funding txid, fundingOutputIndex and the tempContractId');
1032
1131
  dlcTxs.contractId = contractId;
1033
1132
  dlcSign.contractId = contractId;
1034
1133
  dlcSign.cetSignatures = cetSignatures;
1035
1134
  dlcSign.refundSignature = refundSignature;
1036
1135
  dlcSign.fundingSignatures = fundingSignatures;
1037
- return { dlcSign, dlcTransactions: dlcTxs };
1136
+ return {
1137
+ dlcSign,
1138
+ dlcTransactions: dlcTxs
1139
+ };
1038
1140
  }
1039
1141
  /**
1040
- * Finalize Dlc Sign
1041
- * @param _dlcOffer Dlc Offer Message
1042
- * @param _dlcAccept Dlc Accept Message
1043
- * @param _dlcSign Dlc Sign Message
1044
- * @param _dlcTxs Dlc Transactions Message
1045
- * @returns {Promise<Tx>}
1046
- */
1047
- async finalizeDlcSign(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs) {
1048
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
1142
+ * Finalize Dlc Sign
1143
+ * @param _dlcOffer Dlc Offer Message
1144
+ * @param _dlcAccept Dlc Accept Message
1145
+ * @param _dlcSign Dlc Sign Message
1146
+ * @param _dlcTxs Dlc Transactions Message
1147
+ * @returns {Promise<Tx>}
1148
+ */ async finalizeDlcSign(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs) {
1149
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
1049
1150
  _dlcOffer,
1050
1151
  _dlcAccept,
1051
1152
  _dlcSign,
1052
- _dlcTxs,
1153
+ _dlcTxs
1053
1154
  });
1054
1155
  const payoutResponses = this.GetPayouts(dlcOffer);
1055
- const { messagesList } = this.FlattenPayouts(payoutResponses);
1156
+ const { messagesList } = this.FlattenPayouts(payoutResponses);
1056
1157
  await this.VerifyCetAdaptorAndRefundSigs(dlcOffer, dlcAccept, dlcSign, dlcTxs, messagesList, false);
1057
1158
  await this.VerifyFundingSigs(dlcOffer, dlcAccept, dlcSign, dlcTxs, false);
1058
1159
  const fundingSignatures = await this.CreateFundingSigs(dlcOffer, dlcAccept, dlcTxs, false);
@@ -1060,99 +1161,97 @@ Payout Group not found');
1060
1161
  return fundTx;
1061
1162
  }
1062
1163
  /**
1063
- * Execute DLC
1064
- * @param _dlcOffer Dlc Offer Message
1065
- * @param _dlcAccept Dlc Accept Message
1066
- * @param _dlcSign Dlc Sign Message
1067
- * @param _dlcTxs Dlc Transactions Message
1068
- * @param oracleAttestation Oracle Attestations TLV (V0)
1069
- * @param isOfferer Whether party is Dlc Offerer
1070
- * @returns {Promise<Tx>}
1071
- */
1072
- async execute(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs, oracleAttestation, isOfferer) {
1073
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
1164
+ * Execute DLC
1165
+ * @param _dlcOffer Dlc Offer Message
1166
+ * @param _dlcAccept Dlc Accept Message
1167
+ * @param _dlcSign Dlc Sign Message
1168
+ * @param _dlcTxs Dlc Transactions Message
1169
+ * @param oracleAttestation Oracle Attestations TLV (V0)
1170
+ * @param isOfferer Whether party is Dlc Offerer
1171
+ * @returns {Promise<Tx>}
1172
+ */ async execute(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs, oracleAttestation, isOfferer) {
1173
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
1074
1174
  _dlcOffer,
1075
1175
  _dlcAccept,
1076
1176
  _dlcSign,
1077
- _dlcTxs,
1177
+ _dlcTxs
1078
1178
  });
1079
- if (isOfferer === undefined)
1080
- isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1179
+ if (isOfferer === undefined) isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1081
1180
  this.ValidateEvent(dlcOffer, oracleAttestation);
1082
1181
  return this.FindAndSignCet(dlcOffer, dlcAccept, dlcSign, dlcTxs, oracleAttestation, isOfferer);
1083
1182
  }
1084
1183
  /**
1085
- * Refund DLC
1086
- * @param _dlcOffer Dlc Offer Message
1087
- * @param _dlcAccept Dlc Accept Message
1088
- * @param _dlcSign Dlc Sign Message
1089
- * @param _dlcTxs Dlc Transactions message
1090
- * @returns {Promise<Tx>}
1091
- */
1092
- async refund(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs) {
1093
- const { dlcOffer, dlcAccept, dlcSign, dlcTxs } = Utils_1.checkTypes({
1184
+ * Refund DLC
1185
+ * @param _dlcOffer Dlc Offer Message
1186
+ * @param _dlcAccept Dlc Accept Message
1187
+ * @param _dlcSign Dlc Sign Message
1188
+ * @param _dlcTxs Dlc Transactions message
1189
+ * @returns {Promise<Tx>}
1190
+ */ async refund(_dlcOffer, _dlcAccept, _dlcSign, _dlcTxs) {
1191
+ const { dlcOffer , dlcAccept , dlcSign , dlcTxs } = (0, _utils1).checkTypes({
1094
1192
  _dlcOffer,
1095
1193
  _dlcAccept,
1096
1194
  _dlcSign,
1097
- _dlcTxs,
1195
+ _dlcTxs
1098
1196
  });
1099
- const signatures = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1
1100
- ? [
1101
- dlcSign.refundSignature.toString('hex'),
1102
- dlcAccept.refundSignature.toString('hex'),
1103
- ]
1104
- : [
1105
- dlcAccept.refundSignature.toString('hex'),
1106
- dlcSign.refundSignature.toString('hex'),
1107
- ];
1197
+ const signatures = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1 ? [
1198
+ dlcSign.refundSignature.toString('hex'),
1199
+ dlcAccept.refundSignature.toString('hex'),
1200
+ ] : [
1201
+ dlcAccept.refundSignature.toString('hex'),
1202
+ dlcSign.refundSignature.toString('hex'),
1203
+ ];
1108
1204
  const addSigsToRefundTxRequest = {
1109
1205
  refundTxHex: dlcTxs.refundTx.serialize().toString('hex'),
1110
1206
  signatures,
1111
1207
  fundTxId: dlcTxs.fundTx.txId.toString(),
1112
1208
  fundVout: dlcTxs.fundTxVout,
1113
1209
  localFundPubkey: dlcOffer.fundingPubKey.toString('hex'),
1114
- remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex'),
1210
+ remoteFundPubkey: dlcAccept.fundingPubKey.toString('hex')
1115
1211
  };
1116
1212
  const refundHex = (await this.AddSignaturesToRefundTx(addSigsToRefundTxRequest)).hex;
1117
- return bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(refundHex));
1213
+ return _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(refundHex));
1118
1214
  }
1119
1215
  /**
1120
- * Goal of createDlcClose is for alice (the initiator) to
1121
- * 1. take dlcoffer, accept, and sign messages. Create a dlcClose message.
1122
- * 2. Build a close tx, sign.
1123
- * 3. return dlcClose message (no psbt)
1124
- */
1125
- /**
1126
- * Generate DlcClose messagetype for closing DLC with Mutual Consent
1127
- * @param _dlcOffer DlcOffer TLV (V0)
1128
- * @param _dlcAccept DlcAccept TLV (V0)
1129
- * @param _dlcTxs DlcTransactions TLV (V0)
1130
- * @param initiatorPayoutSatoshis Amount initiator expects as a payout
1131
- * @param isOfferer Whether offerer or not
1132
- * @param _inputs Optionally specified closing inputs
1133
- * @returns {Promise<DlcClose>}
1134
- */
1135
- async createDlcClose(_dlcOffer, _dlcAccept, _dlcTxs, initiatorPayoutSatoshis, isOfferer, _inputs) {
1136
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
1216
+ * Goal of createDlcClose is for alice (the initiator) to
1217
+ * 1. take dlcoffer, accept, and sign messages. Create a dlcClose message.
1218
+ * 2. Build a close tx, sign.
1219
+ * 3. return dlcClose message (no psbt)
1220
+ */ /**
1221
+ * Generate DlcClose messagetype for closing DLC with Mutual Consent
1222
+ * @param _dlcOffer DlcOffer TLV (V0)
1223
+ * @param _dlcAccept DlcAccept TLV (V0)
1224
+ * @param _dlcTxs DlcTransactions TLV (V0)
1225
+ * @param initiatorPayoutSatoshis Amount initiator expects as a payout
1226
+ * @param isOfferer Whether offerer or not
1227
+ * @param _inputs Optionally specified closing inputs
1228
+ * @returns {Promise<DlcClose>}
1229
+ */ async createDlcClose(_dlcOffer, _dlcAccept, _dlcTxs, initiatorPayoutSatoshis, isOfferer, _inputs) {
1230
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
1137
1231
  _dlcOffer,
1138
1232
  _dlcAccept,
1139
- _dlcTxs,
1233
+ _dlcTxs
1140
1234
  });
1141
- if (isOfferer === undefined)
1142
- isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1235
+ if (isOfferer === undefined) isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1143
1236
  const network = await this.getConnectedNetwork();
1144
- const psbt = new bitcoinjs_lib_1.Psbt({ network });
1145
- const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1
1146
- ? [dlcOffer.fundingPubKey, dlcAccept.fundingPubKey]
1147
- : [dlcAccept.fundingPubKey, dlcOffer.fundingPubKey];
1148
- const p2ms = bitcoinjs_lib_1.payments.p2ms({
1237
+ const psbt = new _bitcoinjsLib.Psbt({
1238
+ network
1239
+ });
1240
+ const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1 ? [
1241
+ dlcOffer.fundingPubKey,
1242
+ dlcAccept.fundingPubKey
1243
+ ] : [
1244
+ dlcAccept.fundingPubKey,
1245
+ dlcOffer.fundingPubKey
1246
+ ];
1247
+ const p2ms = _bitcoinjsLib.payments.p2ms({
1149
1248
  m: 2,
1150
1249
  pubkeys: fundingPubKeys,
1151
- network,
1250
+ network
1152
1251
  });
1153
- const paymentVariant = bitcoinjs_lib_1.payments.p2wsh({
1252
+ const paymentVariant1 = _bitcoinjsLib.payments.p2wsh({
1154
1253
  redeem: p2ms,
1155
- network,
1254
+ network
1156
1255
  });
1157
1256
  // Initiate and build PSBT
1158
1257
  let inputs = _inputs;
@@ -1160,18 +1259,18 @@ Payout Group not found');
1160
1259
  const tempInputs = await this.GetInputsForAmount(BigInt(20000), dlcOffer.feeRatePerVb, _inputs);
1161
1260
  _inputs = tempInputs;
1162
1261
  }
1163
- inputs = _inputs.map((input) => {
1262
+ inputs = _inputs.map((input)=>{
1164
1263
  return {
1165
1264
  ...input,
1166
- inputSerialId: input.inputSerialId || Utils_1.generateSerialId(),
1167
- toUtxo: input.toUtxo,
1265
+ inputSerialId: input.inputSerialId || (0, _utils1).generateSerialId(),
1266
+ toUtxo: input.toUtxo
1168
1267
  };
1169
1268
  });
1170
- const pubkeys = await Promise.all(inputs.map(async (input) => {
1269
+ const pubkeys = await Promise.all(inputs.map(async (input)=>{
1171
1270
  const address = await this.getMethod('getWalletAddress')(input.address);
1172
1271
  return Buffer.from(address.publicKey, 'hex');
1173
1272
  }));
1174
- const fundingInputSerialId = Utils_1.generateSerialId();
1273
+ const fundingInputSerialId = (0, _utils1).generateSerialId();
1175
1274
  // Make temporary array to hold all inputs and then sort them
1176
1275
  // this method can be improved later
1177
1276
  const psbtInputs = [];
@@ -1180,69 +1279,67 @@ Payout Group not found');
1180
1279
  index: dlcTxs.fundTxVout,
1181
1280
  sequence: 0,
1182
1281
  witnessUtxo: {
1183
- script: paymentVariant.output,
1184
- value: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats),
1282
+ script: paymentVariant1.output,
1283
+ value: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats)
1185
1284
  },
1186
- witnessScript: paymentVariant.redeem.output,
1285
+ witnessScript: paymentVariant1.redeem.output,
1187
1286
  inputSerialId: fundingInputSerialId,
1188
- derivationPath: null,
1287
+ derivationPath: null
1189
1288
  });
1190
1289
  // add all dlc close inputs
1191
- inputs.forEach((input, i) => {
1192
- const paymentVariant = bitcoinjs_lib_1.payments.p2wpkh({ pubkey: pubkeys[i], network });
1290
+ inputs.forEach((input, i)=>{
1291
+ const paymentVariant = _bitcoinjsLib.payments.p2wpkh({
1292
+ pubkey: pubkeys[i],
1293
+ network
1294
+ });
1193
1295
  psbtInputs.push({
1194
1296
  hash: input.txid,
1195
1297
  index: input.vout,
1196
1298
  sequence: 0,
1197
1299
  witnessUtxo: {
1198
1300
  script: paymentVariant.output,
1199
- value: input.value,
1301
+ value: input.value
1200
1302
  },
1201
1303
  inputSerialId: input.inputSerialId,
1202
- derivationPath: input.derivationPath,
1304
+ derivationPath: input.derivationPath
1203
1305
  });
1204
1306
  });
1205
1307
  // sort all inputs in ascending order by serial ID
1206
1308
  // The only reason we are doing this is for privacy. If the fundingInput is
1207
1309
  // always first, it is very obvious. Hence, a serialId is randomly generated
1208
1310
  // and the inputs are sorted by that instead.
1209
- const sortedPsbtInputs = psbtInputs.sort((a, b) => Number(a.inputSerialId - b.inputSerialId));
1311
+ const sortedPsbtInputs = psbtInputs.sort((a, b)=>Number(a.inputSerialId - b.inputSerialId)
1312
+ );
1210
1313
  // Get index of fundingInput
1211
- const fundingInputIndex = sortedPsbtInputs.findIndex((input) => input.inputSerialId === fundingInputSerialId);
1314
+ const fundingInputIndex = sortedPsbtInputs.findIndex((input)=>input.inputSerialId === fundingInputSerialId
1315
+ );
1212
1316
  // add to psbt
1213
- sortedPsbtInputs.forEach((input, i) => psbt.addInput(input));
1214
- const fundingInputs = await Promise.all(inputs.map(async (input) => {
1317
+ sortedPsbtInputs.forEach((input, i)=>psbt.addInput(input)
1318
+ );
1319
+ const fundingInputs = await Promise.all(inputs.map(async (input)=>{
1215
1320
  return this.inputToFundingInput(input);
1216
1321
  }));
1217
- const finalizer = new core_1.DualClosingTxFinalizer(fundingInputs, dlcOffer.payoutSPK, dlcAccept.payoutSPK, dlcOffer.feeRatePerVb);
1218
- const closeInputAmount = BigInt(inputs.reduce((acc, val) => acc + val.value, 0));
1219
- const offerPayoutValue = isOfferer
1220
- ? closeInputAmount +
1221
- initiatorPayoutSatoshis -
1222
- finalizer.offerInitiatorFees
1223
- : dlcOffer.contractInfo.totalCollateral - initiatorPayoutSatoshis;
1224
- const acceptPayoutValue = isOfferer
1225
- ? dlcOffer.contractInfo.totalCollateral - initiatorPayoutSatoshis
1226
- : closeInputAmount +
1227
- initiatorPayoutSatoshis -
1228
- finalizer.offerInitiatorFees;
1322
+ const finalizer = new _core.DualClosingTxFinalizer(fundingInputs, dlcOffer.payoutSPK, dlcAccept.payoutSPK, dlcOffer.feeRatePerVb);
1323
+ const closeInputAmount = BigInt(inputs.reduce((acc, val)=>acc + val.value
1324
+ , 0));
1325
+ const offerPayoutValue = isOfferer ? closeInputAmount + initiatorPayoutSatoshis - finalizer.offerInitiatorFees : dlcOffer.contractInfo.totalCollateral - initiatorPayoutSatoshis;
1326
+ const acceptPayoutValue = isOfferer ? dlcOffer.contractInfo.totalCollateral - initiatorPayoutSatoshis : closeInputAmount + initiatorPayoutSatoshis - finalizer.offerInitiatorFees;
1229
1327
  const offerFirst = dlcOffer.payoutSerialId < dlcAccept.payoutSerialId;
1230
1328
  psbt.addOutput({
1231
1329
  value: Number(offerFirst ? offerPayoutValue : acceptPayoutValue),
1232
- address: bitcoinjs_lib_1.address.fromOutputScript(offerFirst ? dlcOffer.payoutSPK : dlcAccept.payoutSPK, network),
1330
+ address: _bitcoinjsLib.address.fromOutputScript(offerFirst ? dlcOffer.payoutSPK : dlcAccept.payoutSPK, network)
1233
1331
  });
1234
1332
  psbt.addOutput({
1235
1333
  value: Number(offerFirst ? acceptPayoutValue : offerPayoutValue),
1236
- address: bitcoinjs_lib_1.address.fromOutputScript(offerFirst ? dlcAccept.payoutSPK : dlcOffer.payoutSPK, network),
1334
+ address: _bitcoinjsLib.address.fromOutputScript(offerFirst ? dlcAccept.payoutSPK : dlcOffer.payoutSPK, network)
1237
1335
  });
1238
1336
  // Generate keypair to sign inputs
1239
1337
  const fundPrivateKeyPair = await this.GetFundKeyPair(dlcOffer, dlcAccept, isOfferer);
1240
1338
  // Sign dlc fundinginput
1241
1339
  psbt.signInput(fundingInputIndex, fundPrivateKeyPair);
1242
1340
  // Sign dlcclose inputs
1243
- await Promise.all(sortedPsbtInputs.map(async (input, i) => {
1244
- if (i === fundingInputIndex)
1245
- return;
1341
+ await Promise.all(sortedPsbtInputs.map(async (input, i)=>{
1342
+ if (i === fundingInputIndex) return;
1246
1343
  // derive keypair
1247
1344
  const keyPair = await this.getMethod('keyPair')(input.derivationPath);
1248
1345
  psbt.signInput(i, keyPair);
@@ -1250,24 +1347,27 @@ Payout Group not found');
1250
1347
  // Validate signatures
1251
1348
  psbt.validateSignaturesOfAllInputs();
1252
1349
  // Extract close signature from psbt and decode it to only extract r and s values
1253
- const closeSignature = await bitcoinjs_lib_1.script.signature.decode(psbt.data.inputs[fundingInputIndex].partialSig[0].signature).signature;
1350
+ const closeSignature = await _bitcoinjsLib.script.signature.decode(psbt.data.inputs[fundingInputIndex].partialSig[0].signature).signature;
1254
1351
  // Extract funding signatures from psbt
1255
- const inputSigs = psbt.data.inputs
1256
- .filter((input) => input !== fundingInputIndex)
1257
- .map((input) => input.partialSig[0]);
1352
+ const inputSigs = psbt.data.inputs.filter((input)=>input !== fundingInputIndex
1353
+ ).map((input)=>input.partialSig[0]
1354
+ );
1258
1355
  // create fundingSignatures
1259
1356
  const witnessElements = [];
1260
- for (let i = 0; i < inputSigs.length; i++) {
1261
- const sigWitness = new messaging_1.ScriptWitnessV0();
1262
- sigWitness.witness = inputSigs[i].signature;
1263
- const pubKeyWitness = new messaging_1.ScriptWitnessV0();
1264
- pubKeyWitness.witness = inputSigs[i].pubkey;
1265
- witnessElements.push([sigWitness, pubKeyWitness]);
1357
+ for(let i1 = 0; i1 < inputSigs.length; i1++){
1358
+ const sigWitness = new _messaging.ScriptWitnessV0();
1359
+ sigWitness.witness = inputSigs[i1].signature;
1360
+ const pubKeyWitness = new _messaging.ScriptWitnessV0();
1361
+ pubKeyWitness.witness = inputSigs[i1].pubkey;
1362
+ witnessElements.push([
1363
+ sigWitness,
1364
+ pubKeyWitness
1365
+ ]);
1266
1366
  }
1267
- const fundingSignatures = new messaging_1.FundingSignaturesV0();
1367
+ const fundingSignatures = new _messaging.FundingSignaturesV0();
1268
1368
  fundingSignatures.witnessElements = witnessElements;
1269
1369
  // Create DlcClose
1270
- const dlcClose = new messaging_1.DlcCloseV0();
1370
+ const dlcClose = new _messaging.DlcCloseV0();
1271
1371
  dlcClose.contractId = dlcTxs.contractId;
1272
1372
  dlcClose.offerPayoutSatoshis = BigInt(psbt.txOutputs[offerFirst ? 0 : 1].value); // You give collateral back to users
1273
1373
  dlcClose.acceptPayoutSatoshis = BigInt(psbt.txOutputs[offerFirst ? 1 : 0].value); // give collateral back to users
@@ -1279,28 +1379,25 @@ Payout Group not found');
1279
1379
  return dlcClose;
1280
1380
  }
1281
1381
  /**
1282
- * Generate multiple DlcClose messagetypes for closing DLC with Mutual Consent
1283
- * @param _dlcOffer DlcOffer TLV (V0)
1284
- * @param _dlcAccept DlcAccept TLV (V0)
1285
- * @param _dlcTxs DlcTransactions TLV (V0)
1286
- * @param initiatorPayouts Array of amounts initiator expects as payouts
1287
- * @param isOfferer Whether offerer or not
1288
- * @param _inputs Optionally specified closing inputs
1289
- * @returns {Promise<DlcClose[]>}
1290
- */
1291
- async createBatchDlcClose(_dlcOffer, _dlcAccept, _dlcTxs, initiatorPayouts, isOfferer, _inputs) {
1292
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
1382
+ * Generate multiple DlcClose messagetypes for closing DLC with Mutual Consent
1383
+ * @param _dlcOffer DlcOffer TLV (V0)
1384
+ * @param _dlcAccept DlcAccept TLV (V0)
1385
+ * @param _dlcTxs DlcTransactions TLV (V0)
1386
+ * @param initiatorPayouts Array of amounts initiator expects as payouts
1387
+ * @param isOfferer Whether offerer or not
1388
+ * @param _inputs Optionally specified closing inputs
1389
+ * @returns {Promise<DlcClose[]>}
1390
+ */ async createBatchDlcClose(_dlcOffer, _dlcAccept, _dlcTxs, initiatorPayouts, isOfferer, _inputs) {
1391
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
1293
1392
  _dlcOffer,
1294
1393
  _dlcAccept,
1295
- _dlcTxs,
1394
+ _dlcTxs
1296
1395
  });
1297
- if (isOfferer === undefined)
1298
- isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1299
- if (_inputs && _inputs.length > 0)
1300
- throw Error('funding inputs not supported on BatchDlcClose'); // TODO support multiple funding inputs
1301
- const fundingInputSerialId = Utils_1.generateSerialId();
1396
+ if (isOfferer === undefined) isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1397
+ if (_inputs && _inputs.length > 0) throw Error('funding inputs not supported on BatchDlcClose'); // TODO support multiple funding inputs
1398
+ const fundingInputSerialId = (0, _utils1).generateSerialId();
1302
1399
  const fundingInputs = []; // TODO: support multiple funding inputs
1303
- const finalizer = new core_1.DualClosingTxFinalizer(fundingInputs, dlcOffer.payoutSPK, dlcAccept.payoutSPK, dlcOffer.feeRatePerVb);
1400
+ const finalizer = new _core.DualClosingTxFinalizer(fundingInputs, dlcOffer.payoutSPK, dlcAccept.payoutSPK, dlcOffer.feeRatePerVb);
1304
1401
  // Generate keypair to sign inputs
1305
1402
  const fundPrivateKeyPair = await this.GetFundKeyPair(dlcOffer, dlcAccept, isOfferer);
1306
1403
  const closeInputAmount = BigInt(0); // TODO support multiple funding inputs
@@ -1309,22 +1406,14 @@ Payout Group not found');
1309
1406
  const sigHashes = await this.CreateSignatureHashes(dlcOffer, dlcAccept, dlcTxs, rawCloseTxs);
1310
1407
  const signatures = await this.CalculateEcSignatureHashes(sigHashes, privKey);
1311
1408
  const dlcCloses = [];
1312
- signatures.forEach((sig, i) => {
1409
+ signatures.forEach((sig, i)=>{
1313
1410
  const payout = initiatorPayouts[i];
1314
- const payoutMinusOfferFees = finalizer.offerInitiatorFees > payout
1315
- ? BigInt(0)
1316
- : payout - finalizer.offerInitiatorFees;
1317
- const collateralMinusPayout = payout > dlcOffer.contractInfo.totalCollateral
1318
- ? BigInt(0)
1319
- : dlcOffer.contractInfo.totalCollateral - payout;
1320
- const offerPayoutValue = isOfferer
1321
- ? closeInputAmount + payoutMinusOfferFees
1322
- : collateralMinusPayout;
1323
- const acceptPayoutValue = isOfferer
1324
- ? collateralMinusPayout
1325
- : closeInputAmount + payoutMinusOfferFees;
1326
- const fundingSignatures = new messaging_1.FundingSignaturesV0();
1327
- const dlcClose = new messaging_1.DlcCloseV0();
1411
+ const payoutMinusOfferFees = finalizer.offerInitiatorFees > payout ? BigInt(0) : payout - finalizer.offerInitiatorFees;
1412
+ const collateralMinusPayout = payout > dlcOffer.contractInfo.totalCollateral ? BigInt(0) : dlcOffer.contractInfo.totalCollateral - payout;
1413
+ const offerPayoutValue = isOfferer ? closeInputAmount + payoutMinusOfferFees : collateralMinusPayout;
1414
+ const acceptPayoutValue = isOfferer ? collateralMinusPayout : closeInputAmount + payoutMinusOfferFees;
1415
+ const fundingSignatures = new _messaging.FundingSignaturesV0();
1416
+ const dlcClose = new _messaging.DlcCloseV0();
1328
1417
  dlcClose.contractId = dlcTxs.contractId;
1329
1418
  dlcClose.offerPayoutSatoshis = offerPayoutValue;
1330
1419
  dlcClose.acceptPayoutSatoshis = acceptPayoutValue;
@@ -1337,71 +1426,77 @@ Payout Group not found');
1337
1426
  return dlcCloses;
1338
1427
  }
1339
1428
  async verifyBatchDlcCloseUsingMetadata(dlcCloseMetadata, _dlcCloses, isOfferer) {
1340
- const { dlcOffer, dlcAccept, dlcTxs } = dlcCloseMetadata.toDlcMessages();
1429
+ const { dlcOffer , dlcAccept , dlcTxs } = dlcCloseMetadata.toDlcMessages();
1341
1430
  await this.verifyBatchDlcClose(dlcOffer, dlcAccept, dlcTxs, _dlcCloses, isOfferer);
1342
1431
  }
1343
1432
  /**
1344
- * Verify multiple DlcClose messagetypes for closing DLC with Mutual Consent
1345
- * @param _dlcOffer DlcOffer TLV (V0)
1346
- * @param _dlcAccept DlcAccept TLV (V0)
1347
- * @param _dlcTxs DlcTransactions TLV (V0)
1348
- * @param _dlcCloses DlcClose[] TLV (V0)
1349
- * @param isOfferer Whether offerer or not
1350
- * @returns {Promise<void>}
1351
- */
1352
- async verifyBatchDlcClose(_dlcOffer, _dlcAccept, _dlcTxs, _dlcCloses, isOfferer) {
1353
- const { dlcOffer, dlcAccept, dlcTxs } = Utils_1.checkTypes({
1433
+ * Verify multiple DlcClose messagetypes for closing DLC with Mutual Consent
1434
+ * @param _dlcOffer DlcOffer TLV (V0)
1435
+ * @param _dlcAccept DlcAccept TLV (V0)
1436
+ * @param _dlcTxs DlcTransactions TLV (V0)
1437
+ * @param _dlcCloses DlcClose[] TLV (V0)
1438
+ * @param isOfferer Whether offerer or not
1439
+ * @returns {Promise<void>}
1440
+ */ async verifyBatchDlcClose(_dlcOffer, _dlcAccept, _dlcTxs, _dlcCloses, isOfferer) {
1441
+ const { dlcOffer , dlcAccept , dlcTxs } = (0, _utils1).checkTypes({
1354
1442
  _dlcOffer,
1355
1443
  _dlcAccept,
1356
- _dlcTxs,
1444
+ _dlcTxs
1357
1445
  });
1358
- const dlcCloses = _dlcCloses.map((_dlcClose) => Utils_1.checkTypes({ _dlcClose }).dlcClose);
1359
- if (isOfferer === undefined)
1360
- isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1361
- assert_1.default(dlcCloses.every((dlcClose) => dlcClose.fundingInputs.length === 0), 'funding inputs not supported on verify BatchDlcClose'); // TODO support multiple funding inputs
1446
+ const dlcCloses = _dlcCloses.map((_dlcClose)=>(0, _utils1).checkTypes({
1447
+ _dlcClose
1448
+ }).dlcClose
1449
+ );
1450
+ if (isOfferer === undefined) isOfferer = await this.isOfferer(dlcOffer, dlcAccept);
1451
+ (0, _assert).default(dlcCloses.every((dlcClose)=>dlcClose.fundingInputs.length === 0
1452
+ ), 'funding inputs not supported on verify BatchDlcClose'); // TODO support multiple funding inputs
1362
1453
  const closeInputAmount = BigInt(0); // TODO support multiple funding inputs
1363
1454
  const rawCloseTxs = await this.CreateCloseRawTxs(dlcOffer, dlcAccept, dlcTxs, closeInputAmount, isOfferer, dlcCloses);
1364
1455
  const areSigsValid = await this.VerifySignatures(dlcOffer, dlcAccept, dlcTxs, dlcCloses, rawCloseTxs, isOfferer);
1365
- assert_1.default(areSigsValid, 'Signatures invalid in Verify Batch DlcClose');
1456
+ (0, _assert).default(areSigsValid, 'Signatures invalid in Verify Batch DlcClose');
1366
1457
  }
1367
1458
  /**
1368
- * Goal of finalize Dlc Close is for bob to
1369
- * 1. take the dlcClose created by alice using createDlcClose,
1370
- * 2. Build a psbt using Alice's dlcClose message
1371
- * 3. Sign psbt with bob's privkey
1372
- * 4. return a tx ready to be broadcast
1373
- */
1374
- /**
1375
- * Finalize Dlc Close
1376
- * @param _dlcOffer Dlc Offer Message
1377
- * @param _dlcAccept Dlc Accept Message
1378
- * @param _dlcClose Dlc Close Message
1379
- * @param _dlcTxs Dlc Transactions Message
1380
- * @returns {Promise<Tx>}
1381
- */
1382
- async finalizeDlcClose(_dlcOffer, _dlcAccept, _dlcClose, _dlcTxs) {
1383
- const { dlcOffer, dlcAccept, dlcClose, dlcTxs } = Utils_1.checkTypes({
1459
+ * Goal of finalize Dlc Close is for bob to
1460
+ * 1. take the dlcClose created by alice using createDlcClose,
1461
+ * 2. Build a psbt using Alice's dlcClose message
1462
+ * 3. Sign psbt with bob's privkey
1463
+ * 4. return a tx ready to be broadcast
1464
+ */ /**
1465
+ * Finalize Dlc Close
1466
+ * @param _dlcOffer Dlc Offer Message
1467
+ * @param _dlcAccept Dlc Accept Message
1468
+ * @param _dlcClose Dlc Close Message
1469
+ * @param _dlcTxs Dlc Transactions Message
1470
+ * @returns {Promise<Tx>}
1471
+ */ async finalizeDlcClose(_dlcOffer, _dlcAccept, _dlcClose, _dlcTxs) {
1472
+ const { dlcOffer , dlcAccept , dlcClose , dlcTxs } = (0, _utils1).checkTypes({
1384
1473
  _dlcOffer,
1385
1474
  _dlcAccept,
1386
1475
  _dlcClose,
1387
- _dlcTxs,
1476
+ _dlcTxs
1388
1477
  });
1389
1478
  dlcOffer.validate();
1390
1479
  dlcAccept.validate();
1391
1480
  dlcClose.validate();
1392
1481
  const network = await this.getConnectedNetwork();
1393
- const psbt = new bitcoinjs_lib_1.Psbt({ network });
1394
- const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1
1395
- ? [dlcOffer.fundingPubKey, dlcAccept.fundingPubKey]
1396
- : [dlcAccept.fundingPubKey, dlcOffer.fundingPubKey];
1397
- const p2ms = bitcoinjs_lib_1.payments.p2ms({
1482
+ const psbt = new _bitcoinjsLib.Psbt({
1483
+ network
1484
+ });
1485
+ const fundingPubKeys = Buffer.compare(dlcOffer.fundingPubKey, dlcAccept.fundingPubKey) === -1 ? [
1486
+ dlcOffer.fundingPubKey,
1487
+ dlcAccept.fundingPubKey
1488
+ ] : [
1489
+ dlcAccept.fundingPubKey,
1490
+ dlcOffer.fundingPubKey
1491
+ ];
1492
+ const p2ms = _bitcoinjsLib.payments.p2ms({
1398
1493
  m: 2,
1399
1494
  pubkeys: fundingPubKeys,
1400
- network,
1495
+ network
1401
1496
  });
1402
- const paymentVariant = bitcoinjs_lib_1.payments.p2wsh({
1497
+ const paymentVariant = _bitcoinjsLib.payments.p2wsh({
1403
1498
  redeem: p2ms,
1404
- network,
1499
+ network
1405
1500
  });
1406
1501
  // Make temporary array to hold all inputs and then sort them
1407
1502
  // this method can be improved later
@@ -1412,48 +1507,45 @@ Payout Group not found');
1412
1507
  sequence: 0,
1413
1508
  witnessUtxo: {
1414
1509
  script: paymentVariant.output,
1415
- value: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats),
1510
+ value: Number(dlcTxs.fundTx.outputs[dlcTxs.fundTxVout].value.sats)
1416
1511
  },
1417
1512
  witnessScript: paymentVariant.redeem.output,
1418
- inputSerialId: dlcClose.fundInputSerialId,
1513
+ inputSerialId: dlcClose.fundInputSerialId
1419
1514
  });
1420
1515
  // add all dlc close inputs
1421
- dlcClose.fundingInputs.forEach((input, i) => {
1516
+ dlcClose.fundingInputs.forEach((input, i)=>{
1422
1517
  psbtInputs.push({
1423
1518
  hash: input.prevTx.txId.serialize(),
1424
1519
  index: input.prevTxVout,
1425
1520
  sequence: 0,
1426
1521
  witnessUtxo: {
1427
- script: input.prevTx.outputs[input.prevTxVout].scriptPubKey
1428
- .serialize()
1429
- .slice(1),
1430
- value: Number(input.prevTx.outputs[input.prevTxVout].value.sats),
1522
+ script: input.prevTx.outputs[input.prevTxVout].scriptPubKey.serialize().slice(1),
1523
+ value: Number(input.prevTx.outputs[input.prevTxVout].value.sats)
1431
1524
  },
1432
- inputSerialId: input.inputSerialId,
1525
+ inputSerialId: input.inputSerialId
1433
1526
  });
1434
1527
  });
1435
1528
  // sort all inputs in ascending order by serial ID
1436
1529
  // The only reason we are doing this is for privacy. If the fundingInput is
1437
1530
  // always first, it is very obvious. Hence, a serialId is randomly generated
1438
1531
  // and the inputs are sorted by that instead.
1439
- const sortedPsbtInputs = psbtInputs.sort((a, b) => Number(a.inputSerialId - b.inputSerialId));
1532
+ const sortedPsbtInputs = psbtInputs.sort((a, b)=>Number(a.inputSerialId - b.inputSerialId)
1533
+ );
1440
1534
  // Get index of fundingInput
1441
- const fundingInputIndex = sortedPsbtInputs.findIndex((input) => input.inputSerialId === dlcClose.fundInputSerialId);
1535
+ const fundingInputIndex = sortedPsbtInputs.findIndex((input)=>input.inputSerialId === dlcClose.fundInputSerialId
1536
+ );
1442
1537
  const offerFirst = dlcOffer.payoutSerialId < dlcAccept.payoutSerialId;
1443
1538
  psbt.addOutput({
1444
- value: Number(offerFirst
1445
- ? dlcClose.offerPayoutSatoshis
1446
- : dlcClose.acceptPayoutSatoshis),
1447
- address: bitcoinjs_lib_1.address.fromOutputScript(offerFirst ? dlcOffer.payoutSPK : dlcAccept.payoutSPK, network),
1539
+ value: Number(offerFirst ? dlcClose.offerPayoutSatoshis : dlcClose.acceptPayoutSatoshis),
1540
+ address: _bitcoinjsLib.address.fromOutputScript(offerFirst ? dlcOffer.payoutSPK : dlcAccept.payoutSPK, network)
1448
1541
  });
1449
1542
  psbt.addOutput({
1450
- value: Number(offerFirst
1451
- ? dlcClose.acceptPayoutSatoshis
1452
- : dlcClose.offerPayoutSatoshis),
1453
- address: bitcoinjs_lib_1.address.fromOutputScript(offerFirst ? dlcAccept.payoutSPK : dlcOffer.payoutSPK, network),
1543
+ value: Number(offerFirst ? dlcClose.acceptPayoutSatoshis : dlcClose.offerPayoutSatoshis),
1544
+ address: _bitcoinjsLib.address.fromOutputScript(offerFirst ? dlcAccept.payoutSPK : dlcOffer.payoutSPK, network)
1454
1545
  });
1455
1546
  // add to psbt
1456
- sortedPsbtInputs.forEach((input, i) => psbt.addInput(input));
1547
+ sortedPsbtInputs.forEach((input, i)=>psbt.addInput(input)
1548
+ );
1457
1549
  const offerer = await this.isOfferer(dlcOffer, dlcAccept);
1458
1550
  // Generate keypair to sign inputs
1459
1551
  const fundPrivateKeyPair = await this.GetFundKeyPair(dlcOffer, dlcAccept, offerer);
@@ -1462,23 +1554,26 @@ Payout Group not found');
1462
1554
  const partialSig = [
1463
1555
  {
1464
1556
  pubkey: offerer ? dlcAccept.fundingPubKey : dlcOffer.fundingPubKey,
1465
- signature: await bitcoinjs_lib_1.script.signature.encode(dlcClose.closeSignature, 1),
1466
- },
1557
+ signature: await _bitcoinjsLib.script.signature.encode(dlcClose.closeSignature, 1)
1558
+ },
1467
1559
  ];
1468
- psbt.updateInput(fundingInputIndex, { partialSig });
1469
- for (let i = 0; i < psbt.data.inputs.length; ++i) {
1470
- if (i === fundingInputIndex)
1471
- continue;
1472
- if (!psbt.data.inputs[i].partialSig)
1473
- psbt.data.inputs[i].partialSig = [];
1474
- const witnessI = dlcClose.fundingSignatures.witnessElements.findIndex((el) => Buffer.compare(bitcoin_1.Script.p2wpkhLock(crypto_1.hash160(el[1].witness)).serialize().slice(1), psbt.data.inputs[i].witnessUtxo.script) === 0);
1560
+ psbt.updateInput(fundingInputIndex, {
1561
+ partialSig
1562
+ });
1563
+ for(let i = 0; i < psbt.data.inputs.length; ++i){
1564
+ if (i === fundingInputIndex) continue;
1565
+ if (!psbt.data.inputs[i].partialSig) psbt.data.inputs[i].partialSig = [];
1566
+ const witnessI = dlcClose.fundingSignatures.witnessElements.findIndex((el)=>Buffer.compare(_bitcoin.Script.p2wpkhLock((0, _crypto).hash160(el[1].witness)).serialize().slice(1), psbt.data.inputs[i].witnessUtxo.script) === 0
1567
+ );
1475
1568
  const partialSig = [
1476
1569
  {
1477
1570
  pubkey: dlcClose.fundingSignatures.witnessElements[witnessI][1].witness,
1478
- signature: dlcClose.fundingSignatures.witnessElements[witnessI][0].witness,
1479
- },
1571
+ signature: dlcClose.fundingSignatures.witnessElements[witnessI][0].witness
1572
+ },
1480
1573
  ];
1481
- psbt.updateInput(i, { partialSig });
1574
+ psbt.updateInput(i, {
1575
+ partialSig
1576
+ });
1482
1577
  }
1483
1578
  psbt.validateSignaturesOfAllInputs();
1484
1579
  psbt.finalizeAllInputs();
@@ -1549,16 +1644,18 @@ Payout Group not found');
1549
1644
  return this._cfdDlcJs.VerifyRefundTxSignature(jsonObject);
1550
1645
  }
1551
1646
  async fundingInputToInput(_input, findDerivationPath = true) {
1552
- assert_1.default(_input.type === messaging_1.MessageType.FundingInputV0, 'FundingInput must be V0');
1647
+ (0, _assert).default(_input.type === _messaging.MessageType.FundingInputV0, 'FundingInput must be V0');
1553
1648
  const network = await this.getConnectedNetwork();
1554
1649
  const input = _input;
1555
1650
  const prevTx = input.prevTx;
1556
1651
  const prevTxOut = prevTx.outputs[input.prevTxVout];
1557
1652
  const scriptPubKey = prevTxOut.scriptPubKey.serialize().slice(1);
1558
- const _address = bitcoinjs_lib_1.address.fromOutputScript(scriptPubKey, network);
1653
+ const _address = _bitcoinjsLib.address.fromOutputScript(scriptPubKey, network);
1559
1654
  let derivationPath;
1560
1655
  if (findDerivationPath) {
1561
- const inputAddress = await this.client.financewallet.quickFindAddress([_address]);
1656
+ const inputAddress = await this.client.financewallet.quickFindAddress([
1657
+ _address
1658
+ ]);
1562
1659
  if (inputAddress) {
1563
1660
  derivationPath = inputAddress.derivationPath;
1564
1661
  }
@@ -1571,48 +1668,43 @@ Payout Group not found');
1571
1668
  value: Number(prevTxOut.value.sats),
1572
1669
  derivationPath,
1573
1670
  maxWitnessLength: input.maxWitnessLen,
1574
- redeemScript: input.redeemScript
1575
- ? input.redeemScript.toString('hex')
1576
- : '',
1671
+ redeemScript: input.redeemScript ? input.redeemScript.toString('hex') : '',
1577
1672
  scriptPubKey: scriptPubKey.toString('hex'),
1578
1673
  inputSerialId: input.inputSerialId,
1579
- toUtxo: types_1.Input.prototype.toUtxo,
1674
+ toUtxo: _types.Input.prototype.toUtxo
1580
1675
  };
1581
1676
  }
1582
1677
  async inputToFundingInput(input) {
1583
- const fundingInput = new messaging_1.FundingInputV0();
1678
+ const fundingInput = new _messaging.FundingInputV0();
1584
1679
  fundingInput.prevTxVout = input.vout;
1585
1680
  let txRaw = '';
1586
1681
  try {
1587
1682
  txRaw = await this.getMethod('getRawTransactionByHash')(input.txid);
1588
- }
1589
- catch (e) {
1683
+ } catch (e) {
1590
1684
  try {
1591
- txRaw = (await this.getMethod('jsonrpc')('gettransaction', input.txid))
1592
- .hex;
1593
- }
1594
- catch (e) {
1685
+ txRaw = (await this.getMethod('jsonrpc')('gettransaction', input.txid)).hex;
1686
+ } catch (e) {
1595
1687
  throw Error(`Cannot find tx ${input.txid} in inputToFundingInput using getrawtransactionbyhash or gettransaction`);
1596
1688
  }
1597
1689
  }
1598
- const tx = bitcoin_1.Tx.decode(bufio_1.StreamReader.fromHex(txRaw));
1690
+ const tx = _bitcoin.Tx.decode(_bufio.StreamReader.fromHex(txRaw));
1599
1691
  fundingInput.prevTx = tx;
1600
- fundingInput.sequence = bitcoin_1.Sequence.default();
1601
- fundingInput.maxWitnessLen = input.maxWitnessLength
1602
- ? input.maxWitnessLength
1603
- : 108;
1604
- fundingInput.redeemScript = input.redeemScript
1605
- ? Buffer.from(input.redeemScript, 'hex')
1606
- : Buffer.from('', 'hex');
1607
- fundingInput.inputSerialId = input.inputSerialId
1608
- ? input.inputSerialId
1609
- : Utils_1.generateSerialId();
1692
+ fundingInput.sequence = _bitcoin.Sequence.default();
1693
+ fundingInput.maxWitnessLen = input.maxWitnessLength ? input.maxWitnessLength : 108;
1694
+ fundingInput.redeemScript = input.redeemScript ? Buffer.from(input.redeemScript, 'hex') : Buffer.from('', 'hex');
1695
+ fundingInput.inputSerialId = input.inputSerialId ? input.inputSerialId : (0, _utils1).generateSerialId();
1610
1696
  return fundingInput;
1611
1697
  }
1612
1698
  async getConnectedNetwork() {
1613
1699
  return this._network;
1614
1700
  }
1615
- }
1616
- exports.default = BitcoinDlcProvider;
1701
+ constructor(network, cfdDlcJs){
1702
+ super();
1703
+ this._network = network;
1704
+ this._cfdDlcJs = cfdDlcJs;
1705
+ }
1706
+ };
1617
1707
  const BurnAddress = 'bcrt1qxcjufgh2jarkp2qkx68azh08w9v5gah8u6es8s';
1618
- //# sourceMappingURL=BitcoinDlcProvider.js.map
1708
+ exports.default = BitcoinDlcProvider;
1709
+
1710
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2xpYi9CaXRjb2luRGxjUHJvdmlkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2hhaW5IYXNoRnJvbU5ldHdvcmsgfSBmcm9tICdAYXRvbWljZmluYW5jZS9iaXRjb2luLW5ldHdvcmtzJztcbmltcG9ydCBQcm92aWRlciBmcm9tICdAYXRvbWljZmluYW5jZS9wcm92aWRlcic7XG5pbXBvcnQge1xuICBBZGFwdG9yUGFpcixcbiAgQWRkU2lnbmF0dXJlc1RvUmVmdW5kVHhSZXF1ZXN0LFxuICBBZGRTaWduYXR1cmVzVG9SZWZ1bmRUeFJlc3BvbnNlLFxuICBBZGRTaWduYXR1cmVUb0Z1bmRUcmFuc2FjdGlvblJlcXVlc3QsXG4gIEFkZFNpZ25hdHVyZVRvRnVuZFRyYW5zYWN0aW9uUmVzcG9uc2UsXG4gIENhbGN1bGF0ZUVjU2lnbmF0dXJlUmVxdWVzdCxcbiAgQ3JlYXRlQ2V0QWRhcHRvclNpZ25hdHVyZVJlcXVlc3QsXG4gIENyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmVSZXNwb25zZSxcbiAgQ3JlYXRlQ2V0QWRhcHRvclNpZ25hdHVyZXNSZXF1ZXN0LFxuICBDcmVhdGVDZXRBZGFwdG9yU2lnbmF0dXJlc1Jlc3BvbnNlLFxuICBDcmVhdGVDZXRSZXF1ZXN0LFxuICBDcmVhdGVDZXRSZXNwb25zZSxcbiAgQ3JlYXRlRGxjVHJhbnNhY3Rpb25zUmVxdWVzdCxcbiAgQ3JlYXRlRGxjVHJhbnNhY3Rpb25zUmVzcG9uc2UsXG4gIENyZWF0ZUZ1bmRUcmFuc2FjdGlvblJlcXVlc3QsXG4gIENyZWF0ZUZ1bmRUcmFuc2FjdGlvblJlc3BvbnNlLFxuICBDcmVhdGVSYXdUcmFuc2FjdGlvblJlcXVlc3QsXG4gIENyZWF0ZVJlZnVuZFRyYW5zYWN0aW9uUmVxdWVzdCxcbiAgQ3JlYXRlUmVmdW5kVHJhbnNhY3Rpb25SZXNwb25zZSxcbiAgQ3JlYXRlU2lnbmF0dXJlSGFzaFJlcXVlc3QsXG4gIERsY1Byb3ZpZGVyLFxuICBHZXRSYXdGdW5kVHhTaWduYXR1cmVSZXF1ZXN0LFxuICBHZXRSYXdGdW5kVHhTaWduYXR1cmVSZXNwb25zZSxcbiAgR2V0UmF3UmVmdW5kVHhTaWduYXR1cmVSZXF1ZXN0LFxuICBHZXRSYXdSZWZ1bmRUeFNpZ25hdHVyZVJlc3BvbnNlLFxuICBJbnB1dCxcbiAgTWVzc2FnZXMsXG4gIFBheW91dFJlcXVlc3QsXG4gIFNpZ25DZXRSZXF1ZXN0LFxuICBTaWduQ2V0UmVzcG9uc2UsXG4gIFNpZ25GdW5kVHJhbnNhY3Rpb25SZXF1ZXN0LFxuICBTaWduRnVuZFRyYW5zYWN0aW9uUmVzcG9uc2UsXG4gIFV0eG8sXG4gIFZlcmlmeUNldEFkYXB0b3JTaWduYXR1cmVSZXF1ZXN0LFxuICBWZXJpZnlDZXRBZGFwdG9yU2lnbmF0dXJlUmVzcG9uc2UsXG4gIFZlcmlmeUNldEFkYXB0b3JTaWduYXR1cmVzUmVxdWVzdCxcbiAgVmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZXNSZXNwb25zZSxcbiAgVmVyaWZ5RnVuZFR4U2lnbmF0dXJlUmVxdWVzdCxcbiAgVmVyaWZ5RnVuZFR4U2lnbmF0dXJlUmVzcG9uc2UsXG4gIFZlcmlmeVJlZnVuZFR4U2lnbmF0dXJlUmVxdWVzdCxcbiAgVmVyaWZ5UmVmdW5kVHhTaWduYXR1cmVSZXNwb25zZSxcbiAgVmVyaWZ5U2lnbmF0dXJlUmVxdWVzdCxcbn0gZnJvbSAnQGF0b21pY2ZpbmFuY2UvdHlwZXMnO1xuaW1wb3J0IHsgQml0Y29pbk5ldHdvcmsgfSBmcm9tICdAbGlxdWFsaXR5L2JpdGNvaW4tbmV0d29ya3MnO1xuaW1wb3J0IHsgQWRkcmVzcywgYml0Y29pbiB9IGZyb20gJ0BsaXF1YWxpdHkvdHlwZXMnO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICdAbGlxdWFsaXR5L3V0aWxzJztcbmltcG9ydCB7XG4gIER1YWxDbG9zaW5nVHhGaW5hbGl6ZXIsXG4gIER1YWxGdW5kaW5nVHhGaW5hbGl6ZXIsXG4gIGdyb3VwQnlJZ25vcmluZ0RpZ2l0cyxcbiAgSHlwZXJib2xhUGF5b3V0Q3VydmUsXG4gIFBvbHlub21pYWxQYXlvdXRDdXJ2ZSxcbiAgcm91bmRQYXlvdXQsXG59IGZyb20gJ0Bub2RlLWRsYy9jb3JlJztcbmltcG9ydCB7XG4gIENldEFkYXB0b3JTaWduYXR1cmVzVjAsXG4gIENvbnRyYWN0RGVzY3JpcHRvcixcbiAgQ29udHJhY3REZXNjcmlwdG9yVjEsXG4gIENvbnRyYWN0SW5mbyxcbiAgQ29udHJhY3RJbmZvVjAsXG4gIENvbnRyYWN0SW5mb1YxLFxuICBEaWdpdERlY29tcG9zaXRpb25FdmVudERlc2NyaXB0b3JWMCxcbiAgRGxjQWNjZXB0LFxuICBEbGNBY2NlcHRWMCxcbiAgRGxjQ2xvc2UsXG4gIERsY0Nsb3NlTWV0YWRhdGEsXG4gIERsY0Nsb3NlVjAsXG4gIERsY09mZmVyLFxuICBEbGNPZmZlclYwLFxuICBEbGNTaWduLFxuICBEbGNTaWduVjAsXG4gIERsY1RyYW5zYWN0aW9ucyxcbiAgRGxjVHJhbnNhY3Rpb25zVjAsXG4gIEZ1bmRpbmdJbnB1dCxcbiAgRnVuZGluZ0lucHV0VjAsXG4gIEZ1bmRpbmdTaWduYXR1cmVzVjAsXG4gIEh5cGVyYm9sYVBheW91dEN1cnZlUGllY2UsXG4gIE1lc3NhZ2VUeXBlLFxuICBOZWdvdGlhdGlvbkZpZWxkc1YwLFxuICBPcmFjbGVBdHRlc3RhdGlvblYwLFxuICBPcmFjbGVFdmVudFYwLFxuICBPcmFjbGVJbmZvVjAsXG4gIFBheW91dEZ1bmN0aW9uVjAsXG4gIFBvbHlub21pYWxQYXlvdXRDdXJ2ZVBpZWNlLFxuICBTY3JpcHRXaXRuZXNzVjAsXG59IGZyb20gJ0Bub2RlLWRsYy9tZXNzYWdpbmcnO1xuaW1wb3J0IHsgU2NyaXB0LCBTZXF1ZW5jZSwgVHggfSBmcm9tICdAbm9kZS1saWdodG5pbmcvYml0Y29pbic7XG5pbXBvcnQgeyBTdHJlYW1SZWFkZXIgfSBmcm9tICdAbm9kZS1saWdodG5pbmcvYnVmaW8nO1xuaW1wb3J0IHsgaGFzaDE2MCwgc2hhMjU2LCB4b3IgfSBmcm9tICdAbm9kZS1saWdodG5pbmcvY3J5cHRvJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7XG4gIGFkZHJlc3MsXG4gIEVDUGFpckludGVyZmFjZSxcbiAgcGF5bWVudHMsXG4gIFBzYnQsXG4gIHNjcmlwdCxcbn0gZnJvbSAnYml0Y29pbmpzLWxpYic7XG5cbmltcG9ydCB7XG4gIGFzeW5jRm9yRWFjaCxcbiAgY2hlY2tUeXBlcyxcbiAgZ2VuZXJhdGVTZXJpYWxJZCxcbiAgb3V0cHV0c1RvUGF5b3V0cyxcbn0gZnJvbSAnLi91dGlscy9VdGlscyc7XG5cbmNvbnN0IEVTVElNQVRFRF9TSVpFID0gMzEyO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCaXRjb2luRGxjUHJvdmlkZXJcbiAgZXh0ZW5kcyBQcm92aWRlclxuICBpbXBsZW1lbnRzIFBhcnRpYWw8RGxjUHJvdmlkZXI+IHtcbiAgX25ldHdvcms6IEJpdGNvaW5OZXR3b3JrO1xuICBfY2ZkRGxjSnM6IGFueTtcblxuICBjb25zdHJ1Y3RvcihuZXR3b3JrOiBCaXRjb2luTmV0d29yaywgY2ZkRGxjSnM/OiBhbnkpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5fbmV0d29yayA9IG5ldHdvcms7XG4gICAgdGhpcy5fY2ZkRGxjSnMgPSBjZmREbGNKcztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgQ2ZkTG9hZGVkKCkge1xuICAgIHdoaWxlICghdGhpcy5fY2ZkRGxjSnMpIHtcbiAgICAgIGF3YWl0IHNsZWVwKDEwKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIEdldFByaXZLZXlzRm9ySW5wdXRzKGlucHV0czogSW5wdXRbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCBwcml2S2V5czogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpbnB1dCA9IGlucHV0c1tpXTtcbiAgICAgIGxldCBkZXJpdmF0aW9uUGF0aCA9IGlucHV0LmRlcml2YXRpb25QYXRoO1xuXG4gICAgICBpZiAoIWRlcml2YXRpb25QYXRoKSB7XG4gICAgICAgIGRlcml2YXRpb25QYXRoID0gKFxuICAgICAgICAgIGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdnZXRXYWxsZXRBZGRyZXNzJykoaW5wdXQuYWRkcmVzcylcbiAgICAgICAgKS5kZXJpdmF0aW9uUGF0aDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qga2V5UGFpciA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdrZXlQYWlyJykoZGVyaXZhdGlvblBhdGgpO1xuICAgICAgY29uc3QgcHJpdktleSA9IEJ1ZmZlci5mcm9tKGtleVBhaXIuX19EKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBwcml2S2V5cy5wdXNoKHByaXZLZXkpO1xuICAgIH1cblxuICAgIHJldHVybiBwcml2S2V5cztcbiAgfVxuXG4gIGFzeW5jIEdldENmZE5ldHdvcmsoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWROZXR3b3JrKCk7XG5cbiAgICBzd2l0Y2ggKG5ldHdvcmsubmFtZSkge1xuICAgICAgY2FzZSAnYml0Y29pbl90ZXN0bmV0JzpcbiAgICAgICAgcmV0dXJuICd0ZXN0bmV0JztcbiAgICAgIGNhc2UgJ2JpdGNvaW5fcmVndGVzdCc6XG4gICAgICAgIHJldHVybiAncmVndGVzdCc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gJ2JpdGNvaW4nO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIEdldElucHV0c0ZvckFtb3VudChcbiAgICBhbW91bnQ6IGJpZ2ludCxcbiAgICBmZWVSYXRlUGVyVmI6IGJpZ2ludCxcbiAgICBmaXhlZElucHV0czogSW5wdXRbXSA9IFtdLFxuICApOiBQcm9taXNlPElucHV0W10+IHtcbiAgICBpZiAoYW1vdW50ID09PSBCaWdJbnQoMCkpIHJldHVybiBbXTtcbiAgICBjb25zdCB0YXJnZXRzOiBiaXRjb2luLk91dHB1dFRhcmdldFtdID0gW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOiBCdXJuQWRkcmVzcyxcbiAgICAgICAgdmFsdWU6IE51bWJlcihhbW91bnQpICsgRVNUSU1BVEVEX1NJWkUgKiAoTnVtYmVyKGZlZVJhdGVQZXJWYikgLSAxKSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBsZXQgaW5wdXRzOiBJbnB1dFtdO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpbnB1dHNGb3JBbW91bnQ6IElucHV0c0ZvckFtb3VudFJlc3BvbnNlID0gYXdhaXQgdGhpcy5nZXRNZXRob2QoXG4gICAgICAgICdnZXRJbnB1dHNGb3JBbW91bnQnLFxuICAgICAgKSh0YXJnZXRzLCBOdW1iZXIoZmVlUmF0ZVBlclZiKSwgZml4ZWRJbnB1dHMpO1xuICAgICAgaW5wdXRzID0gaW5wdXRzRm9yQW1vdW50LmlucHV0cztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZml4ZWRJbnB1dHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdOb3QgZW5vdWdoIGJhbGFuY2UgZ2V0SW5wdXRzRm9yQW1vdW50Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbnB1dHMgPSBmaXhlZElucHV0cztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaW5wdXRzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBJbml0aWFsaXplKFxuICAgIGNvbGxhdGVyYWw6IGJpZ2ludCxcbiAgICBmZWVSYXRlUGVyVmI6IGJpZ2ludCxcbiAgICBmaXhlZElucHV0czogSW5wdXRbXSxcbiAgKTogUHJvbWlzZTxJbml0aWFsaXplUmVzcG9uc2U+IHtcbiAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWROZXR3b3JrKCk7XG4gICAgY29uc3QgcGF5b3V0QWRkcmVzczogQWRkcmVzcyA9IGF3YWl0IHRoaXMuY2xpZW50LndhbGxldC5nZXRVbnVzZWRBZGRyZXNzKFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgICBjb25zdCBwYXlvdXRTUEs6IEJ1ZmZlciA9IGFkZHJlc3MudG9PdXRwdXRTY3JpcHQoXG4gICAgICBwYXlvdXRBZGRyZXNzLmFkZHJlc3MsXG4gICAgICBuZXR3b3JrLFxuICAgICk7XG4gICAgY29uc3QgY2hhbmdlQWRkcmVzczogQWRkcmVzcyA9IGF3YWl0IHRoaXMuY2xpZW50LndhbGxldC5nZXRVbnVzZWRBZGRyZXNzKFxuICAgICAgdHJ1ZSxcbiAgICApO1xuICAgIGNvbnN0IGNoYW5nZVNQSzogQnVmZmVyID0gYWRkcmVzcy50b091dHB1dFNjcmlwdChcbiAgICAgIGNoYW5nZUFkZHJlc3MuYWRkcmVzcyxcbiAgICAgIG5ldHdvcmssXG4gICAgKTtcblxuICAgIGNvbnN0IGZ1bmRpbmdBZGRyZXNzOiBBZGRyZXNzID0gYXdhaXQgdGhpcy5jbGllbnQud2FsbGV0LmdldFVudXNlZEFkZHJlc3MoXG4gICAgICBmYWxzZSxcbiAgICApO1xuICAgIGNvbnN0IGZ1bmRpbmdQdWJLZXk6IEJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGZ1bmRpbmdBZGRyZXNzLnB1YmxpY0tleSwgJ2hleCcpO1xuXG4gICAgaWYgKGZ1bmRpbmdBZGRyZXNzLmFkZHJlc3MgPT09IHBheW91dEFkZHJlc3MuYWRkcmVzcylcbiAgICAgIHRocm93IEVycm9yKCdBZGRyZXNzIHJldXNlJyk7XG5cbiAgICBjb25zdCBpbnB1dHM6IElucHV0W10gPSBhd2FpdCB0aGlzLkdldElucHV0c0ZvckFtb3VudChcbiAgICAgIGNvbGxhdGVyYWwsXG4gICAgICBmZWVSYXRlUGVyVmIsXG4gICAgICBmaXhlZElucHV0cyxcbiAgICApO1xuICAgIGNvbnN0IGZ1bmRpbmdJbnB1dHM6IEZ1bmRpbmdJbnB1dFtdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBpbnB1dHMubWFwKGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dFRvRnVuZGluZ0lucHV0KGlucHV0KTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBwYXlvdXRTZXJpYWxJZDogYmlnaW50ID0gZ2VuZXJhdGVTZXJpYWxJZCgpO1xuICAgIGNvbnN0IGNoYW5nZVNlcmlhbElkOiBiaWdpbnQgPSBnZW5lcmF0ZVNlcmlhbElkKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZnVuZGluZ1B1YktleSxcbiAgICAgIHBheW91dFNQSyxcbiAgICAgIHBheW91dFNlcmlhbElkLFxuICAgICAgZnVuZGluZ0lucHV0cyxcbiAgICAgIGNoYW5nZVNQSyxcbiAgICAgIGNoYW5nZVNlcmlhbElkLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVE9ETzogQWRkIEdldFBheW91dEZyb21PdXRjb21lc1xuICAgKlxuICAgKiBwcml2YXRlIEdldFBheW91dHNGcm9tT3V0Y29tZXMoXG4gICAqICAgY29udHJhY3REZXNjcmlwdG9yOiBDb250cmFjdERlc2NyaXB0b3JWMCxcbiAgICogICB0b3RhbENvbGxhdGVyYWw6IGJpZ2ludCxcbiAgICogKTogUGF5b3V0UmVxdWVzdFtdIHt9XG4gICAqL1xuXG4gIHByaXZhdGUgR2V0UGF5b3V0c0Zyb21QYXlvdXRGdW5jdGlvbihcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIGNvbnRyYWN0RGVzY3JpcHRvcjogQ29udHJhY3REZXNjcmlwdG9yVjEsXG4gICAgb3JhY2xlSW5mbzogT3JhY2xlSW5mb1YwLFxuICAgIHRvdGFsQ29sbGF0ZXJhbDogYmlnaW50LFxuICApOiBHZXRQYXlvdXRzUmVzcG9uc2Uge1xuICAgIGlmIChfZGxjT2ZmZXIudHlwZSAhPT0gTWVzc2FnZVR5cGUuRGxjT2ZmZXJWMClcbiAgICAgIHRocm93IEVycm9yKCdEbGNPZmZlciBtdXN0IGJlIFYwJyk7XG4gICAgY29uc3QgZGxjT2ZmZXIgPSBfZGxjT2ZmZXIgYXMgRGxjT2ZmZXJWMDtcbiAgICBpZiAoY29udHJhY3REZXNjcmlwdG9yLnBheW91dEZ1bmN0aW9uLnR5cGUgIT09IE1lc3NhZ2VUeXBlLlBheW91dEZ1bmN0aW9uVjApXG4gICAgICB0aHJvdyBFcnJvcignUGF5b3V0RnVuY3Rpb24gbXVzdCBiZSBWMCcpO1xuICAgIGNvbnN0IHBheW91dEZ1bmN0aW9uID0gY29udHJhY3REZXNjcmlwdG9yLnBheW91dEZ1bmN0aW9uIGFzIFBheW91dEZ1bmN0aW9uVjA7XG4gICAgaWYgKHBheW91dEZ1bmN0aW9uLnBpZWNlcy5sZW5ndGggPT09IDApXG4gICAgICB0aHJvdyBFcnJvcignUGF5b3V0RnVuY3Rpb24gbXVzdCBoYXZlIGF0IGxlYXN0IG9uY2UgUGF5b3V0Q3VydmVQaWVjZScpO1xuICAgIGlmIChwYXlvdXRGdW5jdGlvbi5waWVjZXMubGVuZ3RoID4gMSlcbiAgICAgIHRocm93IEVycm9yKCdNb3JlIHRoYW4gb25lIFBheW91dEN1cnZlUGllY2Ugbm90IHN1cHBvcnRlZCcpO1xuICAgIGNvbnN0IHBheW91dEN1cnZlUGllY2UgPSBwYXlvdXRGdW5jdGlvbi5waWVjZXNbMF1cbiAgICAgIC5wYXlvdXRDdXJ2ZVBpZWNlIGFzIEh5cGVyYm9sYVBheW91dEN1cnZlUGllY2U7XG4gICAgaWYgKFxuICAgICAgcGF5b3V0Q3VydmVQaWVjZS50eXBlICE9PSBNZXNzYWdlVHlwZS5IeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlICYmXG4gICAgICBwYXlvdXRDdXJ2ZVBpZWNlLnR5cGUgIT09IE1lc3NhZ2VUeXBlLk9sZEh5cGVyYm9sYVBheW91dEN1cnZlUGllY2VcbiAgICApXG4gICAgICB0aHJvdyBFcnJvcignTXVzdCBiZSBIeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlJyk7XG4gICAgaWYgKHBheW91dEN1cnZlUGllY2UuYiAhPT0gQmlnSW50KDApIHx8IHBheW91dEN1cnZlUGllY2UuYyAhPT0gQmlnSW50KDApKVxuICAgICAgdGhyb3cgRXJyb3IoJ2IgYW5kIGMgSHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZSB2YWx1ZXMgbXVzdCBiZSAwJyk7XG4gICAgY29uc3QgZXZlbnREZXNjcmlwdG9yID0gb3JhY2xlSW5mby5hbm5vdW5jZW1lbnQub3JhY2xlRXZlbnRcbiAgICAgIC5ldmVudERlc2NyaXB0b3IgYXMgRGlnaXREZWNvbXBvc2l0aW9uRXZlbnREZXNjcmlwdG9yVjA7XG4gICAgaWYgKFxuICAgICAgZXZlbnREZXNjcmlwdG9yLnR5cGUgIT09IE1lc3NhZ2VUeXBlLkRpZ2l0RGVjb21wb3NpdGlvbkV2ZW50RGVzY3JpcHRvclYwXG4gICAgKVxuICAgICAgdGhyb3cgRXJyb3IoJ09ubHkgRGlnaXREZWNvbXBvc2l0aW9uIE9yYWNsZSBFdmVudHMgc3VwcG9ydGVkJyk7XG5cbiAgICBjb25zdCByb3VuZGluZ0ludGVydmFscyA9IGNvbnRyYWN0RGVzY3JpcHRvci5yb3VuZGluZ0ludGVydmFscztcbiAgICBjb25zdCBjZXRQYXlvdXRzID0gSHlwZXJib2xhUGF5b3V0Q3VydmUuY29tcHV0ZVBheW91dHMoXG4gICAgICBwYXlvdXRGdW5jdGlvbixcbiAgICAgIHRvdGFsQ29sbGF0ZXJhbCxcbiAgICAgIHJvdW5kaW5nSW50ZXJ2YWxzLFxuICAgICk7XG5cbiAgICBjb25zdCBwYXlvdXRHcm91cHM6IFBheW91dEdyb3VwW10gPSBbXTtcbiAgICBjZXRQYXlvdXRzLmZvckVhY2goKHApID0+IHtcbiAgICAgIHBheW91dEdyb3Vwcy5wdXNoKHtcbiAgICAgICAgcGF5b3V0OiBwLnBheW91dCxcbiAgICAgICAgZ3JvdXBzOiBncm91cEJ5SWdub3JpbmdEaWdpdHMoXG4gICAgICAgICAgcC5pbmRleEZyb20sXG4gICAgICAgICAgcC5pbmRleFRvLFxuICAgICAgICAgIGV2ZW50RGVzY3JpcHRvci5iYXNlLFxuICAgICAgICAgIGNvbnRyYWN0RGVzY3JpcHRvci5udW1EaWdpdHMsXG4gICAgICAgICksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJWYWx1ZXNNZXNzYWdlc0xpc3QgPSB0aGlzLkdlbmVyYXRlTWVzc2FnZXMob3JhY2xlSW5mbyk7XG5cbiAgICBjb25zdCB7IHBheW91dHMsIG1lc3NhZ2VzTGlzdCB9ID0gb3V0cHV0c1RvUGF5b3V0cyhcbiAgICAgIHBheW91dEdyb3VwcyxcbiAgICAgIHJWYWx1ZXNNZXNzYWdlc0xpc3QsXG4gICAgICBkbGNPZmZlci5vZmZlckNvbGxhdGVyYWxTYXRvc2hpcyxcbiAgICAgIGRsY09mZmVyLmNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWwgLSBkbGNPZmZlci5vZmZlckNvbGxhdGVyYWxTYXRvc2hpcyxcbiAgICAgIHRydWUsXG4gICAgKTtcblxuICAgIHJldHVybiB7IHBheW91dHMsIHBheW91dEdyb3VwcywgbWVzc2FnZXNMaXN0IH07XG4gIH1cblxuICBwcml2YXRlIEdldFBheW91dHNGcm9tUG9seW5vbWlhbFBheW91dEZ1bmN0aW9uKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgY29udHJhY3REZXNjcmlwdG9yOiBDb250cmFjdERlc2NyaXB0b3JWMSxcbiAgICBvcmFjbGVJbmZvOiBPcmFjbGVJbmZvVjAsXG4gICAgdG90YWxDb2xsYXRlcmFsOiBiaWdpbnQsXG4gICk6IEdldFBheW91dHNSZXNwb25zZSB7XG4gICAgaWYgKF9kbGNPZmZlci50eXBlICE9PSBNZXNzYWdlVHlwZS5EbGNPZmZlclYwKVxuICAgICAgdGhyb3cgRXJyb3IoJ0RsY09mZmVyIG11c3QgYmUgVjAnKTtcbiAgICBjb25zdCBkbGNPZmZlciA9IF9kbGNPZmZlciBhcyBEbGNPZmZlclYwO1xuICAgIGlmIChjb250cmFjdERlc2NyaXB0b3IucGF5b3V0RnVuY3Rpb24udHlwZSAhPT0gTWVzc2FnZVR5cGUuUGF5b3V0RnVuY3Rpb25WMClcbiAgICAgIHRocm93IEVycm9yKCdQYXlvdXRGdW5jdGlvbiBtdXN0IGJlIFYwJyk7XG4gICAgY29uc3QgcGF5b3V0RnVuY3Rpb24gPSBjb250cmFjdERlc2NyaXB0b3IucGF5b3V0RnVuY3Rpb24gYXMgUGF5b3V0RnVuY3Rpb25WMDtcbiAgICBpZiAocGF5b3V0RnVuY3Rpb24ucGllY2VzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRocm93IEVycm9yKCdQYXlvdXRGdW5jdGlvbiBtdXN0IGhhdmUgYXQgbGVhc3Qgb25jZSBQYXlvdXRDdXJ2ZVBpZWNlJyk7XG4gICAgZm9yIChjb25zdCBwaWVjZSBvZiBwYXlvdXRGdW5jdGlvbi5waWVjZXMpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcGllY2UucGF5b3V0Q3VydmVQaWVjZS50eXBlICE9PSBNZXNzYWdlVHlwZS5Qb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZVxuICAgICAgKVxuICAgICAgICB0aHJvdyBFcnJvcignTXVzdCBiZSBQb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZScpO1xuICAgIH1cbiAgICBjb25zdCBldmVudERlc2NyaXB0b3IgPSBvcmFjbGVJbmZvLmFubm91bmNlbWVudC5vcmFjbGVFdmVudFxuICAgICAgLmV2ZW50RGVzY3JpcHRvciBhcyBEaWdpdERlY29tcG9zaXRpb25FdmVudERlc2NyaXB0b3JWMDtcbiAgICBpZiAoXG4gICAgICBldmVudERlc2NyaXB0b3IudHlwZSAhPT0gTWVzc2FnZVR5cGUuRGlnaXREZWNvbXBvc2l0aW9uRXZlbnREZXNjcmlwdG9yVjBcbiAgICApXG4gICAgICB0aHJvdyBFcnJvcignT25seSBEaWdpdERlY29tcG9zaXRpb24gT3JhY2xlIEV2ZW50cyBzdXBwb3J0ZWQnKTtcblxuICAgIGNvbnN0IHJvdW5kaW5nSW50ZXJ2YWxzID0gY29udHJhY3REZXNjcmlwdG9yLnJvdW5kaW5nSW50ZXJ2YWxzO1xuICAgIGNvbnN0IGNldFBheW91dHMgPSBQb2x5bm9taWFsUGF5b3V0Q3VydmUuY29tcHV0ZVBheW91dHMoXG4gICAgICBwYXlvdXRGdW5jdGlvbixcbiAgICAgIHRvdGFsQ29sbGF0ZXJhbCxcbiAgICAgIHJvdW5kaW5nSW50ZXJ2YWxzLFxuICAgICk7XG5cbiAgICBjb25zdCBwYXlvdXRHcm91cHM6IFBheW91dEdyb3VwW10gPSBbXTtcbiAgICBjZXRQYXlvdXRzLmZvckVhY2goKHApID0+IHtcbiAgICAgIHBheW91dEdyb3Vwcy5wdXNoKHtcbiAgICAgICAgcGF5b3V0OiBwLnBheW91dCxcbiAgICAgICAgZ3JvdXBzOiBncm91cEJ5SWdub3JpbmdEaWdpdHMoXG4gICAgICAgICAgcC5pbmRleEZyb20sXG4gICAgICAgICAgcC5pbmRleFRvLFxuICAgICAgICAgIGV2ZW50RGVzY3JpcHRvci5iYXNlLFxuICAgICAgICAgIGNvbnRyYWN0RGVzY3JpcHRvci5udW1EaWdpdHMsXG4gICAgICAgICksXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHJWYWx1ZXNNZXNzYWdlc0xpc3QgPSB0aGlzLkdlbmVyYXRlTWVzc2FnZXMob3JhY2xlSW5mbyk7XG5cbiAgICBjb25zdCB7IHBheW91dHMsIG1lc3NhZ2VzTGlzdCB9ID0gb3V0cHV0c1RvUGF5b3V0cyhcbiAgICAgIHBheW91dEdyb3VwcyxcbiAgICAgIHJWYWx1ZXNNZXNzYWdlc0xpc3QsXG4gICAgICBkbGNPZmZlci5vZmZlckNvbGxhdGVyYWxTYXRvc2hpcyxcbiAgICAgIGRsY09mZmVyLmNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWwgLSBkbGNPZmZlci5vZmZlckNvbGxhdGVyYWxTYXRvc2hpcyxcbiAgICAgIHRydWUsXG4gICAgKTtcblxuICAgIHJldHVybiB7IHBheW91dHMsIHBheW91dEdyb3VwcywgbWVzc2FnZXNMaXN0IH07XG4gIH1cblxuICBwcml2YXRlIEdldFBheW91dHMoX2RsY09mZmVyOiBEbGNPZmZlcik6IEdldFBheW91dHNSZXNwb25zZVtdIHtcbiAgICBjb25zdCB7IGRsY09mZmVyIH0gPSBjaGVja1R5cGVzKHsgX2RsY09mZmVyIH0pO1xuXG4gICAgY29uc3QgY29udHJhY3RJbmZvID0gZGxjT2ZmZXIuY29udHJhY3RJbmZvO1xuICAgIGNvbnN0IHRvdGFsQ29sbGF0ZXJhbCA9IGNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWw7XG4gICAgY29uc3QgY29udHJhY3RPcmFjbGVQYWlycyA9IHRoaXMuR2V0Q29udHJhY3RPcmFjbGVQYWlycyhjb250cmFjdEluZm8pO1xuXG4gICAgY29uc3QgcGF5b3V0UmVzcG9uc2VzID0gY29udHJhY3RPcmFjbGVQYWlycy5tYXAoXG4gICAgICAoeyBjb250cmFjdERlc2NyaXB0b3IsIG9yYWNsZUluZm8gfSkgPT5cbiAgICAgICAgdGhpcy5HZXRQYXlvdXRzRnJvbUNvbnRyYWN0RGVzY3JpcHRvcihcbiAgICAgICAgICBkbGNPZmZlcixcbiAgICAgICAgICBjb250cmFjdERlc2NyaXB0b3IsXG4gICAgICAgICAgb3JhY2xlSW5mbyxcbiAgICAgICAgICB0b3RhbENvbGxhdGVyYWwsXG4gICAgICAgICksXG4gICAgKTtcblxuICAgIHJldHVybiBwYXlvdXRSZXNwb25zZXM7XG4gIH1cblxuICBwcml2YXRlIEZsYXR0ZW5QYXlvdXRzKHBheW91dFJlc3BvbnNlczogR2V0UGF5b3V0c1Jlc3BvbnNlW10pIHtcbiAgICByZXR1cm4gcGF5b3V0UmVzcG9uc2VzLnJlZHVjZShcbiAgICAgIChhY2MsIHsgcGF5b3V0cywgcGF5b3V0R3JvdXBzLCBtZXNzYWdlc0xpc3QgfSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHBheW91dHM6IGFjYy5wYXlvdXRzLmNvbmNhdChwYXlvdXRzKSxcbiAgICAgICAgICBwYXlvdXRHcm91cHM6IGFjYy5wYXlvdXRHcm91cHMuY29uY2F0KHBheW91dEdyb3VwcyksXG4gICAgICAgICAgbWVzc2FnZXNMaXN0OiBhY2MubWVzc2FnZXNMaXN0LmNvbmNhdChtZXNzYWdlc0xpc3QpLFxuICAgICAgICB9O1xuICAgICAgfSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBHZXRJbmRpY2VzRnJvbVBheW91dHMocGF5b3V0UmVzcG9uc2VzOiBHZXRQYXlvdXRzUmVzcG9uc2VbXSkge1xuICAgIHJldHVybiBwYXlvdXRSZXNwb25zZXMucmVkdWNlKFxuICAgICAgKHByZXYsIGFjYykgPT4ge1xuICAgICAgICByZXR1cm4gcHJldi5jb25jYXQoe1xuICAgICAgICAgIHN0YXJ0aW5nTWVzc2FnZXNJbmRleDpcbiAgICAgICAgICAgIHByZXZbcHJldi5sZW5ndGggLSAxXS5zdGFydGluZ01lc3NhZ2VzSW5kZXggK1xuICAgICAgICAgICAgYWNjLm1lc3NhZ2VzTGlzdC5sZW5ndGgsXG4gICAgICAgICAgc3RhcnRpbmdQYXlvdXRHcm91cHNJbmRleDpcbiAgICAgICAgICAgIHByZXZbcHJldi5sZW5ndGggLSAxXS5zdGFydGluZ1BheW91dEdyb3Vwc0luZGV4ICtcbiAgICAgICAgICAgIGFjYy5wYXlvdXRHcm91cHMubGVuZ3RoLFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBbeyBzdGFydGluZ01lc3NhZ2VzSW5kZXg6IDAsIHN0YXJ0aW5nUGF5b3V0R3JvdXBzSW5kZXg6IDAgfV0sXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgR2V0UGF5b3V0c0Zyb21Db250cmFjdERlc2NyaXB0b3IoXG4gICAgZGxjT2ZmZXI6IERsY09mZmVyVjAsXG4gICAgY29udHJhY3REZXNjcmlwdG9yOiBDb250cmFjdERlc2NyaXB0b3IsXG4gICAgb3JhY2xlSW5mbzogT3JhY2xlSW5mb1YwLFxuICAgIHRvdGFsQ29sbGF0ZXJhbDogYmlnaW50LFxuICApIHtcbiAgICBzd2l0Y2ggKGNvbnRyYWN0RGVzY3JpcHRvci50eXBlKSB7XG4gICAgICBjYXNlIE1lc3NhZ2VUeXBlLkNvbnRyYWN0RGVzY3JpcHRvclYwOiB7XG4gICAgICAgIHRocm93IEVycm9yKCdDb250cmFjdERlc2NyaXB0b3JWMCBub3QgeWV0IHN1cHBvcnRlZCcpO1xuICAgICAgfVxuICAgICAgY2FzZSBNZXNzYWdlVHlwZS5Db250cmFjdERlc2NyaXB0b3JWMTpcbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IGNvbnRyYWN0RGVzY3JpcHRvclYxID0gY29udHJhY3REZXNjcmlwdG9yIGFzIENvbnRyYWN0RGVzY3JpcHRvclYxO1xuICAgICAgICAgIGNvbnN0IHBheW91dEZ1bmN0aW9uID0gY29udHJhY3REZXNjcmlwdG9yVjEucGF5b3V0RnVuY3Rpb24gYXMgUGF5b3V0RnVuY3Rpb25WMDtcblxuICAgICAgICAgIC8vIFRPRE86IGFkZCBhIGJldHRlciBjaGVjayBmb3IgdGhpc1xuICAgICAgICAgIGNvbnN0IHBheW91dEN1cnZlUGllY2UgPSBwYXlvdXRGdW5jdGlvbi5waWVjZXNbMF0ucGF5b3V0Q3VydmVQaWVjZTtcblxuICAgICAgICAgIHN3aXRjaCAocGF5b3V0Q3VydmVQaWVjZS50eXBlKSB7XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VUeXBlLkh5cGVyYm9sYVBheW91dEN1cnZlUGllY2U6XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLkdldFBheW91dHNGcm9tUGF5b3V0RnVuY3Rpb24oXG4gICAgICAgICAgICAgICAgZGxjT2ZmZXIsXG4gICAgICAgICAgICAgICAgY29udHJhY3REZXNjcmlwdG9yIGFzIENvbnRyYWN0RGVzY3JpcHRvclYxLFxuICAgICAgICAgICAgICAgIG9yYWNsZUluZm8sXG4gICAgICAgICAgICAgICAgdG90YWxDb2xsYXRlcmFsLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSBNZXNzYWdlVHlwZS5PbGRIeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlOlxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5HZXRQYXlvdXRzRnJvbVBheW91dEZ1bmN0aW9uKFxuICAgICAgICAgICAgICAgIGRsY09mZmVyLFxuICAgICAgICAgICAgICAgIGNvbnRyYWN0RGVzY3JpcHRvciBhcyBDb250cmFjdERlc2NyaXB0b3JWMSxcbiAgICAgICAgICAgICAgICBvcmFjbGVJbmZvLFxuICAgICAgICAgICAgICAgIHRvdGFsQ29sbGF0ZXJhbCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNhc2UgTWVzc2FnZVR5cGUuUG9seW5vbWlhbFBheW91dEN1cnZlUGllY2U6XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLkdldFBheW91dHNGcm9tUG9seW5vbWlhbFBheW91dEZ1bmN0aW9uKFxuICAgICAgICAgICAgICAgIGRsY09mZmVyLFxuICAgICAgICAgICAgICAgIGNvbnRyYWN0RGVzY3JpcHRvciBhcyBDb250cmFjdERlc2NyaXB0b3JWMSxcbiAgICAgICAgICAgICAgICBvcmFjbGVJbmZvLFxuICAgICAgICAgICAgICAgIHRvdGFsQ29sbGF0ZXJhbCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHRocm93IEVycm9yKCdDb250cmFjdERlc2NyaXB0b3IgbXVzdCBiZSBWMCBvciBWMScpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGVEbGNUeHMoXG4gICAgX2RsY09mZmVyOiBEbGNPZmZlcixcbiAgICBfZGxjQWNjZXB0OiBEbGNBY2NlcHQsXG4gICk6IFByb21pc2U8Q3JlYXRlRGxjVHhzUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7IGRsY09mZmVyLCBkbGNBY2NlcHQgfSA9IGNoZWNrVHlwZXMoe1xuICAgICAgX2RsY09mZmVyLFxuICAgICAgX2RsY0FjY2VwdCxcbiAgICB9KTtcblxuICAgIGNvbnN0IGxvY2FsRnVuZFB1YmtleSA9IGRsY09mZmVyLmZ1bmRpbmdQdWJLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgIGNvbnN0IHJlbW90ZUZ1bmRQdWJrZXkgPSBkbGNBY2NlcHQuZnVuZGluZ1B1YktleS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgbG9jYWxGaW5hbFNjcmlwdFB1YmtleSA9IGRsY09mZmVyLnBheW91dFNQSy50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgcmVtb3RlRmluYWxTY3JpcHRQdWJrZXkgPSBkbGNBY2NlcHQucGF5b3V0U1BLLnRvU3RyaW5nKCdoZXgnKTtcbiAgICBjb25zdCBsb2NhbENoYW5nZVNjcmlwdFB1YmtleSA9IGRsY09mZmVyLmNoYW5nZVNQSy50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgcmVtb3RlQ2hhbmdlU2NyaXB0UHVia2V5ID0gZGxjQWNjZXB0LmNoYW5nZVNQSy50b1N0cmluZygnaGV4Jyk7XG5cbiAgICBjb25zdCBsb2NhbElucHV0czogVXR4b1tdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBkbGNPZmZlci5mdW5kaW5nSW5wdXRzLm1hcChhc3luYyAoZnVuZGluZ0lucHV0KSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gYXdhaXQgdGhpcy5mdW5kaW5nSW5wdXRUb0lucHV0KGZ1bmRpbmdJbnB1dCwgZmFsc2UpO1xuICAgICAgICByZXR1cm4gaW5wdXQudG9VdHhvKCk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgY29uc3QgcmVtb3RlSW5wdXRzOiBVdHhvW10gPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGRsY0FjY2VwdC5mdW5kaW5nSW5wdXRzLm1hcChhc3luYyAoZnVuZGluZ0lucHV0KSA9PiB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gYXdhaXQgdGhpcy5mdW5kaW5nSW5wdXRUb0lucHV0KGZ1bmRpbmdJbnB1dCwgZmFsc2UpO1xuICAgICAgICByZXR1cm4gaW5wdXQudG9VdHhvKCk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgY29uc3QgbG9jYWxJbnB1dEFtb3VudCA9IGxvY2FsSW5wdXRzLnJlZHVjZTxudW1iZXI+KFxuICAgICAgKHByZXYsIGN1cikgPT4gcHJldiArIGN1ci5hbW91bnQuR2V0U2F0b3NoaUFtb3VudCgpLFxuICAgICAgMCxcbiAgICApO1xuXG4gICAgY29uc3QgcmVtb3RlSW5wdXRBbW91bnQgPSByZW1vdGVJbnB1dHMucmVkdWNlPG51bWJlcj4oXG4gICAgICAocHJldiwgY3VyKSA9PiBwcmV2ICsgY3VyLmFtb3VudC5HZXRTYXRvc2hpQW1vdW50KCksXG4gICAgICAwLFxuICAgICk7XG5cbiAgICBjb25zdCBwYXlvdXRSZXNwb25zZXMgPSB0aGlzLkdldFBheW91dHMoZGxjT2ZmZXIpO1xuICAgIGNvbnN0IHsgcGF5b3V0cywgbWVzc2FnZXNMaXN0IH0gPSB0aGlzLkZsYXR0ZW5QYXlvdXRzKHBheW91dFJlc3BvbnNlcyk7XG5cbiAgICBjb25zdCBkbGNUeFJlcXVlc3Q6IENyZWF0ZURsY1RyYW5zYWN0aW9uc1JlcXVlc3QgPSB7XG4gICAgICBwYXlvdXRzLFxuICAgICAgbG9jYWxGdW5kUHVia2V5LFxuICAgICAgbG9jYWxGaW5hbFNjcmlwdFB1YmtleSxcbiAgICAgIHJlbW90ZUZ1bmRQdWJrZXksXG4gICAgICByZW1vdGVGaW5hbFNjcmlwdFB1YmtleSxcbiAgICAgIGxvY2FsSW5wdXRBbW91bnQsXG4gICAgICBsb2NhbENvbGxhdGVyYWxBbW91bnQ6IGRsY09mZmVyLm9mZmVyQ29sbGF0ZXJhbFNhdG9zaGlzLFxuICAgICAgbG9jYWxQYXlvdXRTZXJpYWxJZDogZGxjT2ZmZXIucGF5b3V0U2VyaWFsSWQsXG4gICAgICBsb2NhbENoYW5nZVNlcmlhbElkOiBkbGNPZmZlci5jaGFuZ2VTZXJpYWxJZCxcbiAgICAgIHJlbW90ZUlucHV0QW1vdW50LFxuICAgICAgcmVtb3RlQ29sbGF0ZXJhbEFtb3VudDogZGxjQWNjZXB0LmFjY2VwdENvbGxhdGVyYWxTYXRvc2hpcyxcbiAgICAgIHJlbW90ZVBheW91dFNlcmlhbElkOiBkbGNBY2NlcHQucGF5b3V0U2VyaWFsSWQsXG4gICAgICByZW1vdGVDaGFuZ2VTZXJpYWxJZDogZGxjQWNjZXB0LmNoYW5nZVNlcmlhbElkLFxuICAgICAgcmVmdW5kTG9ja3RpbWU6IGRsY09mZmVyLnJlZnVuZExvY2t0aW1lLFxuICAgICAgbG9jYWxJbnB1dHMsXG4gICAgICByZW1vdGVJbnB1dHMsXG4gICAgICBsb2NhbENoYW5nZVNjcmlwdFB1YmtleSxcbiAgICAgIHJlbW90ZUNoYW5nZVNjcmlwdFB1YmtleSxcbiAgICAgIGZlZVJhdGU6IE51bWJlcihkbGNPZmZlci5mZWVSYXRlUGVyVmIpLFxuICAgICAgY2V0TG9ja1RpbWU6IGRsY09mZmVyLmNldExvY2t0aW1lLFxuICAgICAgZnVuZE91dHB1dFNlcmlhbElkOiBkbGNPZmZlci5mdW5kT3V0cHV0U2VyaWFsSWQsXG4gICAgfTtcblxuICAgIGNvbnN0IGRsY1R4cyA9IGF3YWl0IHRoaXMuQ3JlYXRlRGxjVHJhbnNhY3Rpb25zKGRsY1R4UmVxdWVzdCk7XG5cbiAgICBjb25zdCBkbGNUcmFuc2FjdGlvbnMgPSBuZXcgRGxjVHJhbnNhY3Rpb25zVjAoKTtcbiAgICBkbGNUcmFuc2FjdGlvbnMuZnVuZFR4ID0gVHguZGVjb2RlKFN0cmVhbVJlYWRlci5mcm9tSGV4KGRsY1R4cy5mdW5kVHhIZXgpKTtcbiAgICBkbGNUcmFuc2FjdGlvbnMuZnVuZFR4Vm91dCA9IFtcbiAgICAgIEJpZ0ludChkbGNPZmZlci5jaGFuZ2VTZXJpYWxJZCksXG4gICAgICBCaWdJbnQoZGxjQWNjZXB0LmNoYW5nZVNlcmlhbElkKSxcbiAgICAgIEJpZ0ludChkbGNUeFJlcXVlc3QuZnVuZE91dHB1dFNlcmlhbElkKSxcbiAgICBdXG4gICAgICAuc29ydCgoYSwgYikgPT4gKGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwKSlcbiAgICAgIC5maW5kSW5kZXgoKGkpID0+IEJpZ0ludChpKSA9PT0gQmlnSW50KGRsY1R4UmVxdWVzdC5mdW5kT3V0cHV0U2VyaWFsSWQpKTtcbiAgICBkbGNUcmFuc2FjdGlvbnMucmVmdW5kVHggPSBUeC5kZWNvZGUoXG4gICAgICBTdHJlYW1SZWFkZXIuZnJvbUhleChkbGNUeHMucmVmdW5kVHhIZXgpLFxuICAgICk7XG4gICAgZGxjVHJhbnNhY3Rpb25zLmNldHMgPSBkbGNUeHMuY2V0c0hleC5tYXAoKGNldEhleCkgPT4ge1xuICAgICAgcmV0dXJuIFR4LmRlY29kZShTdHJlYW1SZWFkZXIuZnJvbUhleChjZXRIZXgpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IGRsY1RyYW5zYWN0aW9ucywgbWVzc2FnZXNMaXN0IH07XG4gIH1cblxuICBwcml2YXRlIEdlbmVyYXRlRW51bU1lc3NhZ2VzKG9yYWNsZUV2ZW50OiBPcmFjbGVFdmVudFYwKTogTWVzc2FnZXNbXSB7XG4gICAgdGhyb3cgRXJyb3IoJ09ubHkgRGlnaXREZWNvbXBvc2l0aW9uIE9yYWNsZSBFdmVudHMgc3VwcG9ydGVkJyk7XG4gIH1cblxuICBwcml2YXRlIEdlbmVyYXRlRGlnaXREZWNvbXBvc2l0aW9uTWVzc2FnZXMoXG4gICAgb3JhY2xlRXZlbnQ6IE9yYWNsZUV2ZW50VjAsXG4gICk6IE1lc3NhZ2VzW10ge1xuICAgIGNvbnN0IG9yYWNsZU5vbmNlcyA9IG9yYWNsZUV2ZW50Lm9yYWNsZU5vbmNlcztcbiAgICBjb25zdCBldmVudERlc2NyaXB0b3IgPSBvcmFjbGVFdmVudC5ldmVudERlc2NyaXB0b3IgYXMgRGlnaXREZWNvbXBvc2l0aW9uRXZlbnREZXNjcmlwdG9yVjA7XG5cbiAgICBjb25zdCBtZXNzYWdlc0xpc3Q6IE1lc3NhZ2VzW10gPSBbXTtcbiAgICBvcmFjbGVOb25jZXMuZm9yRWFjaCgoKSA9PiB7XG4gICAgICBjb25zdCBtZXNzYWdlcyA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBldmVudERlc2NyaXB0b3IuYmFzZTsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG0gPSBpLnRvU3RyaW5nKCk7XG4gICAgICAgIG1lc3NhZ2VzLnB1c2gobSk7XG4gICAgICB9XG4gICAgICBtZXNzYWdlc0xpc3QucHVzaCh7IG1lc3NhZ2VzIH0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG1lc3NhZ2VzTGlzdDtcbiAgfVxuXG4gIHByaXZhdGUgR2VuZXJhdGVNZXNzYWdlcyhvcmFjbGVJbmZvOiBPcmFjbGVJbmZvVjApOiBNZXNzYWdlc1tdIHtcbiAgICBjb25zdCBvcmFjbGVFdmVudCA9IG9yYWNsZUluZm8uYW5ub3VuY2VtZW50Lm9yYWNsZUV2ZW50O1xuXG4gICAgc3dpdGNoIChvcmFjbGVFdmVudC5ldmVudERlc2NyaXB0b3IudHlwZSkge1xuICAgICAgY2FzZSBNZXNzYWdlVHlwZS5FbnVtRXZlbnREZXNjcmlwdG9yVjA6XG4gICAgICAgIHJldHVybiB0aGlzLkdlbmVyYXRlRW51bU1lc3NhZ2VzKG9yYWNsZUV2ZW50KTtcbiAgICAgIGNhc2UgTWVzc2FnZVR5cGUuRGlnaXREZWNvbXBvc2l0aW9uRXZlbnREZXNjcmlwdG9yVjA6XG4gICAgICAgIHJldHVybiB0aGlzLkdlbmVyYXRlRGlnaXREZWNvbXBvc2l0aW9uTWVzc2FnZXMob3JhY2xlRXZlbnQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgRXJyb3IoJ0V2ZW50RGVzY3JpcHRvciBtdXN0IGJlIEVudW0gb3IgRGlnaXREZWNvbXBvc2l0aW9uJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBHZXRDb250cmFjdE9yYWNsZVBhaXJzKFxuICAgIF9jb250cmFjdEluZm86IENvbnRyYWN0SW5mbyxcbiAgKTogeyBjb250cmFjdERlc2NyaXB0b3I6IENvbnRyYWN0RGVzY3JpcHRvcjsgb3JhY2xlSW5mbzogT3JhY2xlSW5mb1YwIH1bXSB7XG4gICAgc3dpdGNoIChfY29udHJhY3RJbmZvLnR5cGUpIHtcbiAgICAgIGNhc2UgTWVzc2FnZVR5cGUuQ29udHJhY3RJbmZvVjA6IHtcbiAgICAgICAgY29uc3QgY29udHJhY3RJbmZvID0gX2NvbnRyYWN0SW5mbyBhcyBDb250cmFjdEluZm9WMDtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb250cmFjdERlc2NyaXB0b3I6IGNvbnRyYWN0SW5mby5jb250cmFjdERlc2NyaXB0b3IsXG4gICAgICAgICAgICBvcmFjbGVJbmZvOiBjb250cmFjdEluZm8ub3JhY2xlSW5mbyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgfVxuICAgICAgY2FzZSBNZXNzYWdlVHlwZS5Db250cmFjdEluZm9WMToge1xuICAgICAgICByZXR1cm4gKF9jb250cmFjdEluZm8gYXMgQ29udHJhY3RJbmZvVjEpLmNvbnRyYWN0T3JhY2xlUGFpcnM7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBFcnJvcignQ29udHJhY3RJbmZvIG11c3QgYmUgVjAgb3IgVjEnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIENyZWF0ZUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBtZXNzYWdlc0xpc3Q6IE1lc3NhZ2VzW10sXG4gICAgaXNPZmZlcmVyOiBib29sZWFuLFxuICApOiBQcm9taXNlPENyZWF0ZUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7IGRsY09mZmVyLCBkbGNBY2NlcHQsIGRsY1R4cyB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgICAgX2RsY1R4cyxcbiAgICB9KTtcbiAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWROZXR3b3JrKCk7XG5cbiAgICBjb25zdCBjZXRzSGV4ID0gZGxjVHhzLmNldHMubWFwKChjZXQpID0+IGNldC5zZXJpYWxpemUoKS50b1N0cmluZygnaGV4JykpO1xuXG4gICAgY29uc3QgZnVuZGluZ1NQSyA9IFNjcmlwdC5wMndwa2hMb2NrKFxuICAgICAgaGFzaDE2MChpc09mZmVyZXIgPyBkbGNPZmZlci5mdW5kaW5nUHViS2V5IDogZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkpLFxuICAgIClcbiAgICAgIC5zZXJpYWxpemUoKVxuICAgICAgLnNsaWNlKDEpO1xuXG4gICAgY29uc3QgZnVuZGluZ0FkZHJlc3M6IHN0cmluZyA9IGFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChcbiAgICAgIGZ1bmRpbmdTUEssXG4gICAgICBuZXR3b3JrLFxuICAgICk7XG5cbiAgICBjb25zdCB7XG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICB9ID0gYXdhaXQgdGhpcy5jbGllbnQuZmluYW5jZXdhbGxldC5xdWlja0ZpbmRBZGRyZXNzKFtmdW5kaW5nQWRkcmVzc10pO1xuXG4gICAgY29uc3QgZnVuZFByaXZhdGVLZXlQYWlyID0gYXdhaXQgdGhpcy5nZXRNZXRob2QoJ2tleVBhaXInKShkZXJpdmF0aW9uUGF0aCk7XG4gICAgY29uc3QgZnVuZFByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbShmdW5kUHJpdmF0ZUtleVBhaXIuX19EKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICBjb25zdCBjb250cmFjdE9yYWNsZVBhaXJzID0gdGhpcy5HZXRDb250cmFjdE9yYWNsZVBhaXJzKFxuICAgICAgZGxjT2ZmZXIuY29udHJhY3RJbmZvLFxuICAgICk7XG5cbiAgICBjb25zdCBpbmRpY2VzID0gdGhpcy5HZXRJbmRpY2VzRnJvbVBheW91dHModGhpcy5HZXRQYXlvdXRzKF9kbGNPZmZlcikpO1xuICAgIGNvbnN0IHNpZ3M6IElTaWdbXVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgeyBvcmFjbGVJbmZvIH1dIG9mIGNvbnRyYWN0T3JhY2xlUGFpcnMuZW50cmllcygpKSB7XG4gICAgICBjb25zdCBvcmFjbGVBbm5vdW5jZW1lbnQgPSBvcmFjbGVJbmZvLmFubm91bmNlbWVudDtcblxuICAgICAgY29uc3Qgc3RhcnRpbmdJbmRleCA9IGluZGljZXNbaW5kZXhdLnN0YXJ0aW5nTWVzc2FnZXNJbmRleCxcbiAgICAgICAgZW5kaW5nSW5kZXggPSBpbmRpY2VzW2luZGV4ICsgMV0uc3RhcnRpbmdNZXNzYWdlc0luZGV4O1xuXG4gICAgICBjb25zdCBvcmFjbGVFdmVudE1lc3NhZ2VzTGlzdCA9IG1lc3NhZ2VzTGlzdC5zbGljZShcbiAgICAgICAgc3RhcnRpbmdJbmRleCxcbiAgICAgICAgZW5kaW5nSW5kZXgsXG4gICAgICApO1xuICAgICAgY29uc3Qgb3JhY2xlRXZlbnRDZXRzSGV4ID0gY2V0c0hleC5zbGljZShzdGFydGluZ0luZGV4LCBlbmRpbmdJbmRleCk7XG5cbiAgICAgIGNvbnN0IGNodW5rID0gMTAwO1xuICAgICAgY29uc3QgYWRhcHRvclNpZ1JlcXVlc3RQcm9taXNlczogUHJvbWlzZTxBZGFwdG9yUGFpcltdPltdID0gW107XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gb3JhY2xlRXZlbnRNZXNzYWdlc0xpc3QubGVuZ3RoOyBpIDwgajsgaSArPSBjaHVuaykge1xuICAgICAgICBjb25zdCB0ZW1wTWVzc2FnZXNMaXN0ID0gb3JhY2xlRXZlbnRNZXNzYWdlc0xpc3Quc2xpY2UoaSwgaSArIGNodW5rKTtcbiAgICAgICAgY29uc3QgdGVtcENldHNIZXggPSBvcmFjbGVFdmVudENldHNIZXguc2xpY2UoaSwgaSArIGNodW5rKTtcblxuICAgICAgICBjb25zdCBjZXRTaWduUmVxdWVzdDogQ3JlYXRlQ2V0QWRhcHRvclNpZ25hdHVyZXNSZXF1ZXN0ID0ge1xuICAgICAgICAgIG1lc3NhZ2VzTGlzdDogdGVtcE1lc3NhZ2VzTGlzdCxcbiAgICAgICAgICBjZXRzSGV4OiB0ZW1wQ2V0c0hleCxcbiAgICAgICAgICBwcml2a2V5OiBmdW5kUHJpdmF0ZUtleSxcbiAgICAgICAgICBmdW5kVHhJZDogZGxjVHhzLmZ1bmRUeC50eElkLnRvU3RyaW5nKCksXG4gICAgICAgICAgZnVuZFZvdXQ6IGRsY1R4cy5mdW5kVHhWb3V0LFxuICAgICAgICAgIGxvY2FsRnVuZFB1YmtleTogZGxjT2ZmZXIuZnVuZGluZ1B1YktleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgcmVtb3RlRnVuZFB1YmtleTogZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIGZ1bmRJbnB1dEFtb3VudDogZGxjVHhzLmZ1bmRUeC5vdXRwdXRzW2RsY1R4cy5mdW5kVHhWb3V0XS52YWx1ZS5zYXRzLFxuICAgICAgICAgIG9yYWNsZVB1YmtleTogb3JhY2xlQW5ub3VuY2VtZW50Lm9yYWNsZVB1YmtleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgb3JhY2xlUlZhbHVlczogb3JhY2xlQW5ub3VuY2VtZW50Lm9yYWNsZUV2ZW50Lm9yYWNsZU5vbmNlcy5tYXAoXG4gICAgICAgICAgICAobm9uY2UpID0+IG5vbmNlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICApLFxuICAgICAgICB9O1xuXG4gICAgICAgIGFkYXB0b3JTaWdSZXF1ZXN0UHJvbWlzZXMucHVzaChcbiAgICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLkNyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmVzKFxuICAgICAgICAgICAgICBjZXRTaWduUmVxdWVzdCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuYWRhcHRvclBhaXJzO1xuICAgICAgICAgIH0pKCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFkYXB0b3JQYWlyczogQWRhcHRvclBhaXJbXSA9IChcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoYWRhcHRvclNpZ1JlcXVlc3RQcm9taXNlcylcbiAgICAgICkuZmxhdCgpO1xuXG4gICAgICBzaWdzLnB1c2goXG4gICAgICAgIGFkYXB0b3JQYWlycy5tYXAoKGFkYXB0b3JQYWlyKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFNpZzogQnVmZmVyLmZyb20oYWRhcHRvclBhaXIuc2lnbmF0dXJlLCAnaGV4JyksXG4gICAgICAgICAgICBkbGVxUHJvb2Y6IEJ1ZmZlci5mcm9tKGFkYXB0b3JQYWlyLnByb29mLCAnaGV4JyksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJlZnVuZFNpZ25SZXF1ZXN0OiBHZXRSYXdSZWZ1bmRUeFNpZ25hdHVyZVJlcXVlc3QgPSB7XG4gICAgICByZWZ1bmRUeEhleDogZGxjVHhzLnJlZnVuZFR4LnNlcmlhbGl6ZSgpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIHByaXZrZXk6IGZ1bmRQcml2YXRlS2V5LFxuICAgICAgZnVuZFR4SWQ6IGRsY1R4cy5mdW5kVHgudHhJZC50b1N0cmluZygpLFxuICAgICAgZnVuZFZvdXQ6IGRsY1R4cy5mdW5kVHhWb3V0LFxuICAgICAgbG9jYWxGdW5kUHVia2V5OiBkbGNPZmZlci5mdW5kaW5nUHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIHJlbW90ZUZ1bmRQdWJrZXk6IGRsY0FjY2VwdC5mdW5kaW5nUHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIGZ1bmRJbnB1dEFtb3VudDogZGxjVHhzLmZ1bmRUeC5vdXRwdXRzW2RsY1R4cy5mdW5kVHhWb3V0XS52YWx1ZS5zYXRzLFxuICAgIH07XG5cbiAgICBjb25zdCByZWZ1bmRTaWduYXR1cmUgPSBCdWZmZXIuZnJvbShcbiAgICAgIChhd2FpdCB0aGlzLkdldFJhd1JlZnVuZFR4U2lnbmF0dXJlKHJlZnVuZFNpZ25SZXF1ZXN0KSkuaGV4LFxuICAgICAgJ2hleCcsXG4gICAgKTtcblxuICAgIGNvbnN0IGNldFNpZ25hdHVyZXMgPSBuZXcgQ2V0QWRhcHRvclNpZ25hdHVyZXNWMCgpO1xuICAgIGNldFNpZ25hdHVyZXMuc2lncyA9IHNpZ3MuZmxhdCgpO1xuXG4gICAgcmV0dXJuIHsgY2V0U2lnbmF0dXJlcywgcmVmdW5kU2lnbmF0dXJlIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIFZlcmlmeUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNTaWduOiBEbGNTaWduLFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBtZXNzYWdlc0xpc3Q6IE1lc3NhZ2VzW10sXG4gICAgaXNPZmZlcmVyOiBib29sZWFuLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGRsY09mZmVyLCBkbGNBY2NlcHQsIGRsY1NpZ24sIGRsY1R4cyB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgICAgX2RsY1NpZ24sXG4gICAgICBfZGxjVHhzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY2V0c0hleCA9IGRsY1R4cy5jZXRzLm1hcCgoY2V0KSA9PiBjZXQuc2VyaWFsaXplKCkudG9TdHJpbmcoJ2hleCcpKTtcblxuICAgIGNvbnN0IGNodW5rID0gMTAwO1xuXG4gICAgY29uc3QgY29udHJhY3RPcmFjbGVQYWlycyA9IHRoaXMuR2V0Q29udHJhY3RPcmFjbGVQYWlycyhcbiAgICAgIGRsY09mZmVyLmNvbnRyYWN0SW5mbyxcbiAgICApO1xuXG4gICAgY29uc3QgaW5kaWNlcyA9IHRoaXMuR2V0SW5kaWNlc0Zyb21QYXlvdXRzKHRoaXMuR2V0UGF5b3V0cyhfZGxjT2ZmZXIpKTtcblxuICAgIGZvciAoY29uc3QgW2luZGV4LCB7IG9yYWNsZUluZm8gfV0gb2YgY29udHJhY3RPcmFjbGVQYWlycy5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IG9yYWNsZUFubm91bmNlbWVudCA9IG9yYWNsZUluZm8uYW5ub3VuY2VtZW50O1xuXG4gICAgICBjb25zdCBzdGFydGluZ0luZGV4ID0gaW5kaWNlc1tpbmRleF0uc3RhcnRpbmdNZXNzYWdlc0luZGV4LFxuICAgICAgICBlbmRpbmdJbmRleCA9IGluZGljZXNbaW5kZXggKyAxXS5zdGFydGluZ01lc3NhZ2VzSW5kZXg7XG5cbiAgICAgIGNvbnN0IG9yYWNsZUV2ZW50TWVzc2FnZXNMaXN0ID0gbWVzc2FnZXNMaXN0LnNsaWNlKFxuICAgICAgICBzdGFydGluZ0luZGV4LFxuICAgICAgICBlbmRpbmdJbmRleCxcbiAgICAgICk7XG4gICAgICBjb25zdCBvcmFjbGVFdmVudENldHNIZXggPSBjZXRzSGV4LnNsaWNlKHN0YXJ0aW5nSW5kZXgsIGVuZGluZ0luZGV4KTtcbiAgICAgIGNvbnN0IG9yYWNsZUV2ZW50U2lncyA9IChpc09mZmVyZXJcbiAgICAgICAgPyBkbGNBY2NlcHQuY2V0U2lnbmF0dXJlcy5zaWdzXG4gICAgICAgIDogZGxjU2lnbi5jZXRTaWduYXR1cmVzLnNpZ3NcbiAgICAgICkuc2xpY2Uoc3RhcnRpbmdJbmRleCwgZW5kaW5nSW5kZXgpO1xuXG4gICAgICBjb25zdCBzaWdzVmFsaWRpdHk6IFByb21pc2U8Ym9vbGVhbj5bXSA9IFtdO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgaiA9IG9yYWNsZUV2ZW50TWVzc2FnZXNMaXN0Lmxlbmd0aDsgaSA8IGo7IGkgKz0gY2h1bmspIHtcbiAgICAgICAgY29uc3QgdGVtcE1lc3NhZ2VzTGlzdCA9IG9yYWNsZUV2ZW50TWVzc2FnZXNMaXN0LnNsaWNlKGksIGkgKyBjaHVuayk7XG4gICAgICAgIGNvbnN0IHRlbXBDZXRzSGV4ID0gb3JhY2xlRXZlbnRDZXRzSGV4LnNsaWNlKGksIGkgKyBjaHVuayk7XG4gICAgICAgIGNvbnN0IHRlbXBTaWdzID0gb3JhY2xlRXZlbnRTaWdzLnNsaWNlKGksIGkgKyBjaHVuayk7XG4gICAgICAgIGNvbnN0IHRlbXBBZGFwdG9yUGFpcnMgPSB0ZW1wU2lncy5tYXAoKHNpZykgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzaWduYXR1cmU6IHNpZy5lbmNyeXB0ZWRTaWcudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgcHJvb2Y6IHNpZy5kbGVxUHJvb2YudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHZlcmlmeUNldEFkYXB0b3JTaWduYXR1cmVzUmVxdWVzdDogVmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZXNSZXF1ZXN0ID0ge1xuICAgICAgICAgIGNldHNIZXg6IHRlbXBDZXRzSGV4LFxuICAgICAgICAgIG1lc3NhZ2VzTGlzdDogdGVtcE1lc3NhZ2VzTGlzdCxcbiAgICAgICAgICBvcmFjbGVQdWJrZXk6IG9yYWNsZUFubm91bmNlbWVudC5vcmFjbGVQdWJrZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIG9yYWNsZVJWYWx1ZXM6IG9yYWNsZUFubm91bmNlbWVudC5vcmFjbGVFdmVudC5vcmFjbGVOb25jZXMubWFwKFxuICAgICAgICAgICAgKG5vbmNlKSA9PiBub25jZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgKSxcbiAgICAgICAgICBhZGFwdG9yUGFpcnM6IHRlbXBBZGFwdG9yUGFpcnMsXG4gICAgICAgICAgbG9jYWxGdW5kUHVia2V5OiBkbGNPZmZlci5mdW5kaW5nUHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICByZW1vdGVGdW5kUHVia2V5OiBkbGNBY2NlcHQuZnVuZGluZ1B1YktleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgZnVuZFR4SWQ6IGRsY1R4cy5mdW5kVHgudHhJZC50b1N0cmluZygpLFxuICAgICAgICAgIGZ1bmRWb3V0OiBkbGNUeHMuZnVuZFR4Vm91dCxcbiAgICAgICAgICBmdW5kSW5wdXRBbW91bnQ6IGRsY1R4cy5mdW5kVHgub3V0cHV0c1tkbGNUeHMuZnVuZFR4Vm91dF0udmFsdWUuc2F0cyxcbiAgICAgICAgICB2ZXJpZnlSZW1vdGU6IGlzT2ZmZXJlcixcbiAgICAgICAgfTtcblxuICAgICAgICBzaWdzVmFsaWRpdHkucHVzaChcbiAgICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLlZlcmlmeUNldEFkYXB0b3JTaWduYXR1cmVzKFxuICAgICAgICAgICAgICB2ZXJpZnlDZXRBZGFwdG9yU2lnbmF0dXJlc1JlcXVlc3QsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnZhbGlkO1xuICAgICAgICAgIH0pKCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGxldCBhcmVTaWdzVmFsaWQgPSAoYXdhaXQgUHJvbWlzZS5hbGwoc2lnc1ZhbGlkaXR5KSkuZXZlcnkoKGIpID0+IGIpO1xuXG4gICAgICBjb25zdCB2ZXJpZnlSZWZ1bmRTaWdSZXF1ZXN0OiBWZXJpZnlSZWZ1bmRUeFNpZ25hdHVyZVJlcXVlc3QgPSB7XG4gICAgICAgIHJlZnVuZFR4SGV4OiBkbGNUeHMucmVmdW5kVHguc2VyaWFsaXplKCkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICBzaWduYXR1cmU6IGlzT2ZmZXJlclxuICAgICAgICAgID8gZGxjQWNjZXB0LnJlZnVuZFNpZ25hdHVyZS50b1N0cmluZygnaGV4JylcbiAgICAgICAgICA6IGRsY1NpZ24ucmVmdW5kU2lnbmF0dXJlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgbG9jYWxGdW5kUHVia2V5OiBkbGNPZmZlci5mdW5kaW5nUHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgcmVtb3RlRnVuZFB1YmtleTogZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICBmdW5kVHhJZDogZGxjVHhzLmZ1bmRUeC50eElkLnRvU3RyaW5nKCksXG4gICAgICAgIGZ1bmRWb3V0OiBkbGNUeHMuZnVuZFR4Vm91dCxcbiAgICAgICAgZnVuZElucHV0QW1vdW50OiBkbGNUeHMuZnVuZFR4Lm91dHB1dHNbZGxjVHhzLmZ1bmRUeFZvdXRdLnZhbHVlLnNhdHMsXG4gICAgICAgIHZlcmlmeVJlbW90ZTogaXNPZmZlcmVyLFxuICAgICAgfTtcblxuICAgICAgYXJlU2lnc1ZhbGlkID1cbiAgICAgICAgYXJlU2lnc1ZhbGlkICYmXG4gICAgICAgIChhd2FpdCB0aGlzLlZlcmlmeVJlZnVuZFR4U2lnbmF0dXJlKHZlcmlmeVJlZnVuZFNpZ1JlcXVlc3QpKS52YWxpZDtcblxuICAgICAgaWYgKCFhcmVTaWdzVmFsaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZXMgcmVjZWl2ZWQnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIENyZWF0ZUZ1bmRpbmdTaWdzKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBpc09mZmVyZXI6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8RnVuZGluZ1NpZ25hdHVyZXNWMD4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjVHhzIH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgICBfZGxjVHhzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZnVuZGluZ0lucHV0cyA9IGlzT2ZmZXJlclxuICAgICAgPyBkbGNPZmZlci5mdW5kaW5nSW5wdXRzXG4gICAgICA6IGRsY0FjY2VwdC5mdW5kaW5nSW5wdXRzO1xuXG4gICAgY29uc3QgaW5wdXRzOiBJbnB1dFtdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBmdW5kaW5nSW5wdXRzLm1hcChhc3luYyAoZnVuZGluZ0lucHV0KSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmZ1bmRpbmdJbnB1dFRvSW5wdXQoZnVuZGluZ0lucHV0KTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBpbnB1dFByaXZLZXlzID0gYXdhaXQgdGhpcy5HZXRQcml2S2V5c0ZvcklucHV0cyhpbnB1dHMpO1xuXG4gICAgY29uc3QgZnVuZFR4U2lncyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgaW5wdXRzLm1hcChhc3luYyAoaW5wdXQsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGZ1bmRUeFNpZ25SZXF1ZXN0OiBHZXRSYXdGdW5kVHhTaWduYXR1cmVSZXF1ZXN0ID0ge1xuICAgICAgICAgIGZ1bmRUeEhleDogZGxjVHhzLmZ1bmRUeC5zZXJpYWxpemUoKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgcHJpdmtleTogaW5wdXRQcml2S2V5c1tpbmRleF0sXG4gICAgICAgICAgcHJldlR4SWQ6IGlucHV0LnR4aWQsXG4gICAgICAgICAgcHJldlZvdXQ6IGlucHV0LnZvdXQsXG4gICAgICAgICAgYW1vdW50OiBpbnB1dC52YWx1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gKGF3YWl0IHRoaXMuR2V0UmF3RnVuZFR4U2lnbmF0dXJlKGZ1bmRUeFNpZ25SZXF1ZXN0KSkuaGV4O1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGNvbnN0IGlucHV0UHViS2V5cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgaW5wdXRQcml2S2V5cy5tYXAoYXN5bmMgKHByaXZrZXkpID0+IHtcbiAgICAgICAgY29uc3QgcmVxUHJpdktleSA9IHtcbiAgICAgICAgICBwcml2a2V5LFxuICAgICAgICAgIGlzQ29tcHJlc3NlZDogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdHZXRQdWJrZXlGcm9tUHJpdmtleScpKHJlcVByaXZLZXkpKVxuICAgICAgICAgIC5wdWJrZXk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgY29uc3Qgd2l0bmVzc0VsZW1lbnRzOiBTY3JpcHRXaXRuZXNzVjBbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmdW5kVHhTaWdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzaWdXaXRuZXNzID0gbmV3IFNjcmlwdFdpdG5lc3NWMCgpO1xuICAgICAgc2lnV2l0bmVzcy53aXRuZXNzID0gQnVmZmVyLmZyb20oZnVuZFR4U2lnc1tpXSwgJ2hleCcpO1xuICAgICAgY29uc3QgcHViS2V5V2l0bmVzcyA9IG5ldyBTY3JpcHRXaXRuZXNzVjAoKTtcbiAgICAgIHB1YktleVdpdG5lc3Mud2l0bmVzcyA9IEJ1ZmZlci5mcm9tKGlucHV0UHViS2V5c1tpXSwgJ2hleCcpO1xuICAgICAgd2l0bmVzc0VsZW1lbnRzLnB1c2goW3NpZ1dpdG5lc3MsIHB1YktleVdpdG5lc3NdKTtcbiAgICB9XG5cbiAgICBjb25zdCBmdW5kaW5nU2lnbmF0dXJlcyA9IG5ldyBGdW5kaW5nU2lnbmF0dXJlc1YwKCk7XG4gICAgZnVuZGluZ1NpZ25hdHVyZXMud2l0bmVzc0VsZW1lbnRzID0gd2l0bmVzc0VsZW1lbnRzO1xuXG4gICAgcmV0dXJuIGZ1bmRpbmdTaWduYXR1cmVzO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBWZXJpZnlGdW5kaW5nU2lncyhcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgICBfZGxjU2lnbjogRGxjU2lnbixcbiAgICBfZGxjVHhzOiBEbGNUcmFuc2FjdGlvbnMsXG4gICAgaXNPZmZlcmVyOiBib29sZWFuLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGRsY09mZmVyLCBkbGNBY2NlcHQsIGRsY1NpZ24sIGRsY1R4cyB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgICAgX2RsY1NpZ24sXG4gICAgICBfZGxjVHhzLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2lnc1ZhbGlkaXR5OiBQcm9taXNlPGJvb2xlYW4+W10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRsY1NpZ24uZnVuZGluZ1NpZ25hdHVyZXMud2l0bmVzc0VsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB3aXRuZXNzRWxlbWVudCA9IGRsY1NpZ24uZnVuZGluZ1NpZ25hdHVyZXMud2l0bmVzc0VsZW1lbnRzW2ldO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gd2l0bmVzc0VsZW1lbnRbMF0ud2l0bmVzcy50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBwdWJrZXkgPSB3aXRuZXNzRWxlbWVudFsxXS53aXRuZXNzLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgY29uc3QgZnVuZGluZ0lucHV0ID0gaXNPZmZlcmVyXG4gICAgICAgID8gKGRsY0FjY2VwdC5mdW5kaW5nSW5wdXRzW2ldIGFzIEZ1bmRpbmdJbnB1dFYwKVxuICAgICAgICA6IChkbGNPZmZlci5mdW5kaW5nSW5wdXRzW2ldIGFzIEZ1bmRpbmdJbnB1dFYwKTtcblxuICAgICAgY29uc3QgdmVyaWZ5RnVuZFNpZ1JlcXVlc3Q6IFZlcmlmeUZ1bmRUeFNpZ25hdHVyZVJlcXVlc3QgPSB7XG4gICAgICAgIGZ1bmRUeEhleDogZGxjVHhzLmZ1bmRUeC5zZXJpYWxpemUoKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHNpZ25hdHVyZSxcbiAgICAgICAgcHVia2V5LFxuICAgICAgICBwcmV2VHhJZDogZnVuZGluZ0lucHV0LnByZXZUeC50eElkLnRvU3RyaW5nKCksXG4gICAgICAgIHByZXZWb3V0OiBmdW5kaW5nSW5wdXQucHJldlR4Vm91dCxcbiAgICAgICAgZnVuZElucHV0QW1vdW50OlxuICAgICAgICAgIGZ1bmRpbmdJbnB1dC5wcmV2VHgub3V0cHV0c1tmdW5kaW5nSW5wdXQucHJldlR4Vm91dF0udmFsdWUuc2F0cyxcbiAgICAgIH07XG5cbiAgICAgIHNpZ3NWYWxpZGl0eS5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5WZXJpZnlGdW5kVHhTaWduYXR1cmUoXG4gICAgICAgICAgICB2ZXJpZnlGdW5kU2lnUmVxdWVzdCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiByZXNwb25zZS52YWxpZDtcbiAgICAgICAgfSkoKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgYXJlU2lnc1ZhbGlkID0gKGF3YWl0IFByb21pc2UuYWxsKHNpZ3NWYWxpZGl0eSkpLmV2ZXJ5KChiKSA9PiBiKTtcblxuICAgIGlmICghYXJlU2lnc1ZhbGlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlcyByZWNlaXZlZCcpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgQ3JlYXRlRnVuZGluZ1R4KFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNTaWduOiBEbGNTaWduLFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBmdW5kaW5nU2lnbmF0dXJlczogRnVuZGluZ1NpZ25hdHVyZXNWMCxcbiAgKTogUHJvbWlzZTxUeD4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjU2lnbiwgZGxjVHhzIH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgICBfZGxjU2lnbixcbiAgICAgIF9kbGNUeHMsXG4gICAgfSk7XG5cbiAgICBjb25zdCB3aXRuZXNzRWxlbWVudHMgPSBbXG4gICAgICAuLi5kbGNTaWduLmZ1bmRpbmdTaWduYXR1cmVzLndpdG5lc3NFbGVtZW50cyxcbiAgICAgIC4uLmZ1bmRpbmdTaWduYXR1cmVzLndpdG5lc3NFbGVtZW50cyxcbiAgICBdO1xuICAgIGNvbnN0IGZ1bmRpbmdJbnB1dHMgPSBbXG4gICAgICAuLi5kbGNPZmZlci5mdW5kaW5nSW5wdXRzLFxuICAgICAgLi4uZGxjQWNjZXB0LmZ1bmRpbmdJbnB1dHMsXG4gICAgXTtcblxuICAgIGxldCBmdW5kVHhIZXggPSBkbGNUeHMuZnVuZFR4LnNlcmlhbGl6ZSgpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgIGF3YWl0IGFzeW5jRm9yRWFjaChcbiAgICAgIHdpdG5lc3NFbGVtZW50cyxcbiAgICAgIGFzeW5jICh3aXRuZXNzRWxlbWVudDogU2NyaXB0V2l0bmVzc1YwLCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gd2l0bmVzc0VsZW1lbnRbMF0ud2l0bmVzcy50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHB1YmtleSA9IHdpdG5lc3NFbGVtZW50WzFdLndpdG5lc3MudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGZ1bmRpbmdJbnB1dCA9IGZ1bmRpbmdJbnB1dHNbaV0gYXMgRnVuZGluZ0lucHV0VjA7XG5cbiAgICAgICAgY29uc3QgYWRkU2lnblJlcXVlc3Q6IEFkZFNpZ25hdHVyZVRvRnVuZFRyYW5zYWN0aW9uUmVxdWVzdCA9IHtcbiAgICAgICAgICBmdW5kVHhIZXgsXG4gICAgICAgICAgc2lnbmF0dXJlLFxuICAgICAgICAgIHByZXZUeElkOiBmdW5kaW5nSW5wdXQucHJldlR4LnR4SWQudG9TdHJpbmcoKSxcbiAgICAgICAgICBwcmV2Vm91dDogZnVuZGluZ0lucHV0LnByZXZUeFZvdXQsXG4gICAgICAgICAgcHVia2V5LFxuICAgICAgICB9O1xuICAgICAgICBmdW5kVHhIZXggPSAoYXdhaXQgdGhpcy5BZGRTaWduYXR1cmVUb0Z1bmRUcmFuc2FjdGlvbihhZGRTaWduUmVxdWVzdCkpXG4gICAgICAgICAgLmhleDtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIGNvbnN0IGZ1bmRUeCA9IFR4LmRlY29kZShTdHJlYW1SZWFkZXIuZnJvbUhleChmdW5kVHhIZXgpKTtcblxuICAgIHJldHVybiBmdW5kVHg7XG4gIH1cblxuICBhc3luYyBGaW5kT3V0Y29tZUluZGV4RnJvbVBvbHlub21pYWxQYXlvdXRDdXJ2ZVBpZWNlKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgY29udHJhY3REZXNjcmlwdG9yOiBDb250cmFjdERlc2NyaXB0b3JWMSxcbiAgICBjb250cmFjdE9yYWNsZVBhaXJJbmRleDogbnVtYmVyLFxuICAgIHBvbHlub21pYWxQYXlvdXRDdXJ2ZVBpZWNlOiBQb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZSxcbiAgICBvcmFjbGVBdHRlc3RhdGlvbjogT3JhY2xlQXR0ZXN0YXRpb25WMCxcbiAgICBvdXRjb21lOiBiaWdpbnQsXG4gICk6IFByb21pc2U8RmluZE91dGNvbWVSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIgfSA9IGNoZWNrVHlwZXMoeyBfZGxjT2ZmZXIgfSk7XG5cbiAgICBjb25zdCBwb2x5bm9taWFsQ3VydmUgPSBQb2x5bm9taWFsUGF5b3V0Q3VydmUuZnJvbVBheW91dEN1cnZlUGllY2UoXG4gICAgICBwb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZSxcbiAgICApO1xuXG4gICAgY29uc3QgY2xhbXBCTiA9ICh2YWw6IEJpZ051bWJlcikgPT5cbiAgICAgIEJpZ051bWJlci5tYXgoXG4gICAgICAgIDAsXG4gICAgICAgIEJpZ051bWJlci5taW4odmFsLCBkbGNPZmZlci5jb250cmFjdEluZm8udG90YWxDb2xsYXRlcmFsLnRvU3RyaW5nKCkpLFxuICAgICAgKTtcblxuICAgIGNvbnN0IHBheW91dCA9IGNsYW1wQk4ocG9seW5vbWlhbEN1cnZlLmdldFBheW91dChvdXRjb21lKSk7XG5cbiAgICBjb25zdCBwYXlvdXRSZXNwb25zZXMgPSB0aGlzLkdldFBheW91dHMoZGxjT2ZmZXIpO1xuICAgIGNvbnN0IHBheW91dEluZGV4T2Zmc2V0ID0gdGhpcy5HZXRJbmRpY2VzRnJvbVBheW91dHMocGF5b3V0UmVzcG9uc2VzKVtcbiAgICAgIGNvbnRyYWN0T3JhY2xlUGFpckluZGV4XG4gICAgXS5zdGFydGluZ01lc3NhZ2VzSW5kZXg7XG5cbiAgICBjb25zdCB7IHBheW91dEdyb3VwcyB9ID0gcGF5b3V0UmVzcG9uc2VzW2NvbnRyYWN0T3JhY2xlUGFpckluZGV4XTtcblxuICAgIGNvbnN0IGludGVydmFsc1NvcnRlZCA9IFtcbiAgICAgIC4uLmNvbnRyYWN0RGVzY3JpcHRvci5yb3VuZGluZ0ludGVydmFscy5pbnRlcnZhbHMsXG4gICAgXS5zb3J0KChhLCBiKSA9PiBOdW1iZXIoYi5iZWdpbkludGVydmFsKSAtIE51bWJlcihhLmJlZ2luSW50ZXJ2YWwpKTtcblxuICAgIGNvbnN0IGludGVydmFsID0gaW50ZXJ2YWxzU29ydGVkLmZpbmQoXG4gICAgICAoaW50ZXJ2YWwpID0+IE51bWJlcihvdXRjb21lKSA+PSBOdW1iZXIoaW50ZXJ2YWwuYmVnaW5JbnRlcnZhbCksXG4gICAgKTtcblxuICAgIGNvbnN0IHJvdW5kZWRQYXlvdXQgPSBCaWdJbnQoXG4gICAgICBjbGFtcEJOKFxuICAgICAgICBuZXcgQmlnTnVtYmVyKHJvdW5kUGF5b3V0KHBheW91dCwgaW50ZXJ2YWwucm91bmRpbmdNb2QpLnRvU3RyaW5nKCkpLFxuICAgICAgKS50b1N0cmluZygpLFxuICAgICk7XG5cbiAgICBjb25zdCBvdXRjb21lc0Zvcm1hdHRlZCA9IG9yYWNsZUF0dGVzdGF0aW9uLm91dGNvbWVzLm1hcCgob3V0Y29tZSkgPT5cbiAgICAgIHBhcnNlSW50KG91dGNvbWUpLFxuICAgICk7XG5cbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGxldCBncm91cEluZGV4ID0gLTE7XG4gICAgbGV0IGdyb3VwTGVuZ3RoID0gMDtcblxuICAgIGZvciAoY29uc3QgcGF5b3V0R3JvdXAgb2YgcGF5b3V0R3JvdXBzKSB7XG4gICAgICBpZiAocGF5b3V0R3JvdXAucGF5b3V0ID09PSByb3VuZGVkUGF5b3V0KSB7XG4gICAgICAgIGdyb3VwSW5kZXggPSBwYXlvdXRHcm91cC5ncm91cHMuZmluZEluZGV4KChncm91cCkgPT4ge1xuICAgICAgICAgIHJldHVybiBncm91cC5ldmVyeSgobXNnLCBpKSA9PiBtc2cgPT09IG91dGNvbWVzRm9ybWF0dGVkW2ldKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChncm91cEluZGV4ID09PSAtMSlcbiAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICdGYWlsZWQgdG8gRmluZCBPdXRjb21lSW5kZXggRnJvbSBQb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZS4gXFxcblBheW91dCBHcm91cCBmb3VuZCBidXQgaW5jb3JyZWN0IGdyb3VwIGluZGV4JyxcbiAgICAgICAgICApO1xuICAgICAgICBpbmRleCArPSBncm91cEluZGV4O1xuICAgICAgICBncm91cExlbmd0aCA9IHBheW91dEdyb3VwLmdyb3Vwc1tncm91cEluZGV4XS5sZW5ndGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5kZXggKz0gcGF5b3V0R3JvdXAuZ3JvdXBzLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBJbmRleCA9PT0gLTEpXG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgJ0ZhaWxlZCB0byBGaW5kIE91dGNvbWVJbmRleCBGcm9tIFBvbHlub21pYWxQYXlvdXRDdXJ2ZVBpZWNlLiBcXFxuUGF5b3V0IEdyb3VwIG5vdCBmb3VuZCcsXG4gICAgICApO1xuXG4gICAgcmV0dXJuIHsgaW5kZXg6IHBheW91dEluZGV4T2Zmc2V0ICsgaW5kZXgsIGdyb3VwTGVuZ3RoIH07XG4gIH1cblxuICBhc3luYyBGaW5kT3V0Y29tZUluZGV4RnJvbUh5cGVyYm9sYVBheW91dEN1cnZlUGllY2UoXG4gICAgX2RsY09mZmVyOiBEbGNPZmZlcixcbiAgICBjb250cmFjdERlc2NyaXB0b3I6IENvbnRyYWN0RGVzY3JpcHRvclYxLFxuICAgIGNvbnRyYWN0T3JhY2xlUGFpckluZGV4OiBudW1iZXIsXG4gICAgaHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZTogSHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZSxcbiAgICBvcmFjbGVBdHRlc3RhdGlvbjogT3JhY2xlQXR0ZXN0YXRpb25WMCxcbiAgICBvdXRjb21lOiBiaWdpbnQsXG4gICk6IFByb21pc2U8RmluZE91dGNvbWVSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIgfSA9IGNoZWNrVHlwZXMoeyBfZGxjT2ZmZXIgfSk7XG5cbiAgICBjb25zdCBoeXBlcmJvbGFDdXJ2ZSA9IEh5cGVyYm9sYVBheW91dEN1cnZlLmZyb21QYXlvdXRDdXJ2ZVBpZWNlKFxuICAgICAgaHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZSxcbiAgICApO1xuXG4gICAgY29uc3QgY2xhbXBCTiA9ICh2YWw6IEJpZ051bWJlcikgPT5cbiAgICAgIEJpZ051bWJlci5tYXgoXG4gICAgICAgIDAsXG4gICAgICAgIEJpZ051bWJlci5taW4odmFsLCBkbGNPZmZlci5jb250cmFjdEluZm8udG90YWxDb2xsYXRlcmFsLnRvU3RyaW5nKCkpLFxuICAgICAgKTtcblxuICAgIGNvbnN0IHBheW91dCA9IGNsYW1wQk4oaHlwZXJib2xhQ3VydmUuZ2V0UGF5b3V0KG91dGNvbWUpKTtcblxuICAgIGNvbnN0IHBheW91dFJlc3BvbnNlcyA9IHRoaXMuR2V0UGF5b3V0cyhkbGNPZmZlcik7XG4gICAgY29uc3QgcGF5b3V0SW5kZXhPZmZzZXQgPSB0aGlzLkdldEluZGljZXNGcm9tUGF5b3V0cyhwYXlvdXRSZXNwb25zZXMpW1xuICAgICAgY29udHJhY3RPcmFjbGVQYWlySW5kZXhcbiAgICBdLnN0YXJ0aW5nTWVzc2FnZXNJbmRleDtcblxuICAgIGNvbnN0IHsgcGF5b3V0R3JvdXBzIH0gPSBwYXlvdXRSZXNwb25zZXNbY29udHJhY3RPcmFjbGVQYWlySW5kZXhdO1xuXG4gICAgY29uc3QgaW50ZXJ2YWxzU29ydGVkID0gW1xuICAgICAgLi4uY29udHJhY3REZXNjcmlwdG9yLnJvdW5kaW5nSW50ZXJ2YWxzLmludGVydmFscyxcbiAgICBdLnNvcnQoKGEsIGIpID0+IE51bWJlcihiLmJlZ2luSW50ZXJ2YWwpIC0gTnVtYmVyKGEuYmVnaW5JbnRlcnZhbCkpO1xuXG4gICAgY29uc3QgaW50ZXJ2YWwgPSBpbnRlcnZhbHNTb3J0ZWQuZmluZChcbiAgICAgIChpbnRlcnZhbCkgPT4gTnVtYmVyKG91dGNvbWUpID49IE51bWJlcihpbnRlcnZhbC5iZWdpbkludGVydmFsKSxcbiAgICApO1xuXG4gICAgY29uc3Qgcm91bmRlZFBheW91dCA9IEJpZ0ludChcbiAgICAgIGNsYW1wQk4oXG4gICAgICAgIG5ldyBCaWdOdW1iZXIocm91bmRQYXlvdXQocGF5b3V0LCBpbnRlcnZhbC5yb3VuZGluZ01vZCkudG9TdHJpbmcoKSksXG4gICAgICApLnRvU3RyaW5nKCksXG4gICAgKTtcblxuICAgIGNvbnN0IG91dGNvbWVzRm9ybWF0dGVkID0gb3JhY2xlQXR0ZXN0YXRpb24ub3V0Y29tZXMubWFwKChvdXRjb21lKSA9PlxuICAgICAgcGFyc2VJbnQob3V0Y29tZSksXG4gICAgKTtcblxuICAgIGxldCBpbmRleCA9IDA7XG4gICAgbGV0IGdyb3VwSW5kZXggPSAtMTtcbiAgICBsZXQgZ3JvdXBMZW5ndGggPSAwO1xuXG4gICAgZm9yIChjb25zdCBwYXlvdXRHcm91cCBvZiBwYXlvdXRHcm91cHMpIHtcbiAgICAgIGlmIChwYXlvdXRHcm91cC5wYXlvdXQgPT09IHJvdW5kZWRQYXlvdXQpIHtcbiAgICAgICAgZ3JvdXBJbmRleCA9IHBheW91dEdyb3VwLmdyb3Vwcy5maW5kSW5kZXgoKGdyb3VwKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGdyb3VwLmV2ZXJ5KChtc2csIGkpID0+IG1zZyA9PT0gb3V0Y29tZXNGb3JtYXR0ZWRbaV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGdyb3VwSW5kZXggPT09IC0xKVxuICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgJ0ZhaWxlZCB0byBGaW5kIE91dGNvbWVJbmRleCBGcm9tIEh5cGVyYm9sYVBheW91dEN1cnZlUGllY2UuIFxcXG5QYXlvdXQgR3JvdXAgZm91bmQgYnV0IGluY29ycmVjdCBncm91cCBpbmRleCcsXG4gICAgICAgICAgKTtcbiAgICAgICAgaW5kZXggKz0gZ3JvdXBJbmRleDtcbiAgICAgICAgZ3JvdXBMZW5ndGggPSBwYXlvdXRHcm91cC5ncm91cHNbZ3JvdXBJbmRleF0ubGVuZ3RoO1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGV4ICs9IHBheW91dEdyb3VwLmdyb3Vwcy5sZW5ndGg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwSW5kZXggPT09IC0xKVxuICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICdGYWlsZWQgdG8gRmluZCBPdXRjb21lSW5kZXggRnJvbSBIeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlLiBcXFxuUGF5b3V0IEdyb3VwIG5vdCBmb3VuZCcsXG4gICAgICApO1xuXG4gICAgcmV0dXJuIHsgaW5kZXg6IHBheW91dEluZGV4T2Zmc2V0ICsgaW5kZXgsIGdyb3VwTGVuZ3RoIH07XG4gIH1cblxuICBhc3luYyBGaW5kT3V0Y29tZUluZGV4KFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgb3JhY2xlQXR0ZXN0YXRpb246IE9yYWNsZUF0dGVzdGF0aW9uVjAsXG4gICk6IFByb21pc2U8RmluZE91dGNvbWVSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIgfSA9IGNoZWNrVHlwZXMoeyBfZGxjT2ZmZXIgfSk7XG5cbiAgICBjb25zdCBjb250cmFjdE9yYWNsZVBhaXJzID0gdGhpcy5HZXRDb250cmFjdE9yYWNsZVBhaXJzKFxuICAgICAgZGxjT2ZmZXIuY29udHJhY3RJbmZvLFxuICAgICk7XG5cbiAgICBjb25zdCBjb250cmFjdE9yYWNsZVBhaXJJbmRleCA9IGNvbnRyYWN0T3JhY2xlUGFpcnMuZmluZEluZGV4KFxuICAgICAgKHsgb3JhY2xlSW5mbyB9KSA9PlxuICAgICAgICBvcmFjbGVJbmZvLmFubm91bmNlbWVudC5vcmFjbGVFdmVudC5ldmVudElkID09PVxuICAgICAgICBvcmFjbGVBdHRlc3RhdGlvbi5ldmVudElkLFxuICAgICk7XG5cbiAgICBhc3NlcnQoXG4gICAgICBjb250cmFjdE9yYWNsZVBhaXJJbmRleCAhPT0gLTEsXG4gICAgICAnT3JhY2xlQXR0ZXN0YXRpb24gbXVzdCBiZSBmb3IgYW4gZXhpc3RpbmcgT3JhY2xlRXZlbnQnLFxuICAgICk7XG5cbiAgICBjb25zdCBjb250cmFjdE9yYWNsZVBhaXIgPSBjb250cmFjdE9yYWNsZVBhaXJzW2NvbnRyYWN0T3JhY2xlUGFpckluZGV4XTtcblxuICAgIGNvbnN0IHtcbiAgICAgIGNvbnRyYWN0RGVzY3JpcHRvcjogX2NvbnRyYWN0RGVzY3JpcHRvcixcbiAgICAgIG9yYWNsZUluZm8sXG4gICAgfSA9IGNvbnRyYWN0T3JhY2xlUGFpcjtcblxuICAgIGFzc2VydChcbiAgICAgIF9jb250cmFjdERlc2NyaXB0b3IudHlwZSA9PT0gTWVzc2FnZVR5cGUuQ29udHJhY3REZXNjcmlwdG9yVjEsXG4gICAgICAnQ29udHJhY3REZXNjcmlwdG9yIG11c3QgYmUgVjEnLFxuICAgICk7XG5cbiAgICBjb25zdCBjb250cmFjdERlc2NyaXB0b3IgPSBfY29udHJhY3REZXNjcmlwdG9yIGFzIENvbnRyYWN0RGVzY3JpcHRvclYxO1xuICAgIGNvbnN0IF9wYXlvdXRGdW5jdGlvbiA9IGNvbnRyYWN0RGVzY3JpcHRvci5wYXlvdXRGdW5jdGlvbjtcblxuICAgIGFzc2VydChcbiAgICAgIF9wYXlvdXRGdW5jdGlvbi50eXBlID09PSBNZXNzYWdlVHlwZS5QYXlvdXRGdW5jdGlvblYwLFxuICAgICAgJ1BheW91dEZ1bmN0aW9uIG11c3QgYmUgVjAnLFxuICAgICk7XG5cbiAgICBjb25zdCBldmVudERlc2NyaXB0b3IgPSBvcmFjbGVJbmZvLmFubm91bmNlbWVudC5vcmFjbGVFdmVudFxuICAgICAgLmV2ZW50RGVzY3JpcHRvciBhcyBEaWdpdERlY29tcG9zaXRpb25FdmVudERlc2NyaXB0b3JWMDtcbiAgICBjb25zdCBwYXlvdXRGdW5jdGlvbiA9IF9wYXlvdXRGdW5jdGlvbiBhcyBQYXlvdXRGdW5jdGlvblYwO1xuXG4gICAgY29uc3QgYmFzZSA9IGV2ZW50RGVzY3JpcHRvci5iYXNlO1xuXG4gICAgY29uc3Qgb3V0Y29tZTogbnVtYmVyID0gWy4uLm9yYWNsZUF0dGVzdGF0aW9uLm91dGNvbWVzXVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLnJlZHVjZSgoYWNjLCB2YWwsIGkpID0+IGFjYyArIE51bWJlcih2YWwpICogYmFzZSAqKiBpLCAwKTtcblxuICAgIGNvbnN0IHBpZWNlc1NvcnRlZCA9IHBheW91dEZ1bmN0aW9uLnBpZWNlcy5zb3J0KFxuICAgICAgKGEsIGIpID0+IE51bWJlcihhLmVuZHBvaW50KSAtIE51bWJlcihiLmVuZHBvaW50KSxcbiAgICApO1xuXG4gICAgY29uc3QgcGllY2UgPSBwaWVjZXNTb3J0ZWQuZmluZCgocGllY2UpID0+IG91dGNvbWUgPCBwaWVjZS5lbmRwb2ludCk7XG5cbiAgICBzd2l0Y2ggKHBpZWNlLnBheW91dEN1cnZlUGllY2UudHlwZSkge1xuICAgICAgY2FzZSBNZXNzYWdlVHlwZS5Qb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZTpcbiAgICAgICAgcmV0dXJuIHRoaXMuRmluZE91dGNvbWVJbmRleEZyb21Qb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZShcbiAgICAgICAgICBkbGNPZmZlcixcbiAgICAgICAgICBjb250cmFjdERlc2NyaXB0b3IsXG4gICAgICAgICAgY29udHJhY3RPcmFjbGVQYWlySW5kZXgsXG4gICAgICAgICAgcGllY2UucGF5b3V0Q3VydmVQaWVjZSBhcyBQb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZSxcbiAgICAgICAgICBvcmFjbGVBdHRlc3RhdGlvbixcbiAgICAgICAgICBCaWdJbnQob3V0Y29tZSksXG4gICAgICAgICk7XG4gICAgICBjYXNlIE1lc3NhZ2VUeXBlLkh5cGVyYm9sYVBheW91dEN1cnZlUGllY2U6XG4gICAgICAgIHJldHVybiB0aGlzLkZpbmRPdXRjb21lSW5kZXhGcm9tSHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZShcbiAgICAgICAgICBkbGNPZmZlcixcbiAgICAgICAgICBjb250cmFjdERlc2NyaXB0b3IsXG4gICAgICAgICAgY29udHJhY3RPcmFjbGVQYWlySW5kZXgsXG4gICAgICAgICAgcGllY2UucGF5b3V0Q3VydmVQaWVjZSBhcyBIeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlLFxuICAgICAgICAgIG9yYWNsZUF0dGVzdGF0aW9uLFxuICAgICAgICAgIEJpZ0ludChvdXRjb21lKSxcbiAgICAgICAgKTtcbiAgICAgIGNhc2UgTWVzc2FnZVR5cGUuT2xkSHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZTpcbiAgICAgICAgcmV0dXJuIHRoaXMuRmluZE91dGNvbWVJbmRleEZyb21IeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlKFxuICAgICAgICAgIGRsY09mZmVyLFxuICAgICAgICAgIGNvbnRyYWN0RGVzY3JpcHRvcixcbiAgICAgICAgICBjb250cmFjdE9yYWNsZVBhaXJJbmRleCxcbiAgICAgICAgICBwaWVjZS5wYXlvdXRDdXJ2ZVBpZWNlIGFzIEh5cGVyYm9sYVBheW91dEN1cnZlUGllY2UsXG4gICAgICAgICAgb3JhY2xlQXR0ZXN0YXRpb24sXG4gICAgICAgICAgQmlnSW50KG91dGNvbWUpLFxuICAgICAgICApO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgRXJyb3IoJ011c3QgYmUgSHlwZXJib2xhIG9yIFBvbHlub21pYWwgY3VydmUgcGllY2UnKTtcbiAgICB9XG4gIH1cblxuICBWYWxpZGF0ZUV2ZW50KFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgb3JhY2xlQXR0ZXN0YXRpb246IE9yYWNsZUF0dGVzdGF0aW9uVjAsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIgfSA9IGNoZWNrVHlwZXMoe1xuICAgICAgX2RsY09mZmVyLFxuICAgIH0pO1xuXG4gICAgc3dpdGNoIChkbGNPZmZlci5jb250cmFjdEluZm8udHlwZSkge1xuICAgICAgY2FzZSBNZXNzYWdlVHlwZS5Db250cmFjdEluZm9WMDoge1xuICAgICAgICBjb25zdCBjb250cmFjdEluZm8gPSBkbGNPZmZlci5jb250cmFjdEluZm8gYXMgQ29udHJhY3RJbmZvVjA7XG4gICAgICAgIHN3aXRjaCAoY29udHJhY3RJbmZvLmNvbnRyYWN0RGVzY3JpcHRvci50eXBlKSB7XG4gICAgICAgICAgY2FzZSBNZXNzYWdlVHlwZS5Db250cmFjdERlc2NyaXB0b3JWMDpcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdDb250cmFjdERlc2NyaXB0b3JWMCBub3QgeWV0IHN1cHBvcnRlZCcpO1xuICAgICAgICAgIGNhc2UgTWVzc2FnZVR5cGUuQ29udHJhY3REZXNjcmlwdG9yVjE6IHtcbiAgICAgICAgICAgIGNvbnN0IG9yYWNsZUluZm8gPSBjb250cmFjdEluZm8ub3JhY2xlSW5mbztcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgb3JhY2xlSW5mby5hbm5vdW5jZW1lbnQub3JhY2xlRXZlbnQuZXZlbnRJZCAhPT1cbiAgICAgICAgICAgICAgb3JhY2xlQXR0ZXN0YXRpb24uZXZlbnRJZFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB0aHJvdyBFcnJvcignSW5jb3JyZWN0IE9yYWNsZSBBdHRlc3RhdGlvbi4gRXZlbnQgSWQgbXVzdCBtYXRjaC4nKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0NvbnJhY3REZXNjcmlwdG9yIG11c3QgYmUgVjAgb3IgVjEnKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgTWVzc2FnZVR5cGUuQ29udHJhY3RJbmZvVjE6IHtcbiAgICAgICAgY29uc3QgY29udHJhY3RJbmZvID0gZGxjT2ZmZXIuY29udHJhY3RJbmZvIGFzIENvbnRyYWN0SW5mb1YxO1xuICAgICAgICBjb25zdCBhdHRlc3RlZE9yYWNsZUV2ZW50ID0gY29udHJhY3RJbmZvLmNvbnRyYWN0T3JhY2xlUGFpcnMuZmluZChcbiAgICAgICAgICAoeyBvcmFjbGVJbmZvIH0pID0+XG4gICAgICAgICAgICBvcmFjbGVJbmZvLmFubm91bmNlbWVudC5vcmFjbGVFdmVudC5ldmVudElkID09PVxuICAgICAgICAgICAgb3JhY2xlQXR0ZXN0YXRpb24uZXZlbnRJZCxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAoIWF0dGVzdGVkT3JhY2xlRXZlbnQpXG4gICAgICAgICAgdGhyb3cgRXJyb3IoJ09yYWNsZSBldmVudCBvZiBhdHRlc3RhdGlvbiBub3QgZm91bmQuJyk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBFcnJvcignQ29udHJhY3RJbmZvIG11c3QgYmUgVjAgb3IgVjEnKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBGaW5kQW5kU2lnbkNldChcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgICBfZGxjU2lnbjogRGxjU2lnbixcbiAgICBfZGxjVHhzOiBEbGNUcmFuc2FjdGlvbnMsXG4gICAgb3JhY2xlQXR0ZXN0YXRpb246IE9yYWNsZUF0dGVzdGF0aW9uVjAsXG4gICAgaXNPZmZlcmVyPzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTxUeD4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjU2lnbiwgZGxjVHhzIH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgICBfZGxjU2lnbixcbiAgICAgIF9kbGNUeHMsXG4gICAgfSk7XG5cbiAgICBpZiAoaXNPZmZlcmVyID09PSB1bmRlZmluZWQpXG4gICAgICBpc09mZmVyZXIgPSBhd2FpdCB0aGlzLmlzT2ZmZXJlcihkbGNPZmZlciwgZGxjQWNjZXB0KTtcblxuICAgIGNvbnN0IHsgaW5kZXg6IG91dGNvbWVJbmRleCwgZ3JvdXBMZW5ndGggfSA9IGF3YWl0IHRoaXMuRmluZE91dGNvbWVJbmRleChcbiAgICAgIGRsY09mZmVyLFxuICAgICAgb3JhY2xlQXR0ZXN0YXRpb24sXG4gICAgKTtcblxuICAgIGNvbnN0IGZ1bmRQcml2YXRlS2V5ID0gYXdhaXQgdGhpcy5HZXRGdW5kUHJpdmF0ZUtleShcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgaXNPZmZlcmVyLFxuICAgICk7XG5cbiAgICBjb25zdCBzbGljZUluZGV4ID0gLShvcmFjbGVBdHRlc3RhdGlvbi5zaWduYXR1cmVzLmxlbmd0aCAtIGdyb3VwTGVuZ3RoKTtcblxuICAgIGNvbnN0IG9yYWNsZVNpZ25hdHVyZXMgPVxuICAgICAgc2xpY2VJbmRleCA9PT0gMFxuICAgICAgICA/IG9yYWNsZUF0dGVzdGF0aW9uLnNpZ25hdHVyZXNcbiAgICAgICAgOiBvcmFjbGVBdHRlc3RhdGlvbi5zaWduYXR1cmVzLnNsaWNlKDAsIHNsaWNlSW5kZXgpO1xuXG4gICAgY29uc3Qgc2lnbkNldFJlcXVlc3Q6IFNpZ25DZXRSZXF1ZXN0ID0ge1xuICAgICAgY2V0SGV4OiBkbGNUeHMuY2V0c1tvdXRjb21lSW5kZXhdLnNlcmlhbGl6ZSgpLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIGZ1bmRQcml2a2V5OiBmdW5kUHJpdmF0ZUtleSxcbiAgICAgIGZ1bmRUeElkOiBkbGNUeHMuZnVuZFR4LnR4SWQudG9TdHJpbmcoKSxcbiAgICAgIGZ1bmRWb3V0OiBkbGNUeHMuZnVuZFR4Vm91dCxcbiAgICAgIGxvY2FsRnVuZFB1YmtleTogZGxjT2ZmZXIuZnVuZGluZ1B1YktleS50b1N0cmluZygnaGV4JyksXG4gICAgICByZW1vdGVGdW5kUHVia2V5OiBkbGNBY2NlcHQuZnVuZGluZ1B1YktleS50b1N0cmluZygnaGV4JyksXG4gICAgICBvcmFjbGVTaWduYXR1cmVzOiBvcmFjbGVTaWduYXR1cmVzLm1hcCgoc2lnKSA9PiBzaWcudG9TdHJpbmcoJ2hleCcpKSxcbiAgICAgIGZ1bmRJbnB1dEFtb3VudDogZGxjVHhzLmZ1bmRUeC5vdXRwdXRzW2RsY1R4cy5mdW5kVHhWb3V0XS52YWx1ZS5zYXRzLFxuICAgICAgYWRhcHRvclNpZ25hdHVyZTogaXNPZmZlcmVyXG4gICAgICAgID8gZGxjQWNjZXB0LmNldFNpZ25hdHVyZXMuc2lnc1tvdXRjb21lSW5kZXhdLmVuY3J5cHRlZFNpZy50b1N0cmluZyhcbiAgICAgICAgICAgICdoZXgnLFxuICAgICAgICAgIClcbiAgICAgICAgOiBkbGNTaWduLmNldFNpZ25hdHVyZXMuc2lnc1tvdXRjb21lSW5kZXhdLmVuY3J5cHRlZFNpZy50b1N0cmluZygnaGV4JyksXG4gICAgfTtcblxuICAgIGNvbnN0IGZpbmFsQ2V0ID0gKGF3YWl0IHRoaXMuU2lnbkNldChzaWduQ2V0UmVxdWVzdCkpLmhleDtcblxuICAgIHJldHVybiBUeC5kZWNvZGUoU3RyZWFtUmVhZGVyLmZyb21IZXgoZmluYWxDZXQpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgR2V0RnVuZEFkZHJlc3MoXG4gICAgZGxjT2ZmZXI6IERsY09mZmVyVjAsXG4gICAgZGxjQWNjZXB0OiBEbGNBY2NlcHRWMCxcbiAgICBpc09mZmVyZXI6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgbmV0d29yayA9IGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkTmV0d29yaygpO1xuXG4gICAgY29uc3QgZnVuZGluZ1NQSyA9IFNjcmlwdC5wMndwa2hMb2NrKFxuICAgICAgaGFzaDE2MChpc09mZmVyZXIgPyBkbGNPZmZlci5mdW5kaW5nUHViS2V5IDogZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkpLFxuICAgIClcbiAgICAgIC5zZXJpYWxpemUoKVxuICAgICAgLnNsaWNlKDEpO1xuXG4gICAgY29uc3QgZnVuZGluZ0FkZHJlc3M6IHN0cmluZyA9IGFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChcbiAgICAgIGZ1bmRpbmdTUEssXG4gICAgICBuZXR3b3JrLFxuICAgICk7XG5cbiAgICByZXR1cm4gZnVuZGluZ0FkZHJlc3M7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIEdldEZ1bmRLZXlQYWlyKFxuICAgIGRsY09mZmVyOiBEbGNPZmZlclYwLFxuICAgIGRsY0FjY2VwdDogRGxjQWNjZXB0VjAsXG4gICAgaXNPZmZlcmVyOiBib29sZWFuLFxuICApOiBQcm9taXNlPEVDUGFpckludGVyZmFjZT4ge1xuICAgIGNvbnN0IGZ1bmRpbmdBZGRyZXNzID0gYXdhaXQgdGhpcy5HZXRGdW5kQWRkcmVzcyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgaXNPZmZlcmVyLFxuICAgICk7XG5cbiAgICBjb25zdCB7IGRlcml2YXRpb25QYXRoIH0gPSBhd2FpdCB0aGlzLmdldE1ldGhvZCgnZ2V0V2FsbGV0QWRkcmVzcycpKFxuICAgICAgZnVuZGluZ0FkZHJlc3MsXG4gICAgKTtcbiAgICBjb25zdCBrZXlQYWlyOiBFQ1BhaXJJbnRlcmZhY2UgPSBhd2FpdCB0aGlzLmdldE1ldGhvZCgna2V5UGFpcicpKFxuICAgICAgZGVyaXZhdGlvblBhdGgsXG4gICAgKTtcblxuICAgIHJldHVybiBrZXlQYWlyO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBHZXRGdW5kUHJpdmF0ZUtleShcbiAgICBkbGNPZmZlcjogRGxjT2ZmZXJWMCxcbiAgICBkbGNBY2NlcHQ6IERsY0FjY2VwdFYwLFxuICAgIGlzT2ZmZXJlcjogYm9vbGVhbixcbiAgKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBmdW5kUHJpdmF0ZUtleVBhaXI6IEVDUGFpckludGVyZmFjZSA9IGF3YWl0IHRoaXMuR2V0RnVuZEtleVBhaXIoXG4gICAgICBkbGNPZmZlcixcbiAgICAgIGRsY0FjY2VwdCxcbiAgICAgIGlzT2ZmZXJlcixcbiAgICApO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGZ1bmRQcml2YXRlS2V5UGFpci5wcml2YXRlS2V5KS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICBhc3luYyBDcmVhdGVDbG9zZVJhd1R4cyhcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgICBfZGxjVHhzOiBEbGNUcmFuc2FjdGlvbnMsXG4gICAgY2xvc2VJbnB1dEFtb3VudDogYmlnaW50LFxuICAgIGlzT2ZmZXJlcjogYm9vbGVhbixcbiAgICBfZGxjQ2xvc2VzOiBEbGNDbG9zZVtdID0gW10sXG4gICAgZnVuZGluZ0lucHV0cz86IEZ1bmRpbmdJbnB1dFtdLFxuICAgIGluaXRpYXRvclBheW91dHM/OiBiaWdpbnRbXSxcbiAgKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjVHhzIH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgICBfZGxjVHhzLFxuICAgIH0pO1xuICAgIGNvbnN0IG5ldHdvcmsgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZE5ldHdvcmsoKTtcblxuICAgIGxldCBmaW5hbGl6ZXI6IER1YWxDbG9zaW5nVHhGaW5hbGl6ZXI7XG4gICAgaWYgKF9kbGNDbG9zZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBmaW5hbGl6ZXIgPSBuZXcgRHVhbENsb3NpbmdUeEZpbmFsaXplcihcbiAgICAgICAgZnVuZGluZ0lucHV0cyxcbiAgICAgICAgZGxjT2ZmZXIucGF5b3V0U1BLLFxuICAgICAgICBkbGNBY2NlcHQucGF5b3V0U1BLLFxuICAgICAgICBkbGNPZmZlci5mZWVSYXRlUGVyVmIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHJhd1RyYW5zYWN0aW9uUmVxdWVzdFByb21pc2VzOiBQcm9taXNlPHN0cmluZz5bXSA9IFtdO1xuICAgIGNvbnN0IHJhd0Nsb3NlVHhzID0gW107XG5cbiAgICBjb25zdCBudW1QYXlvdXRzID1cbiAgICAgIF9kbGNDbG9zZXMubGVuZ3RoID09PSAwID8gaW5pdGlhdG9yUGF5b3V0cy5sZW5ndGggOiBfZGxjQ2xvc2VzLmxlbmd0aDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtUGF5b3V0czsgaSsrKSB7XG4gICAgICBsZXQgb2ZmZXJQYXlvdXRWYWx1ZSA9IEJpZ0ludCgwKTtcbiAgICAgIGxldCBhY2NlcHRQYXlvdXRWYWx1ZSA9IEJpZ0ludCgwKTtcblxuICAgICAgaWYgKF9kbGNDbG9zZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnN0IHBheW91dCA9IGluaXRpYXRvclBheW91dHNbaV07XG4gICAgICAgIGNvbnN0IHBheW91dE1pbnVzT2ZmZXJGZWVzID1cbiAgICAgICAgICBmaW5hbGl6ZXIub2ZmZXJJbml0aWF0b3JGZWVzID4gcGF5b3V0XG4gICAgICAgICAgICA/IEJpZ0ludCgwKVxuICAgICAgICAgICAgOiBwYXlvdXQgLSBmaW5hbGl6ZXIub2ZmZXJJbml0aWF0b3JGZWVzO1xuICAgICAgICBjb25zdCBjb2xsYXRlcmFsTWludXNQYXlvdXQgPVxuICAgICAgICAgIHBheW91dCA+IGRsY09mZmVyLmNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWxcbiAgICAgICAgICAgID8gQmlnSW50KDApXG4gICAgICAgICAgICA6IGRsY09mZmVyLmNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWwgLSBwYXlvdXQ7XG5cbiAgICAgICAgb2ZmZXJQYXlvdXRWYWx1ZSA9IGlzT2ZmZXJlclxuICAgICAgICAgID8gY2xvc2VJbnB1dEFtb3VudCArIHBheW91dE1pbnVzT2ZmZXJGZWVzXG4gICAgICAgICAgOiBjb2xsYXRlcmFsTWludXNQYXlvdXQ7XG5cbiAgICAgICAgYWNjZXB0UGF5b3V0VmFsdWUgPSBpc09mZmVyZXJcbiAgICAgICAgICA/IGNvbGxhdGVyYWxNaW51c1BheW91dFxuICAgICAgICAgIDogY2xvc2VJbnB1dEFtb3VudCArIHBheW91dE1pbnVzT2ZmZXJGZWVzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZGxjQ2xvc2UgPSBjaGVja1R5cGVzKHsgX2RsY0Nsb3NlOiBfZGxjQ2xvc2VzW2ldIH0pLmRsY0Nsb3NlO1xuXG4gICAgICAgIG9mZmVyUGF5b3V0VmFsdWUgPSBkbGNDbG9zZS5vZmZlclBheW91dFNhdG9zaGlzO1xuICAgICAgICBhY2NlcHRQYXlvdXRWYWx1ZSA9IGRsY0Nsb3NlLmFjY2VwdFBheW91dFNhdG9zaGlzO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0eE91dHMgPSBbXTtcblxuICAgICAgaWYgKE51bWJlcihvZmZlclBheW91dFZhbHVlKSA+IDApIHtcbiAgICAgICAgdHhPdXRzLnB1c2goe1xuICAgICAgICAgIGFkZHJlc3M6IGFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChkbGNPZmZlci5wYXlvdXRTUEssIG5ldHdvcmspLFxuICAgICAgICAgIGFtb3VudDogTnVtYmVyKG9mZmVyUGF5b3V0VmFsdWUpLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKE51bWJlcihhY2NlcHRQYXlvdXRWYWx1ZSkgPiAwKSB7XG4gICAgICAgIHR4T3V0cy5wdXNoKHtcbiAgICAgICAgICBhZGRyZXNzOiBhZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQoZGxjQWNjZXB0LnBheW91dFNQSywgbmV0d29yayksXG4gICAgICAgICAgYW1vdW50OiBOdW1iZXIoYWNjZXB0UGF5b3V0VmFsdWUpLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRsY09mZmVyLnBheW91dFNlcmlhbElkID4gZGxjQWNjZXB0LnBheW91dFNlcmlhbElkKSB0eE91dHMucmV2ZXJzZSgpO1xuXG4gICAgICBjb25zdCByYXdUcmFuc2FjdGlvblJlcXVlc3Q6IENyZWF0ZVJhd1RyYW5zYWN0aW9uUmVxdWVzdCA9IHtcbiAgICAgICAgdmVyc2lvbjogMixcbiAgICAgICAgbG9ja3RpbWU6IDAsXG4gICAgICAgIHR4aW5zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHhpZDogZGxjVHhzLmZ1bmRUeC50eElkLnNlcmlhbGl6ZSgpLnJldmVyc2UoKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICB2b3V0OiBkbGNUeHMuZnVuZFR4Vm91dCxcbiAgICAgICAgICAgIHNlcXVlbmNlOiAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHR4b3V0czogdHhPdXRzLFxuICAgICAgfTtcblxuICAgICAgcmF3VHJhbnNhY3Rpb25SZXF1ZXN0UHJvbWlzZXMucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdDcmVhdGVSYXdUcmFuc2FjdGlvbicpKFxuICAgICAgICAgICAgcmF3VHJhbnNhY3Rpb25SZXF1ZXN0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmhleDtcbiAgICAgICAgfSkoKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgaGV4czogc3RyaW5nW10gPSBhd2FpdCBQcm9taXNlLmFsbChyYXdUcmFuc2FjdGlvblJlcXVlc3RQcm9taXNlcyk7XG5cbiAgICByYXdDbG9zZVR4cy5wdXNoKGhleHMpO1xuXG4gICAgcmV0dXJuIHJhd0Nsb3NlVHhzLmZsYXQoKTtcbiAgfVxuXG4gIGFzeW5jIENyZWF0ZVNpZ25hdHVyZUhhc2hlcyhcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgICBfZGxjVHhzOiBEbGNUcmFuc2FjdGlvbnMsXG4gICAgcmF3Q2xvc2VUeHM6IHN0cmluZ1tdLFxuICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgeyBkbGNPZmZlciwgZGxjQWNjZXB0LCBkbGNUeHMgfSA9IGNoZWNrVHlwZXMoe1xuICAgICAgX2RsY09mZmVyLFxuICAgICAgX2RsY0FjY2VwdCxcbiAgICAgIF9kbGNUeHMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWROZXR3b3JrKCk7XG5cbiAgICBjb25zdCBmdW5kaW5nUHViS2V5cyA9XG4gICAgICBCdWZmZXIuY29tcGFyZShkbGNPZmZlci5mdW5kaW5nUHViS2V5LCBkbGNBY2NlcHQuZnVuZGluZ1B1YktleSkgPT09IC0xXG4gICAgICAgID8gW2RsY09mZmVyLmZ1bmRpbmdQdWJLZXksIGRsY0FjY2VwdC5mdW5kaW5nUHViS2V5XVxuICAgICAgICA6IFtkbGNBY2NlcHQuZnVuZGluZ1B1YktleSwgZGxjT2ZmZXIuZnVuZGluZ1B1YktleV07XG5cbiAgICBjb25zdCBwMm1zID0gcGF5bWVudHMucDJtcyh7XG4gICAgICBtOiAyLFxuICAgICAgcHVia2V5czogZnVuZGluZ1B1YktleXMsXG4gICAgICBuZXR3b3JrLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcGF5bWVudFZhcmlhbnQgPSBwYXltZW50cy5wMndzaCh7XG4gICAgICByZWRlZW06IHAybXMsXG4gICAgICBuZXR3b3JrLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc2lnSGFzaFJlcXVlc3RQcm9taXNlczogUHJvbWlzZTxzdHJpbmc+W10gPSBbXTtcbiAgICBjb25zdCBzaWdIYXNoZXMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmF3Q2xvc2VUeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gcmF3Q2xvc2VUeHNbaV07XG5cbiAgICAgIGNvbnN0IHNpZ0hhc2hSZXF1ZXN0OiBDcmVhdGVTaWduYXR1cmVIYXNoUmVxdWVzdCA9IHtcbiAgICAgICAgdHg6IHJhd1R4LFxuICAgICAgICB0eGluOiB7XG4gICAgICAgICAgdHhpZDogZGxjVHhzLmZ1bmRUeC50eElkLnNlcmlhbGl6ZSgpLnJldmVyc2UoKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgdm91dDogZGxjVHhzLmZ1bmRUeFZvdXQsXG4gICAgICAgICAga2V5RGF0YToge1xuICAgICAgICAgICAgaGV4OiBwYXltZW50VmFyaWFudC5yZWRlZW0ub3V0cHV0LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgIHR5cGU6ICdyZWRlZW1fc2NyaXB0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFtb3VudDogTnVtYmVyKGRsY1R4cy5mdW5kVHgub3V0cHV0c1tkbGNUeHMuZnVuZFR4Vm91dF0udmFsdWUuc2F0cyksXG4gICAgICAgICAgaGFzaFR5cGU6ICdwMndzaCcsXG4gICAgICAgICAgc2lnaGFzaFR5cGU6ICdhbGwnLFxuICAgICAgICAgIHNpZ2hhc2hBbnlvbmVDYW5QYXk6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgc2lnSGFzaFJlcXVlc3RQcm9taXNlcy5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5nZXRNZXRob2QoJ0NyZWF0ZVNpZ25hdHVyZUhhc2gnKShcbiAgICAgICAgICAgIHNpZ0hhc2hSZXF1ZXN0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnNpZ2hhc2g7XG4gICAgICAgIH0pKCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHNpZ2hhc2hlczogc3RyaW5nW10gPSBhd2FpdCBQcm9taXNlLmFsbChzaWdIYXNoUmVxdWVzdFByb21pc2VzKTtcblxuICAgIHNpZ0hhc2hlcy5wdXNoKHNpZ2hhc2hlcyk7XG5cbiAgICByZXR1cm4gc2lnSGFzaGVzLmZsYXQoKTtcbiAgfVxuXG4gIGFzeW5jIENhbGN1bGF0ZUVjU2lnbmF0dXJlSGFzaGVzKFxuICAgIHNpZ0hhc2hlczogc3RyaW5nW10sXG4gICAgcHJpdktleTogc3RyaW5nLFxuICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgY2ZkTmV0d29yayA9IGF3YWl0IHRoaXMuR2V0Q2ZkTmV0d29yaygpO1xuXG4gICAgY29uc3Qgc2lnc1JlcXVlc3RQcm9taXNlczogUHJvbWlzZTxzdHJpbmc+W10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2lnSGFzaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBzaWdIYXNoID0gc2lnSGFzaGVzW2ldO1xuXG4gICAgICBjb25zdCBjYWxjdWxhdGVFY1NpZ25hdHVyZVJlcXVlc3Q6IENhbGN1bGF0ZUVjU2lnbmF0dXJlUmVxdWVzdCA9IHtcbiAgICAgICAgc2lnaGFzaDogc2lnSGFzaCxcbiAgICAgICAgcHJpdmtleURhdGE6IHtcbiAgICAgICAgICBwcml2a2V5OiBwcml2S2V5LFxuICAgICAgICAgIHdpZjogZmFsc2UsXG4gICAgICAgICAgbmV0d29yazogY2ZkTmV0d29yayxcbiAgICAgICAgfSxcbiAgICAgICAgaXNHcmluZFI6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBzaWdzUmVxdWVzdFByb21pc2VzLnB1c2goXG4gICAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmdldE1ldGhvZCgnQ2FsY3VsYXRlRWNTaWduYXR1cmUnKShcbiAgICAgICAgICAgIGNhbGN1bGF0ZUVjU2lnbmF0dXJlUmVxdWVzdCxcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiByZXNwb25zZS5zaWduYXR1cmU7XG4gICAgICAgIH0pKCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHNpZ3M6IHN0cmluZ1tdID0gYXdhaXQgUHJvbWlzZS5hbGwoc2lnc1JlcXVlc3RQcm9taXNlcyk7XG5cbiAgICByZXR1cm4gc2lncy5mbGF0KCk7XG4gIH1cblxuICBhc3luYyBWZXJpZnlTaWduYXR1cmVzKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBfZGxjQ2xvc2VzOiBEbGNDbG9zZVtdLFxuICAgIHJhd0Nsb3NlVHhzOiBzdHJpbmdbXSxcbiAgICBpc09mZmVyZXI6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjVHhzIH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgICBfZGxjVHhzLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZGxjQ2xvc2VzID0gX2RsY0Nsb3Nlcy5tYXAoXG4gICAgICAoX2RsY0Nsb3NlKSA9PiBjaGVja1R5cGVzKHsgX2RsY0Nsb3NlIH0pLmRsY0Nsb3NlLFxuICAgICk7XG5cbiAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWROZXR3b3JrKCk7XG5cbiAgICBjb25zdCBmdW5kaW5nUHViS2V5cyA9XG4gICAgICBCdWZmZXIuY29tcGFyZShkbGNPZmZlci5mdW5kaW5nUHViS2V5LCBkbGNBY2NlcHQuZnVuZGluZ1B1YktleSkgPT09IC0xXG4gICAgICAgID8gW2RsY09mZmVyLmZ1bmRpbmdQdWJLZXksIGRsY0FjY2VwdC5mdW5kaW5nUHViS2V5XVxuICAgICAgICA6IFtkbGNBY2NlcHQuZnVuZGluZ1B1YktleSwgZGxjT2ZmZXIuZnVuZGluZ1B1YktleV07XG5cbiAgICBjb25zdCBwMm1zID0gcGF5bWVudHMucDJtcyh7XG4gICAgICBtOiAyLFxuICAgICAgcHVia2V5czogZnVuZGluZ1B1YktleXMsXG4gICAgICBuZXR3b3JrLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcGF5bWVudFZhcmlhbnQgPSBwYXltZW50cy5wMndzaCh7XG4gICAgICByZWRlZW06IHAybXMsXG4gICAgICBuZXR3b3JrLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcHVia2V5ID0gaXNPZmZlcmVyID8gZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkgOiBkbGNPZmZlci5mdW5kaW5nUHViS2V5O1xuXG4gICAgY29uc3Qgc2lnc1ZhbGlkaXR5OiBQcm9taXNlPGJvb2xlYW4+W10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmF3Q2xvc2VUeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gcmF3Q2xvc2VUeHNbaV07XG4gICAgICBjb25zdCBkbGNDbG9zZSA9IGRsY0Nsb3Nlc1tpXTtcblxuICAgICAgY29uc3QgdmVyaWZ5U2lnbmF0dXJlUmVxdWVzdDogVmVyaWZ5U2lnbmF0dXJlUmVxdWVzdCA9IHtcbiAgICAgICAgdHg6IHJhd1R4LFxuICAgICAgICB0eGluOiB7XG4gICAgICAgICAgdHhpZDogZGxjVHhzLmZ1bmRUeC50eElkLnNlcmlhbGl6ZSgpLnJldmVyc2UoKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgdm91dDogZGxjVHhzLmZ1bmRUeFZvdXQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBkbGNDbG9zZS5jbG9zZVNpZ25hdHVyZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgcHVia2V5OiBwdWJrZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIHJlZGVlbVNjcmlwdDogcGF5bWVudFZhcmlhbnQucmVkZWVtLm91dHB1dC50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgaGFzaFR5cGU6ICdwMndzaCcsXG4gICAgICAgICAgc2lnaGFzaFR5cGU6ICdhbGwnLFxuICAgICAgICAgIHNpZ2hhc2hBbnlvbmVDYW5QYXk6IGZhbHNlLFxuICAgICAgICAgIGFtb3VudDogTnVtYmVyKGRsY1R4cy5mdW5kVHgub3V0cHV0c1tkbGNUeHMuZnVuZFR4Vm91dF0udmFsdWUuc2F0cyksXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBzaWdzVmFsaWRpdHkucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdWZXJpZnlTaWduYXR1cmUnKShcbiAgICAgICAgICAgIHZlcmlmeVNpZ25hdHVyZVJlcXVlc3QsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgICAgICAgfSkoKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgYXJlU2lnc1ZhbGlkID0gKGF3YWl0IFByb21pc2UuYWxsKHNpZ3NWYWxpZGl0eSkpLmV2ZXJ5KChiKSA9PiBiKTtcbiAgICByZXR1cm4gYXJlU2lnc1ZhbGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgd2FsbGV0IGlzIG9mZmVyZXIgb2YgRGxjT2ZmZXIgb3IgRGxjQWNjZXB0XG4gICAqIEBwYXJhbSBkbGNPZmZlciBEbGMgT2ZmZXIgTWVzc2FnZVxuICAgKiBAcGFyYW0gZGxjQWNjZXB0IERsYyBBY2NlcHQgTWVzc2FnZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn1cbiAgICovXG4gIGFzeW5jIGlzT2ZmZXJlcihcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgeyBkbGNPZmZlciwgZGxjQWNjZXB0IH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgfSk7XG4gICAgY29uc3QgbmV0d29yayA9IGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkTmV0d29yaygpO1xuXG4gICAgY29uc3Qgb2ZmZXJGdW5kaW5nU1BLID0gU2NyaXB0LnAyd3BraExvY2soaGFzaDE2MChkbGNPZmZlci5mdW5kaW5nUHViS2V5KSlcbiAgICAgIC5zZXJpYWxpemUoKVxuICAgICAgLnNsaWNlKDEpO1xuICAgIGNvbnN0IGFjY2VwdEZ1bmRpbmdTUEsgPSBTY3JpcHQucDJ3cGtoTG9jayhoYXNoMTYwKGRsY0FjY2VwdC5mdW5kaW5nUHViS2V5KSlcbiAgICAgIC5zZXJpYWxpemUoKVxuICAgICAgLnNsaWNlKDEpO1xuXG4gICAgY29uc3Qgb2ZmZXJGdW5kaW5nQWRkcmVzczogc3RyaW5nID0gYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KFxuICAgICAgb2ZmZXJGdW5kaW5nU1BLLFxuICAgICAgbmV0d29yayxcbiAgICApO1xuXG4gICAgY29uc3QgYWNjZXB0RnVuZGluZ0FkZHJlc3M6IHN0cmluZyA9IGFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChcbiAgICAgIGFjY2VwdEZ1bmRpbmdTUEssXG4gICAgICBuZXR3b3JrLFxuICAgICk7XG5cbiAgICBsZXQgd2FsbGV0QWRkcmVzczogQWRkcmVzcyA9IGF3YWl0IHRoaXMuY2xpZW50LmZpbmFuY2V3YWxsZXQucXVpY2tGaW5kQWRkcmVzcyhcbiAgICAgIFtvZmZlckZ1bmRpbmdBZGRyZXNzXSxcbiAgICApO1xuICAgIGlmICh3YWxsZXRBZGRyZXNzKSByZXR1cm4gdHJ1ZTtcbiAgICB3YWxsZXRBZGRyZXNzID0gYXdhaXQgdGhpcy5jbGllbnQuZmluYW5jZXdhbGxldC5xdWlja0ZpbmRBZGRyZXNzKFtcbiAgICAgIGFjY2VwdEZ1bmRpbmdBZGRyZXNzLFxuICAgIF0pO1xuICAgIGlmICh3YWxsZXRBZGRyZXNzKSByZXR1cm4gZmFsc2U7XG5cbiAgICB0aHJvdyBFcnJvcignV2FsbGV0IEFkZHJlc3Mgbm90IGZvdW5kIGZvciBEbGNPZmZlciBvciBEbGNBY2NlcHQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgRExDIE9mZmVyIE1lc3NhZ2VcbiAgICogQHBhcmFtIGNvbnRyYWN0SW5mbyBDb250cmFjdEluZm8gVExWIChWMCBvciBWMSlcbiAgICogQHBhcmFtIG9mZmVyQ29sbGF0ZXJhbFNhdG9zaGlzIEFtb3VudCBETEMgSW5pdGlhdG9yIGlzIHB1dHRpbmcgaW50byB0aGUgY29udHJhY3RcbiAgICogQHBhcmFtIGZlZVJhdGVQZXJWYiBGZWUgcmF0ZSBpbiBzYXRvc2hpIHBlciB2aXJ0dWFsIGJ5dGUgdGhhdCBib3RoIHNpZGVzIHVzZSB0byBjb21wdXRlIGZlZXMgaW4gZnVuZGluZyB0eFxuICAgKiBAcGFyYW0gY2V0TG9ja3RpbWUgVGhlIG5Mb2NrVGltZSB0byBiZSBwdXQgb24gQ0VUc1xuICAgKiBAcGFyYW0gcmVmdW5kTG9ja3RpbWUgVGhlIG5Mb2NrVGltZSB0byBiZSBwdXQgb24gdGhlIHJlZnVuZCB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxEbGNPZmZlcj59XG4gICAqL1xuICBhc3luYyBjcmVhdGVEbGNPZmZlcihcbiAgICBjb250cmFjdEluZm86IENvbnRyYWN0SW5mbyxcbiAgICBvZmZlckNvbGxhdGVyYWxTYXRvc2hpczogYmlnaW50LFxuICAgIGZlZVJhdGVQZXJWYjogYmlnaW50LFxuICAgIGNldExvY2t0aW1lOiBudW1iZXIsXG4gICAgcmVmdW5kTG9ja3RpbWU6IG51bWJlcixcbiAgICBmaXhlZElucHV0cz86IElucHV0W10sXG4gICk6IFByb21pc2U8RGxjT2ZmZXI+IHtcbiAgICBjb250cmFjdEluZm8udmFsaWRhdGUoKTtcbiAgICBjb25zdCBuZXR3b3JrID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0ZWROZXR3b3JrKCk7XG5cbiAgICBjb25zdCBkbGNPZmZlciA9IG5ldyBEbGNPZmZlclYwKCk7XG5cbiAgICBjb25zdCB7XG4gICAgICBmdW5kaW5nUHViS2V5LFxuICAgICAgcGF5b3V0U1BLLFxuICAgICAgcGF5b3V0U2VyaWFsSWQsXG4gICAgICBmdW5kaW5nSW5wdXRzOiBfZnVuZGluZ0lucHV0cyxcbiAgICAgIGNoYW5nZVNQSyxcbiAgICAgIGNoYW5nZVNlcmlhbElkLFxuICAgIH0gPSBhd2FpdCB0aGlzLkluaXRpYWxpemUoXG4gICAgICBvZmZlckNvbGxhdGVyYWxTYXRvc2hpcyxcbiAgICAgIGZlZVJhdGVQZXJWYixcbiAgICAgIGZpeGVkSW5wdXRzLFxuICAgICk7XG5cbiAgICBfZnVuZGluZ0lucHV0cy5mb3JFYWNoKChpbnB1dCkgPT5cbiAgICAgIGFzc2VydChcbiAgICAgICAgaW5wdXQudHlwZSA9PT0gTWVzc2FnZVR5cGUuRnVuZGluZ0lucHV0VjAsXG4gICAgICAgICdGdW5kaW5nSW5wdXQgbXVzdCBiZSBWMCcsXG4gICAgICApLFxuICAgICk7XG5cbiAgICBjb25zdCBmdW5kaW5nSW5wdXRzOiBGdW5kaW5nSW5wdXRWMFtdID0gX2Z1bmRpbmdJbnB1dHMubWFwKFxuICAgICAgKGlucHV0KSA9PiBpbnB1dCBhcyBGdW5kaW5nSW5wdXRWMCxcbiAgICApO1xuXG4gICAgY29uc3QgZnVuZE91dHB1dFNlcmlhbElkID0gZ2VuZXJhdGVTZXJpYWxJZCgpO1xuXG4gICAgYXNzZXJ0KFxuICAgICAgY2hhbmdlU2VyaWFsSWQgIT09IGZ1bmRPdXRwdXRTZXJpYWxJZCxcbiAgICAgICdjaGFuZ2VTZXJpYWxJZCBjYW5ub3QgZXF1YWwgdGhlIGZ1bmRPdXRwdXRTZXJpYWxJZCcsXG4gICAgKTtcblxuICAgIGRsY09mZmVyLmNvbnRyYWN0RmxhZ3MgPSBCdWZmZXIuZnJvbSgnMDAnLCAnaGV4Jyk7XG4gICAgZGxjT2ZmZXIuY2hhaW5IYXNoID0gY2hhaW5IYXNoRnJvbU5ldHdvcmsobmV0d29yayk7XG4gICAgZGxjT2ZmZXIuY29udHJhY3RJbmZvID0gY29udHJhY3RJbmZvO1xuICAgIGRsY09mZmVyLmZ1bmRpbmdQdWJLZXkgPSBmdW5kaW5nUHViS2V5O1xuICAgIGRsY09mZmVyLnBheW91dFNQSyA9IHBheW91dFNQSztcbiAgICBkbGNPZmZlci5wYXlvdXRTZXJpYWxJZCA9IHBheW91dFNlcmlhbElkO1xuICAgIGRsY09mZmVyLm9mZmVyQ29sbGF0ZXJhbFNhdG9zaGlzID0gb2ZmZXJDb2xsYXRlcmFsU2F0b3NoaXM7XG4gICAgZGxjT2ZmZXIuZnVuZGluZ0lucHV0cyA9IGZ1bmRpbmdJbnB1dHM7XG4gICAgZGxjT2ZmZXIuY2hhbmdlU1BLID0gY2hhbmdlU1BLO1xuICAgIGRsY09mZmVyLmNoYW5nZVNlcmlhbElkID0gY2hhbmdlU2VyaWFsSWQ7XG4gICAgZGxjT2ZmZXIuZnVuZE91dHB1dFNlcmlhbElkID0gZGxjT2ZmZXIuZnVuZE91dHB1dFNlcmlhbElkID0gZnVuZE91dHB1dFNlcmlhbElkO1xuICAgIGRsY09mZmVyLmZlZVJhdGVQZXJWYiA9IGZlZVJhdGVQZXJWYjtcbiAgICBkbGNPZmZlci5jZXRMb2NrdGltZSA9IGNldExvY2t0aW1lO1xuICAgIGRsY09mZmVyLnJlZnVuZExvY2t0aW1lID0gcmVmdW5kTG9ja3RpbWU7XG5cbiAgICBhc3NlcnQoXG4gICAgICAoKCkgPT4ge1xuICAgICAgICBjb25zdCBmaW5hbGl6ZXIgPSBuZXcgRHVhbEZ1bmRpbmdUeEZpbmFsaXplcihcbiAgICAgICAgICBkbGNPZmZlci5mdW5kaW5nSW5wdXRzLFxuICAgICAgICAgIGRsY09mZmVyLnBheW91dFNQSyxcbiAgICAgICAgICBkbGNPZmZlci5jaGFuZ2VTUEssXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgZGxjT2ZmZXIuZmVlUmF0ZVBlclZiLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBmdW5kaW5nID0gZnVuZGluZ0lucHV0cy5yZWR1Y2UoKHRvdGFsLCBpbnB1dCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0b3RhbCArIGlucHV0LnByZXZUeC5vdXRwdXRzW2lucHV0LnByZXZUeFZvdXRdLnZhbHVlLnNhdHM7XG4gICAgICAgIH0sIEJpZ0ludCgwKSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmRpbmcgPj0gb2ZmZXJDb2xsYXRlcmFsU2F0b3NoaXMgKyBmaW5hbGl6ZXIub2ZmZXJGZWVzO1xuICAgICAgfSkoKSxcbiAgICAgICdmdW5kaW5nSW5wdXRzIGZvciBkbGNPZmZlciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvZmZlckNvbGxhdGVyYWxTYXRvc2hpcyBwbHVzIG9mZmVyRmVlcycsXG4gICAgKTtcblxuICAgIGRsY09mZmVyLnZhbGlkYXRlKCk7XG5cbiAgICByZXR1cm4gZGxjT2ZmZXI7XG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0IERMQyBPZmZlclxuICAgKiBAcGFyYW0gX2RsY09mZmVyIERsYyBPZmZlciBNZXNzYWdlXG4gICAqIEBwYXJhbSBmaXhlZElucHV0cyBPcHRpb25hbCBpbnB1dHMgdG8gdXNlIGZvciBGdW5kaW5nIElucHV0c1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBY2NlcHREbGNPZmZlclJlc3BvbnNlfVxuICAgKi9cbiAgYXN5bmMgYWNjZXB0RGxjT2ZmZXIoXG4gICAgX2RsY09mZmVyOiBEbGNPZmZlcixcbiAgICBmaXhlZElucHV0cz86IElucHV0W10sXG4gICk6IFByb21pc2U8QWNjZXB0RGxjT2ZmZXJSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIgfSA9IGNoZWNrVHlwZXMoeyBfZGxjT2ZmZXIgfSk7XG4gICAgZGxjT2ZmZXIudmFsaWRhdGUoKTtcblxuICAgIGNvbnN0IGFjY2VwdENvbGxhdGVyYWxTYXRvc2hpcyA9XG4gICAgICBkbGNPZmZlci5jb250cmFjdEluZm8udG90YWxDb2xsYXRlcmFsIC0gZGxjT2ZmZXIub2ZmZXJDb2xsYXRlcmFsU2F0b3NoaXM7XG5cbiAgICBhc3NlcnQoXG4gICAgICBhY2NlcHRDb2xsYXRlcmFsU2F0b3NoaXMgPT09XG4gICAgICAgIGRsY09mZmVyLmNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWwgLVxuICAgICAgICAgIGRsY09mZmVyLm9mZmVyQ29sbGF0ZXJhbFNhdG9zaGlzLFxuICAgICAgJ2FjY2VwdENvbGxhdGVyaWFsU2F0b3NoaXMgc2hvdWxkIGVxdWFsIHRvdGFsQ29sbGF0ZXJhbCAtIG9mZmVyQ29sbGF0ZXJhbFNhdG9zaGlzJyxcbiAgICApO1xuXG4gICAgY29uc3Qge1xuICAgICAgZnVuZGluZ1B1YktleSxcbiAgICAgIHBheW91dFNQSyxcbiAgICAgIHBheW91dFNlcmlhbElkLFxuICAgICAgZnVuZGluZ0lucHV0czogX2Z1bmRpbmdJbnB1dHMsXG4gICAgICBjaGFuZ2VTUEssXG4gICAgICBjaGFuZ2VTZXJpYWxJZCxcbiAgICB9ID0gYXdhaXQgdGhpcy5Jbml0aWFsaXplKFxuICAgICAgYWNjZXB0Q29sbGF0ZXJhbFNhdG9zaGlzLFxuICAgICAgZGxjT2ZmZXIuZmVlUmF0ZVBlclZiLFxuICAgICAgZml4ZWRJbnB1dHMsXG4gICAgKTtcblxuICAgIGFzc2VydChcbiAgICAgIEJ1ZmZlci5jb21wYXJlKGRsY09mZmVyLmZ1bmRpbmdQdWJLZXksIGZ1bmRpbmdQdWJLZXkpICE9PSAwLFxuICAgICAgJ0RsY09mZmVyIGFuZCBEbGNBY2NlcHQgRnVuZGluZ1B1YktleSBjYW5ub3QgYmUgdGhlIHNhbWUnLFxuICAgICk7XG5cbiAgICBfZnVuZGluZ0lucHV0cy5mb3JFYWNoKChpbnB1dCkgPT5cbiAgICAgIGFzc2VydChcbiAgICAgICAgaW5wdXQudHlwZSA9PT0gTWVzc2FnZVR5cGUuRnVuZGluZ0lucHV0VjAsXG4gICAgICAgICdGdW5kaW5nSW5wdXQgbXVzdCBiZSBWMCcsXG4gICAgICApLFxuICAgICk7XG5cbiAgICBjb25zdCBmdW5kaW5nSW5wdXRzOiBGdW5kaW5nSW5wdXRWMFtdID0gX2Z1bmRpbmdJbnB1dHMubWFwKFxuICAgICAgKGlucHV0KSA9PiBpbnB1dCBhcyBGdW5kaW5nSW5wdXRWMCxcbiAgICApO1xuXG4gICAgY29uc3QgZGxjQWNjZXB0ID0gbmV3IERsY0FjY2VwdFYwKCk7XG5cbiAgICBkbGNBY2NlcHQudGVtcENvbnRyYWN0SWQgPSBzaGEyNTYoZGxjT2ZmZXIuc2VyaWFsaXplKCkpO1xuICAgIGRsY0FjY2VwdC5hY2NlcHRDb2xsYXRlcmFsU2F0b3NoaXMgPSBhY2NlcHRDb2xsYXRlcmFsU2F0b3NoaXM7XG4gICAgZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkgPSBmdW5kaW5nUHViS2V5O1xuICAgIGRsY0FjY2VwdC5wYXlvdXRTUEsgPSBwYXlvdXRTUEs7XG4gICAgZGxjQWNjZXB0LnBheW91dFNlcmlhbElkID0gZGxjQWNjZXB0LnBheW91dFNlcmlhbElkID0gcGF5b3V0U2VyaWFsSWQ7XG4gICAgZGxjQWNjZXB0LmZ1bmRpbmdJbnB1dHMgPSBmdW5kaW5nSW5wdXRzO1xuICAgIGRsY0FjY2VwdC5jaGFuZ2VTUEsgPSBjaGFuZ2VTUEs7XG4gICAgZGxjQWNjZXB0LmNoYW5nZVNlcmlhbElkID0gZGxjQWNjZXB0LmNoYW5nZVNlcmlhbElkID0gY2hhbmdlU2VyaWFsSWQ7XG5cbiAgICBhc3NlcnQoXG4gICAgICBkbGNBY2NlcHQuY2hhbmdlU2VyaWFsSWQgIT09IGRsY09mZmVyLmZ1bmRPdXRwdXRTZXJpYWxJZCxcbiAgICAgICdjaGFuZ2VTZXJpYWxJZCBjYW5ub3QgZXF1YWwgdGhlIGZ1bmRPdXRwdXRTZXJpYWxJZCcsXG4gICAgKTtcblxuICAgIGFzc2VydChcbiAgICAgIGRsY09mZmVyLnBheW91dFNlcmlhbElkICE9PSBkbGNBY2NlcHQucGF5b3V0U2VyaWFsSWQsXG4gICAgICAnb2ZmZXIucGF5b3V0U2VyaWFsSWQgY2Fubm90IGVxdWFsIGFjY2VwdC5wYXlvdXRTZXJpYWxJZCcsXG4gICAgKTtcblxuICAgIGFzc2VydChcbiAgICAgICgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGlkcyA9IFtcbiAgICAgICAgICBkbGNPZmZlci5jaGFuZ2VTZXJpYWxJZCxcbiAgICAgICAgICBkbGNBY2NlcHQuY2hhbmdlU2VyaWFsSWQsXG4gICAgICAgICAgZGxjT2ZmZXIuZnVuZE91dHB1dFNlcmlhbElkLFxuICAgICAgICBdO1xuICAgICAgICByZXR1cm4gbmV3IFNldChpZHMpLnNpemUgPT09IGlkcy5sZW5ndGg7XG4gICAgICB9KSgpLFxuICAgICAgJ29mZmVyLmNoYW5nZVNlcmlhbElELCBhY2NlcHQuY2hhbmdlU2VyaWFsSWQgYW5kIGZ1bmRPdXRwdXRTZXJpYWxJZCBtdXN0IGJlIHVuaXF1ZScsXG4gICAgKTtcblxuICAgIGRsY0FjY2VwdC52YWxpZGF0ZSgpO1xuXG4gICAgYXNzZXJ0KFxuICAgICAgKCgpID0+IHtcbiAgICAgICAgY29uc3QgZmluYWxpemVyID0gbmV3IER1YWxGdW5kaW5nVHhGaW5hbGl6ZXIoXG4gICAgICAgICAgZGxjT2ZmZXIuZnVuZGluZ0lucHV0cyxcbiAgICAgICAgICBkbGNPZmZlci5wYXlvdXRTUEssXG4gICAgICAgICAgZGxjT2ZmZXIuY2hhbmdlU1BLLFxuICAgICAgICAgIGRsY0FjY2VwdC5mdW5kaW5nSW5wdXRzLFxuICAgICAgICAgIGRsY0FjY2VwdC5wYXlvdXRTUEssXG4gICAgICAgICAgZGxjQWNjZXB0LmNoYW5nZVNQSyxcbiAgICAgICAgICBkbGNPZmZlci5mZWVSYXRlUGVyVmIsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGZ1bmRpbmcgPSBmdW5kaW5nSW5wdXRzLnJlZHVjZSgodG90YWwsIGlucHV0KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRvdGFsICsgaW5wdXQucHJldlR4Lm91dHB1dHNbaW5wdXQucHJldlR4Vm91dF0udmFsdWUuc2F0cztcbiAgICAgICAgfSwgQmlnSW50KDApKTtcblxuICAgICAgICByZXR1cm4gZnVuZGluZyA+PSBhY2NlcHRDb2xsYXRlcmFsU2F0b3NoaXMgKyBmaW5hbGl6ZXIuYWNjZXB0RmVlcztcbiAgICAgIH0pKCksXG4gICAgICAnZnVuZGluZ0lucHV0cyBmb3IgZGxjQWNjZXB0IG11c3QgYmUgZ3JlYXRlciB0aGFuIGFjY2VwdENvbGxhdGVyYWxTYXRvc2hpcyBwbHVzIGFjY2VwdEZlZXMnLFxuICAgICk7XG5cbiAgICBjb25zdCB7IGRsY1RyYW5zYWN0aW9ucywgbWVzc2FnZXNMaXN0IH0gPSBhd2FpdCB0aGlzLmNyZWF0ZURsY1R4cyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICk7XG5cbiAgICBjb25zdCB7XG4gICAgICBjZXRTaWduYXR1cmVzLFxuICAgICAgcmVmdW5kU2lnbmF0dXJlLFxuICAgIH0gPSBhd2FpdCB0aGlzLkNyZWF0ZUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzKFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBkbGNUcmFuc2FjdGlvbnMsXG4gICAgICBtZXNzYWdlc0xpc3QsXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgYXNzZXJ0KFxuICAgICAgZGxjVHJhbnNhY3Rpb25zLnR5cGUgPT09IE1lc3NhZ2VUeXBlLkRsY1RyYW5zYWN0aW9uc1YwLFxuICAgICAgJ0RsY1RyYW5zYWN0aW9ucyBtdXN0IGJlIFYwJyxcbiAgICApO1xuICAgIGNvbnN0IF9kbGNUcmFuc2FjdGlvbnMgPSBkbGNUcmFuc2FjdGlvbnMgYXMgRGxjVHJhbnNhY3Rpb25zVjA7XG5cbiAgICBjb25zdCBjb250cmFjdElkID0geG9yKFxuICAgICAgX2RsY1RyYW5zYWN0aW9ucy5mdW5kVHgudHhJZC5zZXJpYWxpemUoKSxcbiAgICAgIGRsY0FjY2VwdC50ZW1wQ29udHJhY3RJZCxcbiAgICApO1xuICAgIF9kbGNUcmFuc2FjdGlvbnMuY29udHJhY3RJZCA9IGNvbnRyYWN0SWQ7XG5cbiAgICBkbGNBY2NlcHQuY2V0U2lnbmF0dXJlcyA9IGNldFNpZ25hdHVyZXM7XG4gICAgZGxjQWNjZXB0LnJlZnVuZFNpZ25hdHVyZSA9IHJlZnVuZFNpZ25hdHVyZTtcbiAgICBkbGNBY2NlcHQubmVnb3RpYXRpb25GaWVsZHMgPSBuZXcgTmVnb3RpYXRpb25GaWVsZHNWMCgpO1xuXG4gICAgcmV0dXJuIHsgZGxjQWNjZXB0LCBkbGNUcmFuc2FjdGlvbnM6IF9kbGNUcmFuc2FjdGlvbnMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIERsYyBBY2NlcHQgTWVzc2FnZVxuICAgKiBAcGFyYW0gX2RsY09mZmVyIERsYyBPZmZlciBNZXNzYWdlXG4gICAqIEBwYXJhbSBfZGxjQWNjZXB0IERsYyBBY2NlcHQgTWVzc2FnZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTaWduRGxjQWNjZXB0UmVzcG9uc2V9XG4gICAqL1xuICBhc3luYyBzaWduRGxjQWNjZXB0KFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICApOiBQcm9taXNlPFNpZ25EbGNBY2NlcHRSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgIH0pO1xuICAgIGRsY09mZmVyLnZhbGlkYXRlKCk7XG4gICAgZGxjQWNjZXB0LnZhbGlkYXRlKCk7XG5cbiAgICBhc3NlcnQoXG4gICAgICBCdWZmZXIuY29tcGFyZShkbGNPZmZlci5mdW5kaW5nUHViS2V5LCBkbGNBY2NlcHQuZnVuZGluZ1B1YktleSkgIT09IDAsXG4gICAgICAnRGxjT2ZmZXIgYW5kIERsY0FjY2VwdCBGdW5kaW5nUHViS2V5IGNhbm5vdCBiZSB0aGUgc2FtZScsXG4gICAgKTtcblxuICAgIGNvbnN0IGRsY1NpZ24gPSBuZXcgRGxjU2lnblYwKCk7XG5cbiAgICBjb25zdCB7IGRsY1RyYW5zYWN0aW9ucywgbWVzc2FnZXNMaXN0IH0gPSBhd2FpdCB0aGlzLmNyZWF0ZURsY1R4cyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICk7XG5cbiAgICBhd2FpdCB0aGlzLlZlcmlmeUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzKFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBkbGNTaWduLFxuICAgICAgZGxjVHJhbnNhY3Rpb25zLFxuICAgICAgbWVzc2FnZXNMaXN0LFxuICAgICAgdHJ1ZSxcbiAgICApO1xuXG4gICAgY29uc3Qge1xuICAgICAgY2V0U2lnbmF0dXJlcyxcbiAgICAgIHJlZnVuZFNpZ25hdHVyZSxcbiAgICB9ID0gYXdhaXQgdGhpcy5DcmVhdGVDZXRBZGFwdG9yQW5kUmVmdW5kU2lncyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgZGxjVHJhbnNhY3Rpb25zLFxuICAgICAgbWVzc2FnZXNMaXN0LFxuICAgICAgdHJ1ZSxcbiAgICApO1xuXG4gICAgY29uc3QgZnVuZGluZ1NpZ25hdHVyZXMgPSBhd2FpdCB0aGlzLkNyZWF0ZUZ1bmRpbmdTaWdzKFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBkbGNUcmFuc2FjdGlvbnMsXG4gICAgICB0cnVlLFxuICAgICk7XG5cbiAgICBjb25zdCBkbGNUeHMgPSBkbGNUcmFuc2FjdGlvbnMgYXMgRGxjVHJhbnNhY3Rpb25zVjA7XG5cbiAgICBjb25zdCBjb250cmFjdElkID0geG9yKFxuICAgICAgZGxjVHhzLmZ1bmRUeC50eElkLnNlcmlhbGl6ZSgpLFxuICAgICAgZGxjQWNjZXB0LnRlbXBDb250cmFjdElkLFxuICAgICk7XG5cbiAgICBhc3NlcnQoXG4gICAgICBCdWZmZXIuY29tcGFyZShcbiAgICAgICAgY29udHJhY3RJZCxcbiAgICAgICAgeG9yKGRsY1R4cy5mdW5kVHgudHhJZC5zZXJpYWxpemUoKSwgZGxjQWNjZXB0LnRlbXBDb250cmFjdElkKSxcbiAgICAgICkgPT09IDAsXG4gICAgICAnY29udHJhY3RJZCBtdXN0IGJlIHRoZSB4b3Igb2YgZnVuZGluZyB0eGlkLCBmdW5kaW5nT3V0cHV0SW5kZXggYW5kIHRoZSB0ZW1wQ29udHJhY3RJZCcsXG4gICAgKTtcblxuICAgIGRsY1R4cy5jb250cmFjdElkID0gY29udHJhY3RJZDtcblxuICAgIGRsY1NpZ24uY29udHJhY3RJZCA9IGNvbnRyYWN0SWQ7XG4gICAgZGxjU2lnbi5jZXRTaWduYXR1cmVzID0gY2V0U2lnbmF0dXJlcztcbiAgICBkbGNTaWduLnJlZnVuZFNpZ25hdHVyZSA9IHJlZnVuZFNpZ25hdHVyZTtcbiAgICBkbGNTaWduLmZ1bmRpbmdTaWduYXR1cmVzID0gZnVuZGluZ1NpZ25hdHVyZXM7XG5cbiAgICByZXR1cm4geyBkbGNTaWduLCBkbGNUcmFuc2FjdGlvbnM6IGRsY1R4cyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmFsaXplIERsYyBTaWduXG4gICAqIEBwYXJhbSBfZGxjT2ZmZXIgRGxjIE9mZmVyIE1lc3NhZ2VcbiAgICogQHBhcmFtIF9kbGNBY2NlcHQgRGxjIEFjY2VwdCBNZXNzYWdlXG4gICAqIEBwYXJhbSBfZGxjU2lnbiBEbGMgU2lnbiBNZXNzYWdlXG4gICAqIEBwYXJhbSBfZGxjVHhzIERsYyBUcmFuc2FjdGlvbnMgTWVzc2FnZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUeD59XG4gICAqL1xuICBhc3luYyBmaW5hbGl6ZURsY1NpZ24oXG4gICAgX2RsY09mZmVyOiBEbGNPZmZlcixcbiAgICBfZGxjQWNjZXB0OiBEbGNBY2NlcHQsXG4gICAgX2RsY1NpZ246IERsY1NpZ24sXG4gICAgX2RsY1R4czogRGxjVHJhbnNhY3Rpb25zLFxuICApOiBQcm9taXNlPFR4PiB7XG4gICAgY29uc3QgeyBkbGNPZmZlciwgZGxjQWNjZXB0LCBkbGNTaWduLCBkbGNUeHMgfSA9IGNoZWNrVHlwZXMoe1xuICAgICAgX2RsY09mZmVyLFxuICAgICAgX2RsY0FjY2VwdCxcbiAgICAgIF9kbGNTaWduLFxuICAgICAgX2RsY1R4cyxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBheW91dFJlc3BvbnNlcyA9IHRoaXMuR2V0UGF5b3V0cyhkbGNPZmZlcik7XG4gICAgY29uc3QgeyBtZXNzYWdlc0xpc3QgfSA9IHRoaXMuRmxhdHRlblBheW91dHMocGF5b3V0UmVzcG9uc2VzKTtcblxuICAgIGF3YWl0IHRoaXMuVmVyaWZ5Q2V0QWRhcHRvckFuZFJlZnVuZFNpZ3MoXG4gICAgICBkbGNPZmZlcixcbiAgICAgIGRsY0FjY2VwdCxcbiAgICAgIGRsY1NpZ24sXG4gICAgICBkbGNUeHMsXG4gICAgICBtZXNzYWdlc0xpc3QsXG4gICAgICBmYWxzZSxcbiAgICApO1xuXG4gICAgYXdhaXQgdGhpcy5WZXJpZnlGdW5kaW5nU2lncyhkbGNPZmZlciwgZGxjQWNjZXB0LCBkbGNTaWduLCBkbGNUeHMsIGZhbHNlKTtcblxuICAgIGNvbnN0IGZ1bmRpbmdTaWduYXR1cmVzID0gYXdhaXQgdGhpcy5DcmVhdGVGdW5kaW5nU2lncyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgZGxjVHhzLFxuICAgICAgZmFsc2UsXG4gICAgKTtcblxuICAgIGNvbnN0IGZ1bmRUeCA9IGF3YWl0IHRoaXMuQ3JlYXRlRnVuZGluZ1R4KFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBkbGNTaWduLFxuICAgICAgZGxjVHhzLFxuICAgICAgZnVuZGluZ1NpZ25hdHVyZXMsXG4gICAgKTtcblxuICAgIHJldHVybiBmdW5kVHg7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBETENcbiAgICogQHBhcmFtIF9kbGNPZmZlciBEbGMgT2ZmZXIgTWVzc2FnZVxuICAgKiBAcGFyYW0gX2RsY0FjY2VwdCBEbGMgQWNjZXB0IE1lc3NhZ2VcbiAgICogQHBhcmFtIF9kbGNTaWduIERsYyBTaWduIE1lc3NhZ2VcbiAgICogQHBhcmFtIF9kbGNUeHMgRGxjIFRyYW5zYWN0aW9ucyBNZXNzYWdlXG4gICAqIEBwYXJhbSBvcmFjbGVBdHRlc3RhdGlvbiBPcmFjbGUgQXR0ZXN0YXRpb25zIFRMViAoVjApXG4gICAqIEBwYXJhbSBpc09mZmVyZXIgV2hldGhlciBwYXJ0eSBpcyBEbGMgT2ZmZXJlclxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUeD59XG4gICAqL1xuICBhc3luYyBleGVjdXRlKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNTaWduOiBEbGNTaWduLFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBvcmFjbGVBdHRlc3RhdGlvbjogT3JhY2xlQXR0ZXN0YXRpb25WMCxcbiAgICBpc09mZmVyZXI/OiBib29sZWFuLFxuICApOiBQcm9taXNlPFR4PiB7XG4gICAgY29uc3QgeyBkbGNPZmZlciwgZGxjQWNjZXB0LCBkbGNTaWduLCBkbGNUeHMgfSA9IGNoZWNrVHlwZXMoe1xuICAgICAgX2RsY09mZmVyLFxuICAgICAgX2RsY0FjY2VwdCxcbiAgICAgIF9kbGNTaWduLFxuICAgICAgX2RsY1R4cyxcbiAgICB9KTtcblxuICAgIGlmIChpc09mZmVyZXIgPT09IHVuZGVmaW5lZClcbiAgICAgIGlzT2ZmZXJlciA9IGF3YWl0IHRoaXMuaXNPZmZlcmVyKGRsY09mZmVyLCBkbGNBY2NlcHQpO1xuXG4gICAgdGhpcy5WYWxpZGF0ZUV2ZW50KGRsY09mZmVyLCBvcmFjbGVBdHRlc3RhdGlvbik7XG5cbiAgICByZXR1cm4gdGhpcy5GaW5kQW5kU2lnbkNldChcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgZGxjU2lnbixcbiAgICAgIGRsY1R4cyxcbiAgICAgIG9yYWNsZUF0dGVzdGF0aW9uLFxuICAgICAgaXNPZmZlcmVyLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVmdW5kIERMQ1xuICAgKiBAcGFyYW0gX2RsY09mZmVyIERsYyBPZmZlciBNZXNzYWdlXG4gICAqIEBwYXJhbSBfZGxjQWNjZXB0IERsYyBBY2NlcHQgTWVzc2FnZVxuICAgKiBAcGFyYW0gX2RsY1NpZ24gRGxjIFNpZ24gTWVzc2FnZVxuICAgKiBAcGFyYW0gX2RsY1R4cyBEbGMgVHJhbnNhY3Rpb25zIG1lc3NhZ2VcbiAgICogQHJldHVybnMge1Byb21pc2U8VHg+fVxuICAgKi9cbiAgYXN5bmMgcmVmdW5kKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNTaWduOiBEbGNTaWduLFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgKTogUHJvbWlzZTxUeD4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjU2lnbiwgZGxjVHhzIH0gPSBjaGVja1R5cGVzKHtcbiAgICAgIF9kbGNPZmZlcixcbiAgICAgIF9kbGNBY2NlcHQsXG4gICAgICBfZGxjU2lnbixcbiAgICAgIF9kbGNUeHMsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzaWduYXR1cmVzID1cbiAgICAgIEJ1ZmZlci5jb21wYXJlKGRsY09mZmVyLmZ1bmRpbmdQdWJLZXksIGRsY0FjY2VwdC5mdW5kaW5nUHViS2V5KSA9PT0gLTFcbiAgICAgICAgPyBbXG4gICAgICAgICAgICBkbGNTaWduLnJlZnVuZFNpZ25hdHVyZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICBkbGNBY2NlcHQucmVmdW5kU2lnbmF0dXJlLnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBdXG4gICAgICAgIDogW1xuICAgICAgICAgICAgZGxjQWNjZXB0LnJlZnVuZFNpZ25hdHVyZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICBkbGNTaWduLnJlZnVuZFNpZ25hdHVyZS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgXTtcblxuICAgIGNvbnN0IGFkZFNpZ3NUb1JlZnVuZFR4UmVxdWVzdDogQWRkU2lnbmF0dXJlc1RvUmVmdW5kVHhSZXF1ZXN0ID0ge1xuICAgICAgcmVmdW5kVHhIZXg6IGRsY1R4cy5yZWZ1bmRUeC5zZXJpYWxpemUoKS50b1N0cmluZygnaGV4JyksXG4gICAgICBzaWduYXR1cmVzLFxuICAgICAgZnVuZFR4SWQ6IGRsY1R4cy5mdW5kVHgudHhJZC50b1N0cmluZygpLFxuICAgICAgZnVuZFZvdXQ6IGRsY1R4cy5mdW5kVHhWb3V0LFxuICAgICAgbG9jYWxGdW5kUHVia2V5OiBkbGNPZmZlci5mdW5kaW5nUHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIHJlbW90ZUZ1bmRQdWJrZXk6IGRsY0FjY2VwdC5mdW5kaW5nUHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVmdW5kSGV4ID0gKFxuICAgICAgYXdhaXQgdGhpcy5BZGRTaWduYXR1cmVzVG9SZWZ1bmRUeChhZGRTaWdzVG9SZWZ1bmRUeFJlcXVlc3QpXG4gICAgKS5oZXg7XG5cbiAgICByZXR1cm4gVHguZGVjb2RlKFN0cmVhbVJlYWRlci5mcm9tSGV4KHJlZnVuZEhleCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdvYWwgb2YgY3JlYXRlRGxjQ2xvc2UgaXMgZm9yIGFsaWNlICh0aGUgaW5pdGlhdG9yKSB0b1xuICAgKiAxLiB0YWtlIGRsY29mZmVyLCBhY2NlcHQsIGFuZCBzaWduIG1lc3NhZ2VzLiBDcmVhdGUgYSBkbGNDbG9zZSBtZXNzYWdlLlxuICAgKiAyLiBCdWlsZCBhIGNsb3NlIHR4LCBzaWduLlxuICAgKiAzLiByZXR1cm4gZGxjQ2xvc2UgbWVzc2FnZSAobm8gcHNidClcbiAgICovXG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIERsY0Nsb3NlIG1lc3NhZ2V0eXBlIGZvciBjbG9zaW5nIERMQyB3aXRoIE11dHVhbCBDb25zZW50XG4gICAqIEBwYXJhbSBfZGxjT2ZmZXIgRGxjT2ZmZXIgVExWIChWMClcbiAgICogQHBhcmFtIF9kbGNBY2NlcHQgRGxjQWNjZXB0IFRMViAoVjApXG4gICAqIEBwYXJhbSBfZGxjVHhzIERsY1RyYW5zYWN0aW9ucyBUTFYgKFYwKVxuICAgKiBAcGFyYW0gaW5pdGlhdG9yUGF5b3V0U2F0b3NoaXMgQW1vdW50IGluaXRpYXRvciBleHBlY3RzIGFzIGEgcGF5b3V0XG4gICAqIEBwYXJhbSBpc09mZmVyZXIgV2hldGhlciBvZmZlcmVyIG9yIG5vdFxuICAgKiBAcGFyYW0gX2lucHV0cyBPcHRpb25hbGx5IHNwZWNpZmllZCBjbG9zaW5nIGlucHV0c1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxEbGNDbG9zZT59XG4gICAqL1xuICBhc3luYyBjcmVhdGVEbGNDbG9zZShcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgICBfZGxjVHhzOiBEbGNUcmFuc2FjdGlvbnMsXG4gICAgaW5pdGlhdG9yUGF5b3V0U2F0b3NoaXM6IGJpZ2ludCxcbiAgICBpc09mZmVyZXI/OiBib29sZWFuLFxuICAgIF9pbnB1dHM/OiBJbnB1dFtdLFxuICApOiBQcm9taXNlPERsY0Nsb3NlPiB7XG4gICAgY29uc3QgeyBkbGNPZmZlciwgZGxjQWNjZXB0LCBkbGNUeHMgfSA9IGNoZWNrVHlwZXMoe1xuICAgICAgX2RsY09mZmVyLFxuICAgICAgX2RsY0FjY2VwdCxcbiAgICAgIF9kbGNUeHMsXG4gICAgfSk7XG5cbiAgICBpZiAoaXNPZmZlcmVyID09PSB1bmRlZmluZWQpXG4gICAgICBpc09mZmVyZXIgPSBhd2FpdCB0aGlzLmlzT2ZmZXJlcihkbGNPZmZlciwgZGxjQWNjZXB0KTtcblxuICAgIGNvbnN0IG5ldHdvcmsgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZE5ldHdvcmsoKTtcbiAgICBjb25zdCBwc2J0ID0gbmV3IFBzYnQoeyBuZXR3b3JrIH0pO1xuXG4gICAgY29uc3QgZnVuZGluZ1B1YktleXMgPVxuICAgICAgQnVmZmVyLmNvbXBhcmUoZGxjT2ZmZXIuZnVuZGluZ1B1YktleSwgZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkpID09PSAtMVxuICAgICAgICA/IFtkbGNPZmZlci5mdW5kaW5nUHViS2V5LCBkbGNBY2NlcHQuZnVuZGluZ1B1YktleV1cbiAgICAgICAgOiBbZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXksIGRsY09mZmVyLmZ1bmRpbmdQdWJLZXldO1xuXG4gICAgY29uc3QgcDJtcyA9IHBheW1lbnRzLnAybXMoe1xuICAgICAgbTogMixcbiAgICAgIHB1YmtleXM6IGZ1bmRpbmdQdWJLZXlzLFxuICAgICAgbmV0d29yayxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBheW1lbnRWYXJpYW50ID0gcGF5bWVudHMucDJ3c2goe1xuICAgICAgcmVkZWVtOiBwMm1zLFxuICAgICAgbmV0d29yayxcbiAgICB9KTtcblxuICAgIC8vIEluaXRpYXRlIGFuZCBidWlsZCBQU0JUXG4gICAgbGV0IGlucHV0czogSW5wdXRbXSA9IF9pbnB1dHM7XG4gICAgaWYgKCFfaW5wdXRzKSB7XG4gICAgICBjb25zdCB0ZW1wSW5wdXRzID0gYXdhaXQgdGhpcy5HZXRJbnB1dHNGb3JBbW91bnQoXG4gICAgICAgIEJpZ0ludCgyMDAwMCksXG4gICAgICAgIGRsY09mZmVyLmZlZVJhdGVQZXJWYixcbiAgICAgICAgX2lucHV0cyxcbiAgICAgICk7XG4gICAgICBfaW5wdXRzID0gdGVtcElucHV0cztcbiAgICB9XG4gICAgaW5wdXRzID0gX2lucHV0cy5tYXAoKGlucHV0KSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5pbnB1dCxcbiAgICAgICAgaW5wdXRTZXJpYWxJZDogaW5wdXQuaW5wdXRTZXJpYWxJZCB8fCBnZW5lcmF0ZVNlcmlhbElkKCksXG4gICAgICAgIHRvVXR4bzogaW5wdXQudG9VdHhvLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHB1YmtleXM6IEJ1ZmZlcltdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBpbnB1dHMubWFwKGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgICBjb25zdCBhZGRyZXNzOiBBZGRyZXNzID0gYXdhaXQgdGhpcy5nZXRNZXRob2QoJ2dldFdhbGxldEFkZHJlc3MnKShcbiAgICAgICAgICBpbnB1dC5hZGRyZXNzLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gQnVmZmVyLmZyb20oYWRkcmVzcy5wdWJsaWNLZXksICdoZXgnKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBmdW5kaW5nSW5wdXRTZXJpYWxJZCA9IGdlbmVyYXRlU2VyaWFsSWQoKTtcblxuICAgIC8vIE1ha2UgdGVtcG9yYXJ5IGFycmF5IHRvIGhvbGQgYWxsIGlucHV0cyBhbmQgdGhlbiBzb3J0IHRoZW1cbiAgICAvLyB0aGlzIG1ldGhvZCBjYW4gYmUgaW1wcm92ZWQgbGF0ZXJcbiAgICBjb25zdCBwc2J0SW5wdXRzID0gW107XG4gICAgcHNidElucHV0cy5wdXNoKHtcbiAgICAgIGhhc2g6IGRsY1R4cy5mdW5kVHgudHhJZC5zZXJpYWxpemUoKSxcbiAgICAgIGluZGV4OiBkbGNUeHMuZnVuZFR4Vm91dCxcbiAgICAgIHNlcXVlbmNlOiAwLFxuICAgICAgd2l0bmVzc1V0eG86IHtcbiAgICAgICAgc2NyaXB0OiBwYXltZW50VmFyaWFudC5vdXRwdXQsXG4gICAgICAgIHZhbHVlOiBOdW1iZXIoZGxjVHhzLmZ1bmRUeC5vdXRwdXRzW2RsY1R4cy5mdW5kVHhWb3V0XS52YWx1ZS5zYXRzKSxcbiAgICAgIH0sXG4gICAgICB3aXRuZXNzU2NyaXB0OiBwYXltZW50VmFyaWFudC5yZWRlZW0ub3V0cHV0LFxuICAgICAgaW5wdXRTZXJpYWxJZDogZnVuZGluZ0lucHV0U2VyaWFsSWQsXG4gICAgICBkZXJpdmF0aW9uUGF0aDogbnVsbCxcbiAgICB9KTtcblxuICAgIC8vIGFkZCBhbGwgZGxjIGNsb3NlIGlucHV0c1xuICAgIGlucHV0cy5mb3JFYWNoKChpbnB1dCwgaSkgPT4ge1xuICAgICAgY29uc3QgcGF5bWVudFZhcmlhbnQgPSBwYXltZW50cy5wMndwa2goeyBwdWJrZXk6IHB1YmtleXNbaV0sIG5ldHdvcmsgfSk7XG5cbiAgICAgIHBzYnRJbnB1dHMucHVzaCh7XG4gICAgICAgIGhhc2g6IGlucHV0LnR4aWQsXG4gICAgICAgIGluZGV4OiBpbnB1dC52b3V0LFxuICAgICAgICBzZXF1ZW5jZTogMCxcbiAgICAgICAgd2l0bmVzc1V0eG86IHtcbiAgICAgICAgICBzY3JpcHQ6IHBheW1lbnRWYXJpYW50Lm91dHB1dCxcbiAgICAgICAgICB2YWx1ZTogaW5wdXQudmFsdWUsXG4gICAgICAgIH0sXG4gICAgICAgIGlucHV0U2VyaWFsSWQ6IGlucHV0LmlucHV0U2VyaWFsSWQsXG4gICAgICAgIGRlcml2YXRpb25QYXRoOiBpbnB1dC5kZXJpdmF0aW9uUGF0aCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gc29ydCBhbGwgaW5wdXRzIGluIGFzY2VuZGluZyBvcmRlciBieSBzZXJpYWwgSURcbiAgICAvLyBUaGUgb25seSByZWFzb24gd2UgYXJlIGRvaW5nIHRoaXMgaXMgZm9yIHByaXZhY3kuIElmIHRoZSBmdW5kaW5nSW5wdXQgaXNcbiAgICAvLyBhbHdheXMgZmlyc3QsIGl0IGlzIHZlcnkgb2J2aW91cy4gSGVuY2UsIGEgc2VyaWFsSWQgaXMgcmFuZG9tbHkgZ2VuZXJhdGVkXG4gICAgLy8gYW5kIHRoZSBpbnB1dHMgYXJlIHNvcnRlZCBieSB0aGF0IGluc3RlYWQuXG4gICAgY29uc3Qgc29ydGVkUHNidElucHV0cyA9IHBzYnRJbnB1dHMuc29ydCgoYSwgYikgPT5cbiAgICAgIE51bWJlcihhLmlucHV0U2VyaWFsSWQgLSBiLmlucHV0U2VyaWFsSWQpLFxuICAgICk7XG5cbiAgICAvLyBHZXQgaW5kZXggb2YgZnVuZGluZ0lucHV0XG4gICAgY29uc3QgZnVuZGluZ0lucHV0SW5kZXggPSBzb3J0ZWRQc2J0SW5wdXRzLmZpbmRJbmRleChcbiAgICAgIChpbnB1dCkgPT4gaW5wdXQuaW5wdXRTZXJpYWxJZCA9PT0gZnVuZGluZ0lucHV0U2VyaWFsSWQsXG4gICAgKTtcblxuICAgIC8vIGFkZCB0byBwc2J0XG4gICAgc29ydGVkUHNidElucHV0cy5mb3JFYWNoKChpbnB1dCwgaSkgPT4gcHNidC5hZGRJbnB1dChpbnB1dCkpO1xuXG4gICAgY29uc3QgZnVuZGluZ0lucHV0czogRnVuZGluZ0lucHV0W10gPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGlucHV0cy5tYXAoYXN5bmMgKGlucHV0KSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0VG9GdW5kaW5nSW5wdXQoaW5wdXQpO1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGNvbnN0IGZpbmFsaXplciA9IG5ldyBEdWFsQ2xvc2luZ1R4RmluYWxpemVyKFxuICAgICAgZnVuZGluZ0lucHV0cyxcbiAgICAgIGRsY09mZmVyLnBheW91dFNQSyxcbiAgICAgIGRsY0FjY2VwdC5wYXlvdXRTUEssXG4gICAgICBkbGNPZmZlci5mZWVSYXRlUGVyVmIsXG4gICAgKTtcblxuICAgIGNvbnN0IGNsb3NlSW5wdXRBbW91bnQgPSBCaWdJbnQoXG4gICAgICBpbnB1dHMucmVkdWNlKChhY2MsIHZhbCkgPT4gYWNjICsgdmFsLnZhbHVlLCAwKSxcbiAgICApO1xuXG4gICAgY29uc3Qgb2ZmZXJQYXlvdXRWYWx1ZTogYmlnaW50ID0gaXNPZmZlcmVyXG4gICAgICA/IGNsb3NlSW5wdXRBbW91bnQgK1xuICAgICAgICBpbml0aWF0b3JQYXlvdXRTYXRvc2hpcyAtXG4gICAgICAgIGZpbmFsaXplci5vZmZlckluaXRpYXRvckZlZXNcbiAgICAgIDogZGxjT2ZmZXIuY29udHJhY3RJbmZvLnRvdGFsQ29sbGF0ZXJhbCAtIGluaXRpYXRvclBheW91dFNhdG9zaGlzO1xuXG4gICAgY29uc3QgYWNjZXB0UGF5b3V0VmFsdWU6IGJpZ2ludCA9IGlzT2ZmZXJlclxuICAgICAgPyBkbGNPZmZlci5jb250cmFjdEluZm8udG90YWxDb2xsYXRlcmFsIC0gaW5pdGlhdG9yUGF5b3V0U2F0b3NoaXNcbiAgICAgIDogY2xvc2VJbnB1dEFtb3VudCArXG4gICAgICAgIGluaXRpYXRvclBheW91dFNhdG9zaGlzIC1cbiAgICAgICAgZmluYWxpemVyLm9mZmVySW5pdGlhdG9yRmVlcztcblxuICAgIGNvbnN0IG9mZmVyRmlyc3QgPSBkbGNPZmZlci5wYXlvdXRTZXJpYWxJZCA8IGRsY0FjY2VwdC5wYXlvdXRTZXJpYWxJZDtcblxuICAgIHBzYnQuYWRkT3V0cHV0KHtcbiAgICAgIHZhbHVlOiBOdW1iZXIob2ZmZXJGaXJzdCA/IG9mZmVyUGF5b3V0VmFsdWUgOiBhY2NlcHRQYXlvdXRWYWx1ZSksXG4gICAgICBhZGRyZXNzOiBhZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQoXG4gICAgICAgIG9mZmVyRmlyc3QgPyBkbGNPZmZlci5wYXlvdXRTUEsgOiBkbGNBY2NlcHQucGF5b3V0U1BLLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIHBzYnQuYWRkT3V0cHV0KHtcbiAgICAgIHZhbHVlOiBOdW1iZXIob2ZmZXJGaXJzdCA/IGFjY2VwdFBheW91dFZhbHVlIDogb2ZmZXJQYXlvdXRWYWx1ZSksXG4gICAgICBhZGRyZXNzOiBhZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQoXG4gICAgICAgIG9mZmVyRmlyc3QgPyBkbGNBY2NlcHQucGF5b3V0U1BLIDogZGxjT2ZmZXIucGF5b3V0U1BLLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIC8vIEdlbmVyYXRlIGtleXBhaXIgdG8gc2lnbiBpbnB1dHNcbiAgICBjb25zdCBmdW5kUHJpdmF0ZUtleVBhaXIgPSBhd2FpdCB0aGlzLkdldEZ1bmRLZXlQYWlyKFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBpc09mZmVyZXIsXG4gICAgKTtcblxuICAgIC8vIFNpZ24gZGxjIGZ1bmRpbmdpbnB1dFxuICAgIHBzYnQuc2lnbklucHV0KGZ1bmRpbmdJbnB1dEluZGV4LCBmdW5kUHJpdmF0ZUtleVBhaXIpO1xuXG4gICAgLy8gU2lnbiBkbGNjbG9zZSBpbnB1dHNcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHNvcnRlZFBzYnRJbnB1dHMubWFwKGFzeW5jIChpbnB1dCwgaSkgPT4ge1xuICAgICAgICBpZiAoaSA9PT0gZnVuZGluZ0lucHV0SW5kZXgpIHJldHVybjtcblxuICAgICAgICAvLyBkZXJpdmUga2V5cGFpclxuICAgICAgICBjb25zdCBrZXlQYWlyID0gYXdhaXQgdGhpcy5nZXRNZXRob2QoJ2tleVBhaXInKShpbnB1dC5kZXJpdmF0aW9uUGF0aCk7XG4gICAgICAgIHBzYnQuc2lnbklucHV0KGksIGtleVBhaXIpO1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIFZhbGlkYXRlIHNpZ25hdHVyZXNcbiAgICBwc2J0LnZhbGlkYXRlU2lnbmF0dXJlc09mQWxsSW5wdXRzKCk7XG5cbiAgICAvLyBFeHRyYWN0IGNsb3NlIHNpZ25hdHVyZSBmcm9tIHBzYnQgYW5kIGRlY29kZSBpdCB0byBvbmx5IGV4dHJhY3QgciBhbmQgcyB2YWx1ZXNcbiAgICBjb25zdCBjbG9zZVNpZ25hdHVyZSA9IGF3YWl0IHNjcmlwdC5zaWduYXR1cmUuZGVjb2RlKFxuICAgICAgcHNidC5kYXRhLmlucHV0c1tmdW5kaW5nSW5wdXRJbmRleF0ucGFydGlhbFNpZ1swXS5zaWduYXR1cmUsXG4gICAgKS5zaWduYXR1cmU7XG5cbiAgICAvLyBFeHRyYWN0IGZ1bmRpbmcgc2lnbmF0dXJlcyBmcm9tIHBzYnRcbiAgICBjb25zdCBpbnB1dFNpZ3MgPSBwc2J0LmRhdGEuaW5wdXRzXG4gICAgICAuZmlsdGVyKChpbnB1dCkgPT4gaW5wdXQgIT09IGZ1bmRpbmdJbnB1dEluZGV4KVxuICAgICAgLm1hcCgoaW5wdXQpID0+IGlucHV0LnBhcnRpYWxTaWdbMF0pO1xuXG4gICAgLy8gY3JlYXRlIGZ1bmRpbmdTaWduYXR1cmVzXG4gICAgY29uc3Qgd2l0bmVzc0VsZW1lbnRzOiBTY3JpcHRXaXRuZXNzVjBbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dFNpZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHNpZ1dpdG5lc3MgPSBuZXcgU2NyaXB0V2l0bmVzc1YwKCk7XG4gICAgICBzaWdXaXRuZXNzLndpdG5lc3MgPSBpbnB1dFNpZ3NbaV0uc2lnbmF0dXJlO1xuICAgICAgY29uc3QgcHViS2V5V2l0bmVzcyA9IG5ldyBTY3JpcHRXaXRuZXNzVjAoKTtcbiAgICAgIHB1YktleVdpdG5lc3Mud2l0bmVzcyA9IGlucHV0U2lnc1tpXS5wdWJrZXk7XG4gICAgICB3aXRuZXNzRWxlbWVudHMucHVzaChbc2lnV2l0bmVzcywgcHViS2V5V2l0bmVzc10pO1xuICAgIH1cbiAgICBjb25zdCBmdW5kaW5nU2lnbmF0dXJlcyA9IG5ldyBGdW5kaW5nU2lnbmF0dXJlc1YwKCk7XG4gICAgZnVuZGluZ1NpZ25hdHVyZXMud2l0bmVzc0VsZW1lbnRzID0gd2l0bmVzc0VsZW1lbnRzO1xuXG4gICAgLy8gQ3JlYXRlIERsY0Nsb3NlXG4gICAgY29uc3QgZGxjQ2xvc2UgPSBuZXcgRGxjQ2xvc2VWMCgpO1xuICAgIGRsY0Nsb3NlLmNvbnRyYWN0SWQgPSBkbGNUeHMuY29udHJhY3RJZDtcbiAgICBkbGNDbG9zZS5vZmZlclBheW91dFNhdG9zaGlzID0gQmlnSW50KFxuICAgICAgcHNidC50eE91dHB1dHNbb2ZmZXJGaXJzdCA/IDAgOiAxXS52YWx1ZSxcbiAgICApOyAvLyBZb3UgZ2l2ZSBjb2xsYXRlcmFsIGJhY2sgdG8gdXNlcnNcbiAgICBkbGNDbG9zZS5hY2NlcHRQYXlvdXRTYXRvc2hpcyA9IEJpZ0ludChcbiAgICAgIHBzYnQudHhPdXRwdXRzW29mZmVyRmlyc3QgPyAxIDogMF0udmFsdWUsXG4gICAgKTsgLy8gZ2l2ZSBjb2xsYXRlcmFsIGJhY2sgdG8gdXNlcnNcbiAgICBkbGNDbG9zZS5mdW5kSW5wdXRTZXJpYWxJZCA9IGZ1bmRpbmdJbnB1dFNlcmlhbElkOyAvLyByYW5kb21seSBnZW5lcmF0ZWQgc2VyaWFsIGlkXG4gICAgZGxjQ2xvc2UuY2xvc2VTaWduYXR1cmUgPSBjbG9zZVNpZ25hdHVyZTtcbiAgICBkbGNDbG9zZS5mdW5kaW5nU2lnbmF0dXJlcyA9IGZ1bmRpbmdTaWduYXR1cmVzO1xuICAgIGRsY0Nsb3NlLmZ1bmRpbmdJbnB1dHMgPSBmdW5kaW5nSW5wdXRzIGFzIEZ1bmRpbmdJbnB1dFYwW107XG4gICAgZGxjQ2xvc2UudmFsaWRhdGUoKTtcblxuICAgIHJldHVybiBkbGNDbG9zZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBtdWx0aXBsZSBEbGNDbG9zZSBtZXNzYWdldHlwZXMgZm9yIGNsb3NpbmcgRExDIHdpdGggTXV0dWFsIENvbnNlbnRcbiAgICogQHBhcmFtIF9kbGNPZmZlciBEbGNPZmZlciBUTFYgKFYwKVxuICAgKiBAcGFyYW0gX2RsY0FjY2VwdCBEbGNBY2NlcHQgVExWIChWMClcbiAgICogQHBhcmFtIF9kbGNUeHMgRGxjVHJhbnNhY3Rpb25zIFRMViAoVjApXG4gICAqIEBwYXJhbSBpbml0aWF0b3JQYXlvdXRzIEFycmF5IG9mIGFtb3VudHMgaW5pdGlhdG9yIGV4cGVjdHMgYXMgcGF5b3V0c1xuICAgKiBAcGFyYW0gaXNPZmZlcmVyIFdoZXRoZXIgb2ZmZXJlciBvciBub3RcbiAgICogQHBhcmFtIF9pbnB1dHMgT3B0aW9uYWxseSBzcGVjaWZpZWQgY2xvc2luZyBpbnB1dHNcbiAgICogQHJldHVybnMge1Byb21pc2U8RGxjQ2xvc2VbXT59XG4gICAqL1xuICBhc3luYyBjcmVhdGVCYXRjaERsY0Nsb3NlKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNUeHM6IERsY1RyYW5zYWN0aW9ucyxcbiAgICBpbml0aWF0b3JQYXlvdXRzOiBiaWdpbnRbXSxcbiAgICBpc09mZmVyZXI/OiBib29sZWFuLFxuICAgIF9pbnB1dHM/OiBJbnB1dFtdLFxuICApOiBQcm9taXNlPERsY0Nsb3NlW10+IHtcbiAgICBjb25zdCB7IGRsY09mZmVyLCBkbGNBY2NlcHQsIGRsY1R4cyB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgICAgX2RsY1R4cyxcbiAgICB9KTtcblxuICAgIGlmIChpc09mZmVyZXIgPT09IHVuZGVmaW5lZClcbiAgICAgIGlzT2ZmZXJlciA9IGF3YWl0IHRoaXMuaXNPZmZlcmVyKGRsY09mZmVyLCBkbGNBY2NlcHQpO1xuXG4gICAgaWYgKF9pbnB1dHMgJiYgX2lucHV0cy5sZW5ndGggPiAwKVxuICAgICAgdGhyb3cgRXJyb3IoJ2Z1bmRpbmcgaW5wdXRzIG5vdCBzdXBwb3J0ZWQgb24gQmF0Y2hEbGNDbG9zZScpOyAvLyBUT0RPIHN1cHBvcnQgbXVsdGlwbGUgZnVuZGluZyBpbnB1dHNcblxuICAgIGNvbnN0IGZ1bmRpbmdJbnB1dFNlcmlhbElkID0gZ2VuZXJhdGVTZXJpYWxJZCgpO1xuXG4gICAgY29uc3QgZnVuZGluZ0lucHV0czogRnVuZGluZ0lucHV0W10gPSBbXTsgLy8gVE9ETzogc3VwcG9ydCBtdWx0aXBsZSBmdW5kaW5nIGlucHV0c1xuXG4gICAgY29uc3QgZmluYWxpemVyID0gbmV3IER1YWxDbG9zaW5nVHhGaW5hbGl6ZXIoXG4gICAgICBmdW5kaW5nSW5wdXRzLFxuICAgICAgZGxjT2ZmZXIucGF5b3V0U1BLLFxuICAgICAgZGxjQWNjZXB0LnBheW91dFNQSyxcbiAgICAgIGRsY09mZmVyLmZlZVJhdGVQZXJWYixcbiAgICApO1xuXG4gICAgLy8gR2VuZXJhdGUga2V5cGFpciB0byBzaWduIGlucHV0c1xuICAgIGNvbnN0IGZ1bmRQcml2YXRlS2V5UGFpciA9IGF3YWl0IHRoaXMuR2V0RnVuZEtleVBhaXIoXG4gICAgICBkbGNPZmZlcixcbiAgICAgIGRsY0FjY2VwdCxcbiAgICAgIGlzT2ZmZXJlcixcbiAgICApO1xuXG4gICAgY29uc3QgY2xvc2VJbnB1dEFtb3VudCA9IEJpZ0ludCgwKTsgLy8gVE9ETyBzdXBwb3J0IG11bHRpcGxlIGZ1bmRpbmcgaW5wdXRzXG5cbiAgICBjb25zdCBwcml2S2V5ID0gQnVmZmVyLmZyb20oZnVuZFByaXZhdGVLZXlQYWlyLnByaXZhdGVLZXkpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgIGNvbnN0IHJhd0Nsb3NlVHhzID0gYXdhaXQgdGhpcy5DcmVhdGVDbG9zZVJhd1R4cyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgZGxjVHhzLFxuICAgICAgY2xvc2VJbnB1dEFtb3VudCxcbiAgICAgIGlzT2ZmZXJlcixcbiAgICAgIFtdLFxuICAgICAgZnVuZGluZ0lucHV0cyxcbiAgICAgIGluaXRpYXRvclBheW91dHMsXG4gICAgKTtcblxuICAgIGNvbnN0IHNpZ0hhc2hlcyA9IGF3YWl0IHRoaXMuQ3JlYXRlU2lnbmF0dXJlSGFzaGVzKFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBkbGNUeHMsXG4gICAgICByYXdDbG9zZVR4cyxcbiAgICApO1xuXG4gICAgY29uc3Qgc2lnbmF0dXJlcyA9IGF3YWl0IHRoaXMuQ2FsY3VsYXRlRWNTaWduYXR1cmVIYXNoZXMoXG4gICAgICBzaWdIYXNoZXMsXG4gICAgICBwcml2S2V5LFxuICAgICk7XG5cbiAgICBjb25zdCBkbGNDbG9zZXMgPSBbXTtcblxuICAgIHNpZ25hdHVyZXMuZm9yRWFjaCgoc2lnLCBpKSA9PiB7XG4gICAgICBjb25zdCBwYXlvdXQgPSBpbml0aWF0b3JQYXlvdXRzW2ldO1xuICAgICAgY29uc3QgcGF5b3V0TWludXNPZmZlckZlZXMgPVxuICAgICAgICBmaW5hbGl6ZXIub2ZmZXJJbml0aWF0b3JGZWVzID4gcGF5b3V0XG4gICAgICAgICAgPyBCaWdJbnQoMClcbiAgICAgICAgICA6IHBheW91dCAtIGZpbmFsaXplci5vZmZlckluaXRpYXRvckZlZXM7XG4gICAgICBjb25zdCBjb2xsYXRlcmFsTWludXNQYXlvdXQgPVxuICAgICAgICBwYXlvdXQgPiBkbGNPZmZlci5jb250cmFjdEluZm8udG90YWxDb2xsYXRlcmFsXG4gICAgICAgICAgPyBCaWdJbnQoMClcbiAgICAgICAgICA6IGRsY09mZmVyLmNvbnRyYWN0SW5mby50b3RhbENvbGxhdGVyYWwgLSBwYXlvdXQ7XG5cbiAgICAgIGNvbnN0IG9mZmVyUGF5b3V0VmFsdWU6IGJpZ2ludCA9IGlzT2ZmZXJlclxuICAgICAgICA/IGNsb3NlSW5wdXRBbW91bnQgKyBwYXlvdXRNaW51c09mZmVyRmVlc1xuICAgICAgICA6IGNvbGxhdGVyYWxNaW51c1BheW91dDtcblxuICAgICAgY29uc3QgYWNjZXB0UGF5b3V0VmFsdWU6IGJpZ2ludCA9IGlzT2ZmZXJlclxuICAgICAgICA/IGNvbGxhdGVyYWxNaW51c1BheW91dFxuICAgICAgICA6IGNsb3NlSW5wdXRBbW91bnQgKyBwYXlvdXRNaW51c09mZmVyRmVlcztcblxuICAgICAgY29uc3QgZnVuZGluZ1NpZ25hdHVyZXMgPSBuZXcgRnVuZGluZ1NpZ25hdHVyZXNWMCgpO1xuXG4gICAgICBjb25zdCBkbGNDbG9zZSA9IG5ldyBEbGNDbG9zZVYwKCk7XG4gICAgICBkbGNDbG9zZS5jb250cmFjdElkID0gZGxjVHhzLmNvbnRyYWN0SWQ7XG4gICAgICBkbGNDbG9zZS5vZmZlclBheW91dFNhdG9zaGlzID0gb2ZmZXJQYXlvdXRWYWx1ZTtcbiAgICAgIGRsY0Nsb3NlLmFjY2VwdFBheW91dFNhdG9zaGlzID0gYWNjZXB0UGF5b3V0VmFsdWU7XG4gICAgICBkbGNDbG9zZS5mdW5kSW5wdXRTZXJpYWxJZCA9IGZ1bmRpbmdJbnB1dFNlcmlhbElkO1xuICAgICAgZGxjQ2xvc2UuY2xvc2VTaWduYXR1cmUgPSBCdWZmZXIuZnJvbShzaWcsICdoZXgnKTtcbiAgICAgIGRsY0Nsb3NlLmZ1bmRpbmdTaWduYXR1cmVzID0gZnVuZGluZ1NpZ25hdHVyZXM7XG4gICAgICBkbGNDbG9zZS52YWxpZGF0ZSgpO1xuXG4gICAgICBkbGNDbG9zZXMucHVzaChkbGNDbG9zZSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGxjQ2xvc2VzO1xuICB9XG5cbiAgYXN5bmMgdmVyaWZ5QmF0Y2hEbGNDbG9zZVVzaW5nTWV0YWRhdGEoXG4gICAgZGxjQ2xvc2VNZXRhZGF0YTogRGxjQ2xvc2VNZXRhZGF0YSxcbiAgICBfZGxjQ2xvc2VzOiBEbGNDbG9zZVtdLFxuICAgIGlzT2ZmZXJlcj86IGJvb2xlYW4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjVHhzIH0gPSBkbGNDbG9zZU1ldGFkYXRhLnRvRGxjTWVzc2FnZXMoKTtcblxuICAgIGF3YWl0IHRoaXMudmVyaWZ5QmF0Y2hEbGNDbG9zZShcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgZGxjVHhzLFxuICAgICAgX2RsY0Nsb3NlcyxcbiAgICAgIGlzT2ZmZXJlcixcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSBtdWx0aXBsZSBEbGNDbG9zZSBtZXNzYWdldHlwZXMgZm9yIGNsb3NpbmcgRExDIHdpdGggTXV0dWFsIENvbnNlbnRcbiAgICogQHBhcmFtIF9kbGNPZmZlciBEbGNPZmZlciBUTFYgKFYwKVxuICAgKiBAcGFyYW0gX2RsY0FjY2VwdCBEbGNBY2NlcHQgVExWIChWMClcbiAgICogQHBhcmFtIF9kbGNUeHMgRGxjVHJhbnNhY3Rpb25zIFRMViAoVjApXG4gICAqIEBwYXJhbSBfZGxjQ2xvc2VzIERsY0Nsb3NlW10gVExWIChWMClcbiAgICogQHBhcmFtIGlzT2ZmZXJlciBXaGV0aGVyIG9mZmVyZXIgb3Igbm90XG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgdmVyaWZ5QmF0Y2hEbGNDbG9zZShcbiAgICBfZGxjT2ZmZXI6IERsY09mZmVyLFxuICAgIF9kbGNBY2NlcHQ6IERsY0FjY2VwdCxcbiAgICBfZGxjVHhzOiBEbGNUcmFuc2FjdGlvbnMsXG4gICAgX2RsY0Nsb3NlczogRGxjQ2xvc2VbXSxcbiAgICBpc09mZmVyZXI/OiBib29sZWFuLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGRsY09mZmVyLCBkbGNBY2NlcHQsIGRsY1R4cyB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgICAgX2RsY1R4cyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRsY0Nsb3NlcyA9IF9kbGNDbG9zZXMubWFwKFxuICAgICAgKF9kbGNDbG9zZSkgPT4gY2hlY2tUeXBlcyh7IF9kbGNDbG9zZSB9KS5kbGNDbG9zZSxcbiAgICApO1xuXG4gICAgaWYgKGlzT2ZmZXJlciA9PT0gdW5kZWZpbmVkKVxuICAgICAgaXNPZmZlcmVyID0gYXdhaXQgdGhpcy5pc09mZmVyZXIoZGxjT2ZmZXIsIGRsY0FjY2VwdCk7XG5cbiAgICBhc3NlcnQoXG4gICAgICBkbGNDbG9zZXMuZXZlcnkoKGRsY0Nsb3NlKSA9PiBkbGNDbG9zZS5mdW5kaW5nSW5wdXRzLmxlbmd0aCA9PT0gMCksXG4gICAgICAnZnVuZGluZyBpbnB1dHMgbm90IHN1cHBvcnRlZCBvbiB2ZXJpZnkgQmF0Y2hEbGNDbG9zZScsXG4gICAgKTsgLy8gVE9ETyBzdXBwb3J0IG11bHRpcGxlIGZ1bmRpbmcgaW5wdXRzXG5cbiAgICBjb25zdCBjbG9zZUlucHV0QW1vdW50ID0gQmlnSW50KDApOyAvLyBUT0RPIHN1cHBvcnQgbXVsdGlwbGUgZnVuZGluZyBpbnB1dHNcblxuICAgIGNvbnN0IHJhd0Nsb3NlVHhzID0gYXdhaXQgdGhpcy5DcmVhdGVDbG9zZVJhd1R4cyhcbiAgICAgIGRsY09mZmVyLFxuICAgICAgZGxjQWNjZXB0LFxuICAgICAgZGxjVHhzLFxuICAgICAgY2xvc2VJbnB1dEFtb3VudCxcbiAgICAgIGlzT2ZmZXJlcixcbiAgICAgIGRsY0Nsb3NlcyxcbiAgICApO1xuXG4gICAgY29uc3QgYXJlU2lnc1ZhbGlkID0gYXdhaXQgdGhpcy5WZXJpZnlTaWduYXR1cmVzKFxuICAgICAgZGxjT2ZmZXIsXG4gICAgICBkbGNBY2NlcHQsXG4gICAgICBkbGNUeHMsXG4gICAgICBkbGNDbG9zZXMsXG4gICAgICByYXdDbG9zZVR4cyxcbiAgICAgIGlzT2ZmZXJlcixcbiAgICApO1xuXG4gICAgYXNzZXJ0KGFyZVNpZ3NWYWxpZCwgJ1NpZ25hdHVyZXMgaW52YWxpZCBpbiBWZXJpZnkgQmF0Y2ggRGxjQ2xvc2UnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHb2FsIG9mIGZpbmFsaXplIERsYyBDbG9zZSBpcyBmb3IgYm9iIHRvXG4gICAqIDEuIHRha2UgdGhlIGRsY0Nsb3NlIGNyZWF0ZWQgYnkgYWxpY2UgdXNpbmcgY3JlYXRlRGxjQ2xvc2UsXG4gICAqIDIuIEJ1aWxkIGEgcHNidCB1c2luZyBBbGljZSdzIGRsY0Nsb3NlIG1lc3NhZ2VcbiAgICogMy4gU2lnbiBwc2J0IHdpdGggYm9iJ3MgcHJpdmtleVxuICAgKiA0LiByZXR1cm4gYSB0eCByZWFkeSB0byBiZSBicm9hZGNhc3RcbiAgICovXG5cbiAgLyoqXG4gICAqIEZpbmFsaXplIERsYyBDbG9zZVxuICAgKiBAcGFyYW0gX2RsY09mZmVyIERsYyBPZmZlciBNZXNzYWdlXG4gICAqIEBwYXJhbSBfZGxjQWNjZXB0IERsYyBBY2NlcHQgTWVzc2FnZVxuICAgKiBAcGFyYW0gX2RsY0Nsb3NlIERsYyBDbG9zZSBNZXNzYWdlXG4gICAqIEBwYXJhbSBfZGxjVHhzIERsYyBUcmFuc2FjdGlvbnMgTWVzc2FnZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUeD59XG4gICAqL1xuICBhc3luYyBmaW5hbGl6ZURsY0Nsb3NlKFxuICAgIF9kbGNPZmZlcjogRGxjT2ZmZXIsXG4gICAgX2RsY0FjY2VwdDogRGxjQWNjZXB0LFxuICAgIF9kbGNDbG9zZTogRGxjQ2xvc2UsXG4gICAgX2RsY1R4czogRGxjVHJhbnNhY3Rpb25zLFxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHsgZGxjT2ZmZXIsIGRsY0FjY2VwdCwgZGxjQ2xvc2UsIGRsY1R4cyB9ID0gY2hlY2tUeXBlcyh7XG4gICAgICBfZGxjT2ZmZXIsXG4gICAgICBfZGxjQWNjZXB0LFxuICAgICAgX2RsY0Nsb3NlLFxuICAgICAgX2RsY1R4cyxcbiAgICB9KTtcblxuICAgIGRsY09mZmVyLnZhbGlkYXRlKCk7XG4gICAgZGxjQWNjZXB0LnZhbGlkYXRlKCk7XG4gICAgZGxjQ2xvc2UudmFsaWRhdGUoKTtcblxuICAgIGNvbnN0IG5ldHdvcmsgPSBhd2FpdCB0aGlzLmdldENvbm5lY3RlZE5ldHdvcmsoKTtcbiAgICBjb25zdCBwc2J0ID0gbmV3IFBzYnQoeyBuZXR3b3JrIH0pO1xuXG4gICAgY29uc3QgZnVuZGluZ1B1YktleXMgPVxuICAgICAgQnVmZmVyLmNvbXBhcmUoZGxjT2ZmZXIuZnVuZGluZ1B1YktleSwgZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkpID09PSAtMVxuICAgICAgICA/IFtkbGNPZmZlci5mdW5kaW5nUHViS2V5LCBkbGNBY2NlcHQuZnVuZGluZ1B1YktleV1cbiAgICAgICAgOiBbZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXksIGRsY09mZmVyLmZ1bmRpbmdQdWJLZXldO1xuXG4gICAgY29uc3QgcDJtcyA9IHBheW1lbnRzLnAybXMoe1xuICAgICAgbTogMixcbiAgICAgIHB1YmtleXM6IGZ1bmRpbmdQdWJLZXlzLFxuICAgICAgbmV0d29yayxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBheW1lbnRWYXJpYW50ID0gcGF5bWVudHMucDJ3c2goe1xuICAgICAgcmVkZWVtOiBwMm1zLFxuICAgICAgbmV0d29yayxcbiAgICB9KTtcblxuICAgIC8vIE1ha2UgdGVtcG9yYXJ5IGFycmF5IHRvIGhvbGQgYWxsIGlucHV0cyBhbmQgdGhlbiBzb3J0IHRoZW1cbiAgICAvLyB0aGlzIG1ldGhvZCBjYW4gYmUgaW1wcm92ZWQgbGF0ZXJcbiAgICBjb25zdCBwc2J0SW5wdXRzID0gW107XG4gICAgcHNidElucHV0cy5wdXNoKHtcbiAgICAgIGhhc2g6IGRsY1R4cy5mdW5kVHgudHhJZC5zZXJpYWxpemUoKSxcbiAgICAgIGluZGV4OiBkbGNUeHMuZnVuZFR4Vm91dCxcbiAgICAgIHNlcXVlbmNlOiAwLFxuICAgICAgd2l0bmVzc1V0eG86IHtcbiAgICAgICAgc2NyaXB0OiBwYXltZW50VmFyaWFudC5vdXRwdXQsXG4gICAgICAgIHZhbHVlOiBOdW1iZXIoZGxjVHhzLmZ1bmRUeC5vdXRwdXRzW2RsY1R4cy5mdW5kVHhWb3V0XS52YWx1ZS5zYXRzKSxcbiAgICAgIH0sXG4gICAgICB3aXRuZXNzU2NyaXB0OiBwYXltZW50VmFyaWFudC5yZWRlZW0ub3V0cHV0LFxuICAgICAgaW5wdXRTZXJpYWxJZDogZGxjQ2xvc2UuZnVuZElucHV0U2VyaWFsSWQsXG4gICAgfSk7XG5cbiAgICAvLyBhZGQgYWxsIGRsYyBjbG9zZSBpbnB1dHNcbiAgICBkbGNDbG9zZS5mdW5kaW5nSW5wdXRzLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgICBwc2J0SW5wdXRzLnB1c2goe1xuICAgICAgICBoYXNoOiBpbnB1dC5wcmV2VHgudHhJZC5zZXJpYWxpemUoKSxcbiAgICAgICAgaW5kZXg6IGlucHV0LnByZXZUeFZvdXQsXG4gICAgICAgIHNlcXVlbmNlOiAwLFxuICAgICAgICB3aXRuZXNzVXR4bzoge1xuICAgICAgICAgIHNjcmlwdDogaW5wdXQucHJldlR4Lm91dHB1dHNbaW5wdXQucHJldlR4Vm91dF0uc2NyaXB0UHViS2V5XG4gICAgICAgICAgICAuc2VyaWFsaXplKClcbiAgICAgICAgICAgIC5zbGljZSgxKSxcbiAgICAgICAgICB2YWx1ZTogTnVtYmVyKGlucHV0LnByZXZUeC5vdXRwdXRzW2lucHV0LnByZXZUeFZvdXRdLnZhbHVlLnNhdHMpLFxuICAgICAgICB9LFxuICAgICAgICBpbnB1dFNlcmlhbElkOiBpbnB1dC5pbnB1dFNlcmlhbElkLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBzb3J0IGFsbCBpbnB1dHMgaW4gYXNjZW5kaW5nIG9yZGVyIGJ5IHNlcmlhbCBJRFxuICAgIC8vIFRoZSBvbmx5IHJlYXNvbiB3ZSBhcmUgZG9pbmcgdGhpcyBpcyBmb3IgcHJpdmFjeS4gSWYgdGhlIGZ1bmRpbmdJbnB1dCBpc1xuICAgIC8vIGFsd2F5cyBmaXJzdCwgaXQgaXMgdmVyeSBvYnZpb3VzLiBIZW5jZSwgYSBzZXJpYWxJZCBpcyByYW5kb21seSBnZW5lcmF0ZWRcbiAgICAvLyBhbmQgdGhlIGlucHV0cyBhcmUgc29ydGVkIGJ5IHRoYXQgaW5zdGVhZC5cbiAgICBjb25zdCBzb3J0ZWRQc2J0SW5wdXRzID0gcHNidElucHV0cy5zb3J0KChhLCBiKSA9PlxuICAgICAgTnVtYmVyKGEuaW5wdXRTZXJpYWxJZCAtIGIuaW5wdXRTZXJpYWxJZCksXG4gICAgKTtcblxuICAgIC8vIEdldCBpbmRleCBvZiBmdW5kaW5nSW5wdXRcbiAgICBjb25zdCBmdW5kaW5nSW5wdXRJbmRleCA9IHNvcnRlZFBzYnRJbnB1dHMuZmluZEluZGV4KFxuICAgICAgKGlucHV0KSA9PiBpbnB1dC5pbnB1dFNlcmlhbElkID09PSBkbGNDbG9zZS5mdW5kSW5wdXRTZXJpYWxJZCxcbiAgICApO1xuXG4gICAgY29uc3Qgb2ZmZXJGaXJzdCA9IGRsY09mZmVyLnBheW91dFNlcmlhbElkIDwgZGxjQWNjZXB0LnBheW91dFNlcmlhbElkO1xuXG4gICAgcHNidC5hZGRPdXRwdXQoe1xuICAgICAgdmFsdWU6IE51bWJlcihcbiAgICAgICAgb2ZmZXJGaXJzdFxuICAgICAgICAgID8gZGxjQ2xvc2Uub2ZmZXJQYXlvdXRTYXRvc2hpc1xuICAgICAgICAgIDogZGxjQ2xvc2UuYWNjZXB0UGF5b3V0U2F0b3NoaXMsXG4gICAgICApLFxuICAgICAgYWRkcmVzczogYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KFxuICAgICAgICBvZmZlckZpcnN0ID8gZGxjT2ZmZXIucGF5b3V0U1BLIDogZGxjQWNjZXB0LnBheW91dFNQSyxcbiAgICAgICAgbmV0d29yayxcbiAgICAgICksXG4gICAgfSk7XG5cbiAgICBwc2J0LmFkZE91dHB1dCh7XG4gICAgICB2YWx1ZTogTnVtYmVyKFxuICAgICAgICBvZmZlckZpcnN0XG4gICAgICAgICAgPyBkbGNDbG9zZS5hY2NlcHRQYXlvdXRTYXRvc2hpc1xuICAgICAgICAgIDogZGxjQ2xvc2Uub2ZmZXJQYXlvdXRTYXRvc2hpcyxcbiAgICAgICksXG4gICAgICBhZGRyZXNzOiBhZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQoXG4gICAgICAgIG9mZmVyRmlyc3QgPyBkbGNBY2NlcHQucGF5b3V0U1BLIDogZGxjT2ZmZXIucGF5b3V0U1BLLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgKSxcbiAgICB9KTtcblxuICAgIC8vIGFkZCB0byBwc2J0XG4gICAgc29ydGVkUHNidElucHV0cy5mb3JFYWNoKChpbnB1dCwgaSkgPT4gcHNidC5hZGRJbnB1dChpbnB1dCkpO1xuXG4gICAgY29uc3Qgb2ZmZXJlciA9IGF3YWl0IHRoaXMuaXNPZmZlcmVyKGRsY09mZmVyLCBkbGNBY2NlcHQpO1xuXG4gICAgLy8gR2VuZXJhdGUga2V5cGFpciB0byBzaWduIGlucHV0c1xuICAgIGNvbnN0IGZ1bmRQcml2YXRlS2V5UGFpciA9IGF3YWl0IHRoaXMuR2V0RnVuZEtleVBhaXIoXG4gICAgICBkbGNPZmZlcixcbiAgICAgIGRsY0FjY2VwdCxcbiAgICAgIG9mZmVyZXIsXG4gICAgKTtcblxuICAgIC8vIFNpZ24gZGxjIGZ1bmRpbmdpbnB1dFxuICAgIHBzYnQuc2lnbklucHV0KGZ1bmRpbmdJbnB1dEluZGV4LCBmdW5kUHJpdmF0ZUtleVBhaXIpO1xuXG4gICAgY29uc3QgcGFydGlhbFNpZyA9IFtcbiAgICAgIHtcbiAgICAgICAgcHVia2V5OiBvZmZlcmVyID8gZGxjQWNjZXB0LmZ1bmRpbmdQdWJLZXkgOiBkbGNPZmZlci5mdW5kaW5nUHViS2V5LFxuICAgICAgICBzaWduYXR1cmU6IGF3YWl0IHNjcmlwdC5zaWduYXR1cmUuZW5jb2RlKGRsY0Nsb3NlLmNsb3NlU2lnbmF0dXJlLCAxKSwgLy8gZW5jb2RlIHVzaW5nIFNJR0hBU0hfQUxMXG4gICAgICB9LFxuICAgIF07XG4gICAgcHNidC51cGRhdGVJbnB1dChmdW5kaW5nSW5wdXRJbmRleCwgeyBwYXJ0aWFsU2lnIH0pO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoaSA9PT0gZnVuZGluZ0lucHV0SW5kZXgpIGNvbnRpbnVlO1xuICAgICAgaWYgKCFwc2J0LmRhdGEuaW5wdXRzW2ldLnBhcnRpYWxTaWcpIHBzYnQuZGF0YS5pbnB1dHNbaV0ucGFydGlhbFNpZyA9IFtdO1xuXG4gICAgICBjb25zdCB3aXRuZXNzSSA9IGRsY0Nsb3NlLmZ1bmRpbmdTaWduYXR1cmVzLndpdG5lc3NFbGVtZW50cy5maW5kSW5kZXgoXG4gICAgICAgIChlbCkgPT5cbiAgICAgICAgICBCdWZmZXIuY29tcGFyZShcbiAgICAgICAgICAgIFNjcmlwdC5wMndwa2hMb2NrKGhhc2gxNjAoZWxbMV0ud2l0bmVzcykpLnNlcmlhbGl6ZSgpLnNsaWNlKDEpLFxuICAgICAgICAgICAgcHNidC5kYXRhLmlucHV0c1tpXS53aXRuZXNzVXR4by5zY3JpcHQsXG4gICAgICAgICAgKSA9PT0gMCxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHBhcnRpYWxTaWcgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBwdWJrZXk6XG4gICAgICAgICAgICBkbGNDbG9zZS5mdW5kaW5nU2lnbmF0dXJlcy53aXRuZXNzRWxlbWVudHNbd2l0bmVzc0ldWzFdLndpdG5lc3MsXG4gICAgICAgICAgc2lnbmF0dXJlOlxuICAgICAgICAgICAgZGxjQ2xvc2UuZnVuZGluZ1NpZ25hdHVyZXMud2l0bmVzc0VsZW1lbnRzW3dpdG5lc3NJXVswXS53aXRuZXNzLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgcHNidC51cGRhdGVJbnB1dChpLCB7IHBhcnRpYWxTaWcgfSk7XG4gICAgfVxuXG4gICAgcHNidC52YWxpZGF0ZVNpZ25hdHVyZXNPZkFsbElucHV0cygpO1xuICAgIHBzYnQuZmluYWxpemVBbGxJbnB1dHMoKTtcblxuICAgIHJldHVybiBwc2J0LmV4dHJhY3RUcmFuc2FjdGlvbigpLnRvSGV4KCk7XG4gIH1cblxuICBhc3luYyBBZGRTaWduYXR1cmVUb0Z1bmRUcmFuc2FjdGlvbihcbiAgICBqc29uT2JqZWN0OiBBZGRTaWduYXR1cmVUb0Z1bmRUcmFuc2FjdGlvblJlcXVlc3QsXG4gICk6IFByb21pc2U8QWRkU2lnbmF0dXJlVG9GdW5kVHJhbnNhY3Rpb25SZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuQWRkU2lnbmF0dXJlVG9GdW5kVHJhbnNhY3Rpb24oanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBDcmVhdGVDZXRBZGFwdG9yU2lnbmF0dXJlKFxuICAgIGpzb25PYmplY3Q6IENyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmVSZXF1ZXN0LFxuICApOiBQcm9taXNlPENyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmVSZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuQ3JlYXRlQ2V0QWRhcHRvclNpZ25hdHVyZShqc29uT2JqZWN0KTtcbiAgfVxuXG4gIGFzeW5jIENyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmVzKFxuICAgIGpzb25PYmplY3Q6IENyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmVzUmVxdWVzdCxcbiAgKTogUHJvbWlzZTxDcmVhdGVDZXRBZGFwdG9yU2lnbmF0dXJlc1Jlc3BvbnNlPiB7XG4gICAgYXdhaXQgdGhpcy5DZmRMb2FkZWQoKTtcblxuICAgIHJldHVybiB0aGlzLl9jZmREbGNKcy5DcmVhdGVDZXRBZGFwdG9yU2lnbmF0dXJlcyhqc29uT2JqZWN0KTtcbiAgfVxuXG4gIGFzeW5jIEFkZFNpZ25hdHVyZXNUb1JlZnVuZFR4KFxuICAgIGpzb25PYmplY3Q6IEFkZFNpZ25hdHVyZXNUb1JlZnVuZFR4UmVxdWVzdCxcbiAgKTogUHJvbWlzZTxBZGRTaWduYXR1cmVzVG9SZWZ1bmRUeFJlc3BvbnNlPiB7XG4gICAgYXdhaXQgdGhpcy5DZmRMb2FkZWQoKTtcblxuICAgIHJldHVybiB0aGlzLl9jZmREbGNKcy5BZGRTaWduYXR1cmVzVG9SZWZ1bmRUeChqc29uT2JqZWN0KTtcbiAgfVxuXG4gIGFzeW5jIENyZWF0ZUNldChqc29uT2JqZWN0OiBDcmVhdGVDZXRSZXF1ZXN0KTogUHJvbWlzZTxDcmVhdGVDZXRSZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuQ3JlYXRlQ2V0KGpzb25PYmplY3QpO1xuICB9XG5cbiAgYXN5bmMgQ3JlYXRlRGxjVHJhbnNhY3Rpb25zKFxuICAgIGpzb25PYmplY3Q6IENyZWF0ZURsY1RyYW5zYWN0aW9uc1JlcXVlc3QsXG4gICk6IFByb21pc2U8Q3JlYXRlRGxjVHJhbnNhY3Rpb25zUmVzcG9uc2U+IHtcbiAgICBhd2FpdCB0aGlzLkNmZExvYWRlZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NmZERsY0pzLkNyZWF0ZURsY1RyYW5zYWN0aW9ucyhqc29uT2JqZWN0KTtcbiAgfVxuXG4gIGFzeW5jIENyZWF0ZUZ1bmRUcmFuc2FjdGlvbihcbiAgICBqc29uT2JqZWN0OiBDcmVhdGVGdW5kVHJhbnNhY3Rpb25SZXF1ZXN0LFxuICApOiBQcm9taXNlPENyZWF0ZUZ1bmRUcmFuc2FjdGlvblJlc3BvbnNlPiB7XG4gICAgYXdhaXQgdGhpcy5DZmRMb2FkZWQoKTtcblxuICAgIHJldHVybiB0aGlzLl9jZmREbGNKcy5DcmVhdGVGdW5kVHJhbnNhY3Rpb24oanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBDcmVhdGVSZWZ1bmRUcmFuc2FjdGlvbihcbiAgICBqc29uT2JqZWN0OiBDcmVhdGVSZWZ1bmRUcmFuc2FjdGlvblJlcXVlc3QsXG4gICk6IFByb21pc2U8Q3JlYXRlUmVmdW5kVHJhbnNhY3Rpb25SZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuQ3JlYXRlUmVmdW5kVHJhbnNhY3Rpb24oanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBHZXRSYXdGdW5kVHhTaWduYXR1cmUoXG4gICAganNvbk9iamVjdDogR2V0UmF3RnVuZFR4U2lnbmF0dXJlUmVxdWVzdCxcbiAgKTogUHJvbWlzZTxHZXRSYXdGdW5kVHhTaWduYXR1cmVSZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuR2V0UmF3RnVuZFR4U2lnbmF0dXJlKGpzb25PYmplY3QpO1xuICB9XG5cbiAgYXN5bmMgR2V0UmF3UmVmdW5kVHhTaWduYXR1cmUoXG4gICAganNvbk9iamVjdDogR2V0UmF3UmVmdW5kVHhTaWduYXR1cmVSZXF1ZXN0LFxuICApOiBQcm9taXNlPEdldFJhd1JlZnVuZFR4U2lnbmF0dXJlUmVzcG9uc2U+IHtcbiAgICBhd2FpdCB0aGlzLkNmZExvYWRlZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NmZERsY0pzLkdldFJhd1JlZnVuZFR4U2lnbmF0dXJlKGpzb25PYmplY3QpO1xuICB9XG5cbiAgYXN5bmMgU2lnbkNldChqc29uT2JqZWN0OiBTaWduQ2V0UmVxdWVzdCk6IFByb21pc2U8U2lnbkNldFJlc3BvbnNlPiB7XG4gICAgYXdhaXQgdGhpcy5DZmRMb2FkZWQoKTtcblxuICAgIHJldHVybiB0aGlzLl9jZmREbGNKcy5TaWduQ2V0KGpzb25PYmplY3QpO1xuICB9XG5cbiAgYXN5bmMgVmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZShcbiAgICBqc29uT2JqZWN0OiBWZXJpZnlDZXRBZGFwdG9yU2lnbmF0dXJlUmVxdWVzdCxcbiAgKTogUHJvbWlzZTxWZXJpZnlDZXRBZGFwdG9yU2lnbmF0dXJlUmVzcG9uc2U+IHtcbiAgICBhd2FpdCB0aGlzLkNmZExvYWRlZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NmZERsY0pzLlZlcmlmeUNldEFkYXB0b3JTaWduYXR1cmUoanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBWZXJpZnlDZXRBZGFwdG9yU2lnbmF0dXJlcyhcbiAgICBqc29uT2JqZWN0OiBWZXJpZnlDZXRBZGFwdG9yU2lnbmF0dXJlc1JlcXVlc3QsXG4gICk6IFByb21pc2U8VmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZXNSZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuVmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZXMoanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBTaWduRnVuZFRyYW5zYWN0aW9uKFxuICAgIGpzb25PYmplY3Q6IFNpZ25GdW5kVHJhbnNhY3Rpb25SZXF1ZXN0LFxuICApOiBQcm9taXNlPFNpZ25GdW5kVHJhbnNhY3Rpb25SZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuU2lnbkZ1bmRUcmFuc2FjdGlvbihqc29uT2JqZWN0KTtcbiAgfVxuXG4gIGFzeW5jIFZlcmlmeUZ1bmRUeFNpZ25hdHVyZShcbiAgICBqc29uT2JqZWN0OiBWZXJpZnlGdW5kVHhTaWduYXR1cmVSZXF1ZXN0LFxuICApOiBQcm9taXNlPFZlcmlmeUZ1bmRUeFNpZ25hdHVyZVJlc3BvbnNlPiB7XG4gICAgYXdhaXQgdGhpcy5DZmRMb2FkZWQoKTtcblxuICAgIHJldHVybiB0aGlzLl9jZmREbGNKcy5WZXJpZnlGdW5kVHhTaWduYXR1cmUoanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBWZXJpZnlSZWZ1bmRUeFNpZ25hdHVyZShcbiAgICBqc29uT2JqZWN0OiBWZXJpZnlSZWZ1bmRUeFNpZ25hdHVyZVJlcXVlc3QsXG4gICk6IFByb21pc2U8VmVyaWZ5UmVmdW5kVHhTaWduYXR1cmVSZXNwb25zZT4ge1xuICAgIGF3YWl0IHRoaXMuQ2ZkTG9hZGVkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2ZkRGxjSnMuVmVyaWZ5UmVmdW5kVHhTaWduYXR1cmUoanNvbk9iamVjdCk7XG4gIH1cblxuICBhc3luYyBmdW5kaW5nSW5wdXRUb0lucHV0KFxuICAgIF9pbnB1dDogRnVuZGluZ0lucHV0LFxuICAgIGZpbmREZXJpdmF0aW9uUGF0aCA9IHRydWUsXG4gICk6IFByb21pc2U8SW5wdXQ+IHtcbiAgICBhc3NlcnQoXG4gICAgICBfaW5wdXQudHlwZSA9PT0gTWVzc2FnZVR5cGUuRnVuZGluZ0lucHV0VjAsXG4gICAgICAnRnVuZGluZ0lucHV0IG11c3QgYmUgVjAnLFxuICAgICk7XG4gICAgY29uc3QgbmV0d29yayA9IGF3YWl0IHRoaXMuZ2V0Q29ubmVjdGVkTmV0d29yaygpO1xuICAgIGNvbnN0IGlucHV0ID0gX2lucHV0IGFzIEZ1bmRpbmdJbnB1dFYwO1xuICAgIGNvbnN0IHByZXZUeCA9IGlucHV0LnByZXZUeDtcbiAgICBjb25zdCBwcmV2VHhPdXQgPSBwcmV2VHgub3V0cHV0c1tpbnB1dC5wcmV2VHhWb3V0XTtcbiAgICBjb25zdCBzY3JpcHRQdWJLZXkgPSBwcmV2VHhPdXQuc2NyaXB0UHViS2V5LnNlcmlhbGl6ZSgpLnNsaWNlKDEpO1xuICAgIGNvbnN0IF9hZGRyZXNzID0gYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHNjcmlwdFB1YktleSwgbmV0d29yayk7XG4gICAgbGV0IGRlcml2YXRpb25QYXRoOiBzdHJpbmc7XG5cbiAgICBpZiAoZmluZERlcml2YXRpb25QYXRoKSB7XG4gICAgICBjb25zdCBpbnB1dEFkZHJlc3M6IEFkZHJlc3MgPSBhd2FpdCB0aGlzLmNsaWVudC5maW5hbmNld2FsbGV0LnF1aWNrRmluZEFkZHJlc3MoXG4gICAgICAgIFtfYWRkcmVzc10sXG4gICAgICApO1xuICAgICAgaWYgKGlucHV0QWRkcmVzcykge1xuICAgICAgICBkZXJpdmF0aW9uUGF0aCA9IGlucHV0QWRkcmVzcy5kZXJpdmF0aW9uUGF0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHhpZDogcHJldlR4LnR4SWQudG9TdHJpbmcoKSxcbiAgICAgIHZvdXQ6IGlucHV0LnByZXZUeFZvdXQsXG4gICAgICBhZGRyZXNzOiBfYWRkcmVzcyxcbiAgICAgIGFtb3VudDogcHJldlR4T3V0LnZhbHVlLmJpdGNvaW4sXG4gICAgICB2YWx1ZTogTnVtYmVyKHByZXZUeE91dC52YWx1ZS5zYXRzKSxcbiAgICAgIGRlcml2YXRpb25QYXRoLFxuICAgICAgbWF4V2l0bmVzc0xlbmd0aDogaW5wdXQubWF4V2l0bmVzc0xlbixcbiAgICAgIHJlZGVlbVNjcmlwdDogaW5wdXQucmVkZWVtU2NyaXB0XG4gICAgICAgID8gaW5wdXQucmVkZWVtU2NyaXB0LnRvU3RyaW5nKCdoZXgnKVxuICAgICAgICA6ICcnLFxuICAgICAgc2NyaXB0UHViS2V5OiBzY3JpcHRQdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgaW5wdXRTZXJpYWxJZDogaW5wdXQuaW5wdXRTZXJpYWxJZCxcbiAgICAgIHRvVXR4bzogSW5wdXQucHJvdG90eXBlLnRvVXR4byxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgaW5wdXRUb0Z1bmRpbmdJbnB1dChpbnB1dDogSW5wdXQpOiBQcm9taXNlPEZ1bmRpbmdJbnB1dD4ge1xuICAgIGNvbnN0IGZ1bmRpbmdJbnB1dCA9IG5ldyBGdW5kaW5nSW5wdXRWMCgpO1xuICAgIGZ1bmRpbmdJbnB1dC5wcmV2VHhWb3V0ID0gaW5wdXQudm91dDtcblxuICAgIGxldCB0eFJhdyA9ICcnO1xuICAgIHRyeSB7XG4gICAgICB0eFJhdyA9IGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdnZXRSYXdUcmFuc2FjdGlvbkJ5SGFzaCcpKGlucHV0LnR4aWQpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHR4UmF3ID0gKGF3YWl0IHRoaXMuZ2V0TWV0aG9kKCdqc29ucnBjJykoJ2dldHRyYW5zYWN0aW9uJywgaW5wdXQudHhpZCkpXG4gICAgICAgICAgLmhleDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgYENhbm5vdCBmaW5kIHR4ICR7aW5wdXQudHhpZH0gaW4gaW5wdXRUb0Z1bmRpbmdJbnB1dCB1c2luZyBnZXRyYXd0cmFuc2FjdGlvbmJ5aGFzaCBvciBnZXR0cmFuc2FjdGlvbmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHR4ID0gVHguZGVjb2RlKFN0cmVhbVJlYWRlci5mcm9tSGV4KHR4UmF3KSk7XG5cbiAgICBmdW5kaW5nSW5wdXQucHJldlR4ID0gdHg7XG4gICAgZnVuZGluZ0lucHV0LnNlcXVlbmNlID0gU2VxdWVuY2UuZGVmYXVsdCgpO1xuICAgIGZ1bmRpbmdJbnB1dC5tYXhXaXRuZXNzTGVuID0gaW5wdXQubWF4V2l0bmVzc0xlbmd0aFxuICAgICAgPyBpbnB1dC5tYXhXaXRuZXNzTGVuZ3RoXG4gICAgICA6IDEwODtcbiAgICBmdW5kaW5nSW5wdXQucmVkZWVtU2NyaXB0ID0gaW5wdXQucmVkZWVtU2NyaXB0XG4gICAgICA/IEJ1ZmZlci5mcm9tKGlucHV0LnJlZGVlbVNjcmlwdCwgJ2hleCcpXG4gICAgICA6IEJ1ZmZlci5mcm9tKCcnLCAnaGV4Jyk7XG4gICAgZnVuZGluZ0lucHV0LmlucHV0U2VyaWFsSWQgPSBpbnB1dC5pbnB1dFNlcmlhbElkXG4gICAgICA/IGlucHV0LmlucHV0U2VyaWFsSWRcbiAgICAgIDogZ2VuZXJhdGVTZXJpYWxJZCgpO1xuXG4gICAgcmV0dXJuIGZ1bmRpbmdJbnB1dDtcbiAgfVxuXG4gIGFzeW5jIGdldENvbm5lY3RlZE5ldHdvcmsoKTogUHJvbWlzZTxCaXRjb2luTmV0d29yaz4ge1xuICAgIHJldHVybiB0aGlzLl9uZXR3b3JrO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5pdGlhbGl6ZVJlc3BvbnNlIHtcbiAgZnVuZGluZ1B1YktleTogQnVmZmVyO1xuICBwYXlvdXRTUEs6IEJ1ZmZlcjtcbiAgcGF5b3V0U2VyaWFsSWQ6IGJpZ2ludDtcbiAgZnVuZGluZ0lucHV0czogRnVuZGluZ0lucHV0W107XG4gIGNoYW5nZVNQSzogQnVmZmVyO1xuICBjaGFuZ2VTZXJpYWxJZDogYmlnaW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjY2VwdERsY09mZmVyUmVzcG9uc2Uge1xuICBkbGNBY2NlcHQ6IERsY0FjY2VwdDtcbiAgZGxjVHJhbnNhY3Rpb25zOiBEbGNUcmFuc2FjdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2lnbkRsY0FjY2VwdFJlc3BvbnNlIHtcbiAgZGxjU2lnbjogRGxjU2lnbjtcbiAgZGxjVHJhbnNhY3Rpb25zOiBEbGNUcmFuc2FjdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR2V0UGF5b3V0c1Jlc3BvbnNlIHtcbiAgcGF5b3V0czogUGF5b3V0UmVxdWVzdFtdO1xuICBwYXlvdXRHcm91cHM6IFBheW91dEdyb3VwW107XG4gIG1lc3NhZ2VzTGlzdDogTWVzc2FnZXNbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVEbGNUeHNSZXNwb25zZSB7XG4gIGRsY1RyYW5zYWN0aW9uczogRGxjVHJhbnNhY3Rpb25zO1xuICBtZXNzYWdlc0xpc3Q6IE1lc3NhZ2VzW107XG59XG5cbmludGVyZmFjZSBJU2lnIHtcbiAgZW5jcnlwdGVkU2lnOiBCdWZmZXI7XG4gIGRsZXFQcm9vZjogQnVmZmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzUmVzcG9uc2Uge1xuICBjZXRTaWduYXR1cmVzOiBDZXRBZGFwdG9yU2lnbmF0dXJlc1YwO1xuICByZWZ1bmRTaWduYXR1cmU6IEJ1ZmZlcjtcbn1cblxuaW50ZXJmYWNlIFBheW91dEdyb3VwIHtcbiAgcGF5b3V0OiBiaWdpbnQ7XG4gIGdyb3VwczogbnVtYmVyW11bXTtcbn1cblxuaW50ZXJmYWNlIEZpbmRPdXRjb21lUmVzcG9uc2Uge1xuICBpbmRleDogbnVtYmVyO1xuICBncm91cExlbmd0aDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENoYW5nZSB7XG4gIHZhbHVlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3V0cHV0IHtcbiAgdmFsdWU6IG51bWJlcjtcbiAgaWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXRzRm9yQW1vdW50UmVzcG9uc2Uge1xuICBpbnB1dHM6IElucHV0W107XG4gIGNoYW5nZTogQ2hhbmdlO1xuICBvdXRwdXRzOiBPdXRwdXRbXTtcbiAgZmVlOiBudW1iZXI7XG59XG5cbmNvbnN0IEJ1cm5BZGRyZXNzID0gJ2JjcnQxcXhjanVmZ2gyamFya3AycWt4NjhhemgwOHc5djVnYWg4dTZlczhzJztcbiJdLCJuYW1lcyI6WyJFU1RJTUFURURfU0laRSIsIkJpdGNvaW5EbGNQcm92aWRlciIsIlByb3ZpZGVyIiwiQ2ZkTG9hZGVkIiwiX2NmZERsY0pzIiwic2xlZXAiLCJHZXRQcml2S2V5c0ZvcklucHV0cyIsImlucHV0cyIsInByaXZLZXlzIiwiaSIsImxlbmd0aCIsImlucHV0IiwiZGVyaXZhdGlvblBhdGgiLCJnZXRNZXRob2QiLCJhZGRyZXNzIiwia2V5UGFpciIsInByaXZLZXkiLCJCdWZmZXIiLCJmcm9tIiwiX19EIiwidG9TdHJpbmciLCJwdXNoIiwiR2V0Q2ZkTmV0d29yayIsIm5ldHdvcmsiLCJnZXRDb25uZWN0ZWROZXR3b3JrIiwibmFtZSIsIkdldElucHV0c0ZvckFtb3VudCIsImFtb3VudCIsImZlZVJhdGVQZXJWYiIsImZpeGVkSW5wdXRzIiwiQmlnSW50IiwidGFyZ2V0cyIsIkJ1cm5BZGRyZXNzIiwidmFsdWUiLCJOdW1iZXIiLCJpbnB1dHNGb3JBbW91bnQiLCJlIiwiRXJyb3IiLCJJbml0aWFsaXplIiwiY29sbGF0ZXJhbCIsInBheW91dEFkZHJlc3MiLCJjbGllbnQiLCJ3YWxsZXQiLCJnZXRVbnVzZWRBZGRyZXNzIiwicGF5b3V0U1BLIiwidG9PdXRwdXRTY3JpcHQiLCJjaGFuZ2VBZGRyZXNzIiwiY2hhbmdlU1BLIiwiZnVuZGluZ0FkZHJlc3MiLCJmdW5kaW5nUHViS2V5IiwicHVibGljS2V5IiwiZnVuZGluZ0lucHV0cyIsIlByb21pc2UiLCJhbGwiLCJtYXAiLCJpbnB1dFRvRnVuZGluZ0lucHV0IiwicGF5b3V0U2VyaWFsSWQiLCJnZW5lcmF0ZVNlcmlhbElkIiwiY2hhbmdlU2VyaWFsSWQiLCJHZXRQYXlvdXRzRnJvbVBheW91dEZ1bmN0aW9uIiwiX2RsY09mZmVyIiwiY29udHJhY3REZXNjcmlwdG9yIiwib3JhY2xlSW5mbyIsInRvdGFsQ29sbGF0ZXJhbCIsInR5cGUiLCJNZXNzYWdlVHlwZSIsIkRsY09mZmVyVjAiLCJkbGNPZmZlciIsInBheW91dEZ1bmN0aW9uIiwiUGF5b3V0RnVuY3Rpb25WMCIsInBpZWNlcyIsInBheW91dEN1cnZlUGllY2UiLCJIeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlIiwiT2xkSHlwZXJib2xhUGF5b3V0Q3VydmVQaWVjZSIsImIiLCJjIiwiZXZlbnREZXNjcmlwdG9yIiwiYW5ub3VuY2VtZW50Iiwib3JhY2xlRXZlbnQiLCJEaWdpdERlY29tcG9zaXRpb25FdmVudERlc2NyaXB0b3JWMCIsInJvdW5kaW5nSW50ZXJ2YWxzIiwiY2V0UGF5b3V0cyIsIkh5cGVyYm9sYVBheW91dEN1cnZlIiwiY29tcHV0ZVBheW91dHMiLCJwYXlvdXRHcm91cHMiLCJmb3JFYWNoIiwicCIsInBheW91dCIsImdyb3VwcyIsImdyb3VwQnlJZ25vcmluZ0RpZ2l0cyIsImluZGV4RnJvbSIsImluZGV4VG8iLCJiYXNlIiwibnVtRGlnaXRzIiwiclZhbHVlc01lc3NhZ2VzTGlzdCIsIkdlbmVyYXRlTWVzc2FnZXMiLCJwYXlvdXRzIiwibWVzc2FnZXNMaXN0Iiwib3V0cHV0c1RvUGF5b3V0cyIsIm9mZmVyQ29sbGF0ZXJhbFNhdG9zaGlzIiwiY29udHJhY3RJbmZvIiwiR2V0UGF5b3V0c0Zyb21Qb2x5bm9taWFsUGF5b3V0RnVuY3Rpb24iLCJwaWVjZSIsIlBvbHlub21pYWxQYXlvdXRDdXJ2ZVBpZWNlIiwiUG9seW5vbWlhbFBheW91dEN1cnZlIiwiR2V0UGF5b3V0cyIsImNoZWNrVHlwZXMiLCJjb250cmFjdE9yYWNsZVBhaXJzIiwiR2V0Q29udHJhY3RPcmFjbGVQYWlycyIsInBheW91dFJlc3BvbnNlcyIsIkdldFBheW91dHNGcm9tQ29udHJhY3REZXNjcmlwdG9yIiwiRmxhdHRlblBheW91dHMiLCJyZWR1Y2UiLCJhY2MiLCJjb25jYXQiLCJHZXRJbmRpY2VzRnJvbVBheW91dHMiLCJwcmV2Iiwic3RhcnRpbmdNZXNzYWdlc0luZGV4Iiwic3RhcnRpbmdQYXlvdXRHcm91cHNJbmRleCIsIkNvbnRyYWN0RGVzY3JpcHRvclYwIiwiQ29udHJhY3REZXNjcmlwdG9yVjEiLCJjb250cmFjdERlc2NyaXB0b3JWMSIsImNyZWF0ZURsY1R4cyIsIl9kbGNBY2NlcHQiLCJkbGNBY2NlcHQiLCJsb2NhbEZ1bmRQdWJrZXkiLCJyZW1vdGVGdW5kUHVia2V5IiwibG9jYWxGaW5hbFNjcmlwdFB1YmtleSIsInJlbW90ZUZpbmFsU2NyaXB0UHVia2V5IiwibG9jYWxDaGFuZ2VTY3JpcHRQdWJrZXkiLCJyZW1vdGVDaGFuZ2VTY3JpcHRQdWJrZXkiLCJsb2NhbElucHV0cyIsImZ1bmRpbmdJbnB1dCIsImZ1bmRpbmdJbnB1dFRvSW5wdXQiLCJ0b1V0eG8iLCJyZW1vdGVJbnB1dHMiLCJsb2NhbElucHV0QW1vdW50IiwiY3VyIiwiR2V0U2F0b3NoaUFtb3VudCIsInJlbW90ZUlucHV0QW1vdW50IiwiZGxjVHhSZXF1ZXN0IiwibG9jYWxDb2xsYXRlcmFsQW1vdW50IiwibG9jYWxQYXlvdXRTZXJpYWxJZCIsImxvY2FsQ2hhbmdlU2VyaWFsSWQiLCJyZW1vdGVDb2xsYXRlcmFsQW1vdW50IiwiYWNjZXB0Q29sbGF0ZXJhbFNhdG9zaGlzIiwicmVtb3RlUGF5b3V0U2VyaWFsSWQiLCJyZW1vdGVDaGFuZ2VTZXJpYWxJZCIsInJlZnVuZExvY2t0aW1lIiwiZmVlUmF0ZSIsImNldExvY2tUaW1lIiwiY2V0TG9ja3RpbWUiLCJmdW5kT3V0cHV0U2VyaWFsSWQiLCJkbGNUeHMiLCJDcmVhdGVEbGNUcmFuc2FjdGlvbnMiLCJkbGNUcmFuc2FjdGlvbnMiLCJEbGNUcmFuc2FjdGlvbnNWMCIsImZ1bmRUeCIsIlR4IiwiZGVjb2RlIiwiU3RyZWFtUmVhZGVyIiwiZnJvbUhleCIsImZ1bmRUeEhleCIsImZ1bmRUeFZvdXQiLCJzb3J0IiwiYSIsImZpbmRJbmRleCIsInJlZnVuZFR4IiwicmVmdW5kVHhIZXgiLCJjZXRzIiwiY2V0c0hleCIsImNldEhleCIsIkdlbmVyYXRlRW51bU1lc3NhZ2VzIiwiR2VuZXJhdGVEaWdpdERlY29tcG9zaXRpb25NZXNzYWdlcyIsIm9yYWNsZU5vbmNlcyIsIm1lc3NhZ2VzIiwibSIsIkVudW1FdmVudERlc2NyaXB0b3JWMCIsIl9jb250cmFjdEluZm8iLCJDb250cmFjdEluZm9WMCIsIkNvbnRyYWN0SW5mb1YxIiwiQ3JlYXRlQ2V0QWRhcHRvckFuZFJlZnVuZFNpZ3MiLCJfZGxjVHhzIiwiaXNPZmZlcmVyIiwiY2V0Iiwic2VyaWFsaXplIiwiZnVuZGluZ1NQSyIsIlNjcmlwdCIsInAyd3BraExvY2siLCJoYXNoMTYwIiwic2xpY2UiLCJmcm9tT3V0cHV0U2NyaXB0IiwiZmluYW5jZXdhbGxldCIsInF1aWNrRmluZEFkZHJlc3MiLCJmdW5kUHJpdmF0ZUtleVBhaXIiLCJmdW5kUHJpdmF0ZUtleSIsImluZGljZXMiLCJzaWdzIiwiaW5kZXgiLCJlbnRyaWVzIiwib3JhY2xlQW5ub3VuY2VtZW50Iiwic3RhcnRpbmdJbmRleCIsImVuZGluZ0luZGV4Iiwib3JhY2xlRXZlbnRNZXNzYWdlc0xpc3QiLCJvcmFjbGVFdmVudENldHNIZXgiLCJjaHVuayIsImFkYXB0b3JTaWdSZXF1ZXN0UHJvbWlzZXMiLCJqIiwidGVtcE1lc3NhZ2VzTGlzdCIsInRlbXBDZXRzSGV4IiwiY2V0U2lnblJlcXVlc3QiLCJwcml2a2V5IiwiZnVuZFR4SWQiLCJ0eElkIiwiZnVuZFZvdXQiLCJmdW5kSW5wdXRBbW91bnQiLCJvdXRwdXRzIiwic2F0cyIsIm9yYWNsZVB1YmtleSIsIm9yYWNsZVJWYWx1ZXMiLCJub25jZSIsInJlc3BvbnNlIiwiQ3JlYXRlQ2V0QWRhcHRvclNpZ25hdHVyZXMiLCJhZGFwdG9yUGFpcnMiLCJmbGF0IiwiYWRhcHRvclBhaXIiLCJlbmNyeXB0ZWRTaWciLCJzaWduYXR1cmUiLCJkbGVxUHJvb2YiLCJwcm9vZiIsInJlZnVuZFNpZ25SZXF1ZXN0IiwicmVmdW5kU2lnbmF0dXJlIiwiR2V0UmF3UmVmdW5kVHhTaWduYXR1cmUiLCJoZXgiLCJjZXRTaWduYXR1cmVzIiwiQ2V0QWRhcHRvclNpZ25hdHVyZXNWMCIsIlZlcmlmeUNldEFkYXB0b3JBbmRSZWZ1bmRTaWdzIiwiX2RsY1NpZ24iLCJkbGNTaWduIiwib3JhY2xlRXZlbnRTaWdzIiwic2lnc1ZhbGlkaXR5IiwidGVtcFNpZ3MiLCJ0ZW1wQWRhcHRvclBhaXJzIiwic2lnIiwidmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZXNSZXF1ZXN0IiwidmVyaWZ5UmVtb3RlIiwiVmVyaWZ5Q2V0QWRhcHRvclNpZ25hdHVyZXMiLCJ2YWxpZCIsImFyZVNpZ3NWYWxpZCIsImV2ZXJ5IiwidmVyaWZ5UmVmdW5kU2lnUmVxdWVzdCIsIlZlcmlmeVJlZnVuZFR4U2lnbmF0dXJlIiwiQ3JlYXRlRnVuZGluZ1NpZ3MiLCJpbnB1dFByaXZLZXlzIiwiZnVuZFR4U2lncyIsImZ1bmRUeFNpZ25SZXF1ZXN0IiwicHJldlR4SWQiLCJ0eGlkIiwicHJldlZvdXQiLCJ2b3V0IiwiR2V0UmF3RnVuZFR4U2lnbmF0dXJlIiwiaW5wdXRQdWJLZXlzIiwicmVxUHJpdktleSIsImlzQ29tcHJlc3NlZCIsInB1YmtleSIsIndpdG5lc3NFbGVtZW50cyIsInNpZ1dpdG5lc3MiLCJTY3JpcHRXaXRuZXNzVjAiLCJ3aXRuZXNzIiwicHViS2V5V2l0bmVzcyIsImZ1bmRpbmdTaWduYXR1cmVzIiwiRnVuZGluZ1NpZ25hdHVyZXNWMCIsIlZlcmlmeUZ1bmRpbmdTaWdzIiwid2l0bmVzc0VsZW1lbnQiLCJ2ZXJpZnlGdW5kU2lnUmVxdWVzdCIsInByZXZUeCIsInByZXZUeFZvdXQiLCJWZXJpZnlGdW5kVHhTaWduYXR1cmUiLCJDcmVhdGVGdW5kaW5nVHgiLCJhc3luY0ZvckVhY2giLCJhZGRTaWduUmVxdWVzdCIsIkFkZFNpZ25hdHVyZVRvRnVuZFRyYW5zYWN0aW9uIiwiRmluZE91dGNvbWVJbmRleEZyb21Qb2x5bm9taWFsUGF5b3V0Q3VydmVQaWVjZSIsImNvbnRyYWN0T3JhY2xlUGFpckluZGV4IiwicG9seW5vbWlhbFBheW91dEN1cnZlUGllY2UiLCJvcmFjbGVBdHRlc3RhdGlvbiIsIm91dGNvbWUiLCJwb2x5bm9taWFsQ3VydmUiLCJmcm9tUGF5b3V0Q3VydmVQaWVjZSIsImNsYW1wQk4iLCJ2YWwiLCJCaWdOdW1iZXIiLCJtYXgiLCJtaW4iLCJnZXRQYXlvdXQiLCJwYXlvdXRJbmRleE9mZnNldCIsImludGVydmFsc1NvcnRlZCIsImludGVydmFscyIsImJlZ2luSW50ZXJ2YWwiLCJpbnRlcnZhbCIsImZpbmQiLCJyb3VuZGVkUGF5b3V0Iiwicm91bmRQYXlvdXQiLCJyb3VuZGluZ01vZCIsIm91dGNvbWVzRm9ybWF0dGVkIiwib3V0Y29tZXMiLCJwYXJzZUludCIsImdyb3VwSW5kZXgiLCJncm91cExlbmd0aCIsInBheW91dEdyb3VwIiwiZ3JvdXAiLCJtc2ciLCJGaW5kT3V0Y29tZUluZGV4RnJvbUh5cGVyYm9sYVBheW91dEN1cnZlUGllY2UiLCJoeXBlcmJvbGFQYXlvdXRDdXJ2ZVBpZWNlIiwiaHlwZXJib2xhQ3VydmUiLCJGaW5kT3V0Y29tZUluZGV4IiwiZXZlbnRJZCIsImFzc2VydCIsImNvbnRyYWN0T3JhY2xlUGFpciIsIl9jb250cmFjdERlc2NyaXB0b3IiLCJfcGF5b3V0RnVuY3Rpb24iLCJyZXZlcnNlIiwicGllY2VzU29ydGVkIiwiZW5kcG9pbnQiLCJWYWxpZGF0ZUV2ZW50IiwiYXR0ZXN0ZWRPcmFjbGVFdmVudCIsIkZpbmRBbmRTaWduQ2V0IiwidW5kZWZpbmVkIiwib3V0Y29tZUluZGV4IiwiR2V0RnVuZFByaXZhdGVLZXkiLCJzbGljZUluZGV4Iiwic2lnbmF0dXJlcyIsIm9yYWNsZVNpZ25hdHVyZXMiLCJzaWduQ2V0UmVxdWVzdCIsImZ1bmRQcml2a2V5IiwiYWRhcHRvclNpZ25hdHVyZSIsImZpbmFsQ2V0IiwiU2lnbkNldCIsIkdldEZ1bmRBZGRyZXNzIiwiR2V0RnVuZEtleVBhaXIiLCJwcml2YXRlS2V5IiwiQ3JlYXRlQ2xvc2VSYXdUeHMiLCJjbG9zZUlucHV0QW1vdW50IiwiX2RsY0Nsb3NlcyIsImluaXRpYXRvclBheW91dHMiLCJmaW5hbGl6ZXIiLCJEdWFsQ2xvc2luZ1R4RmluYWxpemVyIiwicmF3VHJhbnNhY3Rpb25SZXF1ZXN0UHJvbWlzZXMiLCJyYXdDbG9zZVR4cyIsIm51bVBheW91dHMiLCJvZmZlclBheW91dFZhbHVlIiwiYWNjZXB0UGF5b3V0VmFsdWUiLCJwYXlvdXRNaW51c09mZmVyRmVlcyIsIm9mZmVySW5pdGlhdG9yRmVlcyIsImNvbGxhdGVyYWxNaW51c1BheW91dCIsImRsY0Nsb3NlIiwiX2RsY0Nsb3NlIiwib2ZmZXJQYXlvdXRTYXRvc2hpcyIsImFjY2VwdFBheW91dFNhdG9zaGlzIiwidHhPdXRzIiwicmF3VHJhbnNhY3Rpb25SZXF1ZXN0IiwidmVyc2lvbiIsImxvY2t0aW1lIiwidHhpbnMiLCJzZXF1ZW5jZSIsInR4b3V0cyIsImhleHMiLCJDcmVhdGVTaWduYXR1cmVIYXNoZXMiLCJmdW5kaW5nUHViS2V5cyIsImNvbXBhcmUiLCJwMm1zIiwicGF5bWVudHMiLCJwdWJrZXlzIiwicGF5bWVudFZhcmlhbnQiLCJwMndzaCIsInJlZGVlbSIsInNpZ0hhc2hSZXF1ZXN0UHJvbWlzZXMiLCJzaWdIYXNoZXMiLCJyYXdUeCIsInNpZ0hhc2hSZXF1ZXN0IiwidHgiLCJ0eGluIiwia2V5RGF0YSIsIm91dHB1dCIsImhhc2hUeXBlIiwic2lnaGFzaFR5cGUiLCJzaWdoYXNoQW55b25lQ2FuUGF5Iiwic2lnaGFzaCIsInNpZ2hhc2hlcyIsIkNhbGN1bGF0ZUVjU2lnbmF0dXJlSGFzaGVzIiwiY2ZkTmV0d29yayIsInNpZ3NSZXF1ZXN0UHJvbWlzZXMiLCJzaWdIYXNoIiwiY2FsY3VsYXRlRWNTaWduYXR1cmVSZXF1ZXN0IiwicHJpdmtleURhdGEiLCJ3aWYiLCJpc0dyaW5kUiIsIlZlcmlmeVNpZ25hdHVyZXMiLCJkbGNDbG9zZXMiLCJ2ZXJpZnlTaWduYXR1cmVSZXF1ZXN0IiwiY2xvc2VTaWduYXR1cmUiLCJyZWRlZW1TY3JpcHQiLCJzdWNjZXNzIiwib2ZmZXJGdW5kaW5nU1BLIiwiYWNjZXB0RnVuZGluZ1NQSyIsIm9mZmVyRnVuZGluZ0FkZHJlc3MiLCJhY2NlcHRGdW5kaW5nQWRkcmVzcyIsIndhbGxldEFkZHJlc3MiLCJjcmVhdGVEbGNPZmZlciIsInZhbGlkYXRlIiwiX2Z1bmRpbmdJbnB1dHMiLCJGdW5kaW5nSW5wdXRWMCIsImNvbnRyYWN0RmxhZ3MiLCJjaGFpbkhhc2giLCJjaGFpbkhhc2hGcm9tTmV0d29yayIsIkR1YWxGdW5kaW5nVHhGaW5hbGl6ZXIiLCJmdW5kaW5nIiwidG90YWwiLCJvZmZlckZlZXMiLCJhY2NlcHREbGNPZmZlciIsIkRsY0FjY2VwdFYwIiwidGVtcENvbnRyYWN0SWQiLCJzaGEyNTYiLCJpZHMiLCJTZXQiLCJzaXplIiwiYWNjZXB0RmVlcyIsIl9kbGNUcmFuc2FjdGlvbnMiLCJjb250cmFjdElkIiwieG9yIiwibmVnb3RpYXRpb25GaWVsZHMiLCJOZWdvdGlhdGlvbkZpZWxkc1YwIiwic2lnbkRsY0FjY2VwdCIsIkRsY1NpZ25WMCIsImZpbmFsaXplRGxjU2lnbiIsImV4ZWN1dGUiLCJyZWZ1bmQiLCJhZGRTaWdzVG9SZWZ1bmRUeFJlcXVlc3QiLCJyZWZ1bmRIZXgiLCJBZGRTaWduYXR1cmVzVG9SZWZ1bmRUeCIsImNyZWF0ZURsY0Nsb3NlIiwiaW5pdGlhdG9yUGF5b3V0U2F0b3NoaXMiLCJfaW5wdXRzIiwicHNidCIsIlBzYnQiLCJ0ZW1wSW5wdXRzIiwiaW5wdXRTZXJpYWxJZCIsImZ1bmRpbmdJbnB1dFNlcmlhbElkIiwicHNidElucHV0cyIsImhhc2giLCJ3aXRuZXNzVXR4byIsInNjcmlwdCIsIndpdG5lc3NTY3JpcHQiLCJwMndwa2giLCJzb3J0ZWRQc2J0SW5wdXRzIiwiZnVuZGluZ0lucHV0SW5kZXgiLCJhZGRJbnB1dCIsIm9mZmVyRmlyc3QiLCJhZGRPdXRwdXQiLCJzaWduSW5wdXQiLCJ2YWxpZGF0ZVNpZ25hdHVyZXNPZkFsbElucHV0cyIsImRhdGEiLCJwYXJ0aWFsU2lnIiwiaW5wdXRTaWdzIiwiZmlsdGVyIiwiRGxjQ2xvc2VWMCIsInR4T3V0cHV0cyIsImZ1bmRJbnB1dFNlcmlhbElkIiwiY3JlYXRlQmF0Y2hEbGNDbG9zZSIsInZlcmlmeUJhdGNoRGxjQ2xvc2VVc2luZ01ldGFkYXRhIiwiZGxjQ2xvc2VNZXRhZGF0YSIsInRvRGxjTWVzc2FnZXMiLCJ2ZXJpZnlCYXRjaERsY0Nsb3NlIiwiZmluYWxpemVEbGNDbG9zZSIsInNjcmlwdFB1YktleSIsIm9mZmVyZXIiLCJlbmNvZGUiLCJ1cGRhdGVJbnB1dCIsIndpdG5lc3NJIiwiZWwiLCJmaW5hbGl6ZUFsbElucHV0cyIsImV4dHJhY3RUcmFuc2FjdGlvbiIsInRvSGV4IiwianNvbk9iamVjdCIsIkNyZWF0ZUNldEFkYXB0b3JTaWduYXR1cmUiLCJDcmVhdGVDZXQiLCJDcmVhdGVGdW5kVHJhbnNhY3Rpb24iLCJDcmVhdGVSZWZ1bmRUcmFuc2FjdGlvbiIsIlZlcmlmeUNldEFkYXB0b3JTaWduYXR1cmUiLCJTaWduRnVuZFRyYW5zYWN0aW9uIiwiX2lucHV0IiwiZmluZERlcml2YXRpb25QYXRoIiwicHJldlR4T3V0IiwiX2FkZHJlc3MiLCJpbnB1dEFkZHJlc3MiLCJiaXRjb2luIiwibWF4V2l0bmVzc0xlbmd0aCIsIm1heFdpdG5lc3NMZW4iLCJJbnB1dCIsInByb3RvdHlwZSIsInR4UmF3IiwiU2VxdWVuY2UiLCJkZWZhdWx0IiwiX25ldHdvcmsiLCJjb25zdHJ1Y3RvciIsImNmZERsY0pzIl0sIm1hcHBpbmdzIjoiQUFBQTs7OztBQUFxQyxJQUFBLGdCQUFpQyxXQUFqQyxpQ0FBaUMsQ0FBQTtBQUNqRCxJQUFBLFNBQXlCLGtDQUF6Qix5QkFBeUIsRUFBQTtBQTRDdkMsSUFBQSxNQUFzQixXQUF0QixzQkFBc0IsQ0FBQTtBQUdQLElBQUEsTUFBa0IsV0FBbEIsa0JBQWtCLENBQUE7QUFRakMsSUFBQSxLQUFnQixXQUFoQixnQkFBZ0IsQ0FBQTtBQWdDaEIsSUFBQSxVQUFxQixXQUFyQixxQkFBcUIsQ0FBQTtBQUNTLElBQUEsUUFBeUIsV0FBekIseUJBQXlCLENBQUE7QUFDakMsSUFBQSxNQUF1QixXQUF2Qix1QkFBdUIsQ0FBQTtBQUNmLElBQUEsT0FBd0IsV0FBeEIsd0JBQXdCLENBQUE7QUFDMUMsSUFBQSxPQUFRLGtDQUFSLFFBQVEsRUFBQTtBQUNMLElBQUEsWUFBYyxrQ0FBZCxjQUFjLEVBQUE7QUFPN0IsSUFBQSxhQUFlLFdBQWYsZUFBZSxDQUFBO0FBT2YsSUFBQSxPQUFlLFdBQWYsZUFBZSxDQUFBOzs7Ozs7QUFFdEIsTUFBTUEsY0FBYyxHQUFHLEdBQUcsQUFBQztBQUVaLElBQUEsQUFBTUMsa0JBQWtCLEdBQXhCLE1BQU1BLGtCQUFrQixTQUM3QkMsU0FBUSxRQUFBO0lBWWhCLE1BQWNDLFNBQVMsR0FBRztRQUN4QixNQUFPLENBQUMsSUFBSSxDQUFDQyxTQUFTLENBQUU7WUFDdEIsTUFBTUMsQ0FBQUEsR0FBQUEsTUFBSyxBQUFJLENBQUEsTUFBSixDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ2pCO0tBQ0Y7SUFFRCxN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