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