@atomicfinance/bitcoin-dlc-provider 2.5.0 → 2.5.1

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