@bitgo-beta/sdk-coin-trx 1.0.2-beta.202 → 1.0.2-beta.2021
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.
- package/dist/resources/protobuf/Contract.proto +32 -0
- package/dist/resources/protobuf/tron.d.ts +1478 -214
- package/dist/resources/protobuf/tron.js +6312 -2600
- package/dist/resources/protobuf/tron.proto +6 -0
- package/dist/src/index.js +6 -2
- package/dist/src/lib/accountCreateTxBuilder.d.ts +60 -0
- package/dist/src/lib/accountCreateTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/accountCreateTxBuilder.js +191 -0
- package/dist/src/lib/constants.d.ts +4 -0
- package/dist/src/lib/constants.d.ts.map +1 -0
- package/dist/src/lib/constants.js +7 -0
- package/dist/src/lib/contractCallBuilder.d.ts +1 -35
- package/dist/src/lib/contractCallBuilder.d.ts.map +1 -1
- package/dist/src/lib/contractCallBuilder.js +13 -76
- package/dist/src/lib/delegateResourceTxBuilder.d.ts +27 -0
- package/dist/src/lib/delegateResourceTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/delegateResourceTxBuilder.js +104 -0
- package/dist/src/lib/enum.d.ts +40 -1
- package/dist/src/lib/enum.d.ts.map +1 -1
- package/dist/src/lib/enum.js +44 -4
- package/dist/src/lib/freezeBalanceTxBuilder.d.ts +71 -0
- package/dist/src/lib/freezeBalanceTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/freezeBalanceTxBuilder.js +217 -0
- package/dist/src/lib/iface.d.ts +248 -2
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +1 -1
- package/dist/src/lib/index.js +23 -9
- package/dist/src/lib/keyPair.d.ts +0 -1
- package/dist/src/lib/keyPair.d.ts.map +1 -1
- package/dist/src/lib/keyPair.js +31 -18
- package/dist/src/lib/resourceManagementTxBuilder.d.ts +72 -0
- package/dist/src/lib/resourceManagementTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/resourceManagementTxBuilder.js +150 -0
- package/dist/src/lib/tokenTransferBuilder.d.ts +1 -1
- package/dist/src/lib/tokenTransferBuilder.js +3 -3
- package/dist/src/lib/transaction.d.ts +3 -0
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +115 -6
- package/dist/src/lib/transactionBuilder.d.ts +53 -6
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +114 -21
- package/dist/src/lib/undelegateResourceTxBuilder.d.ts +27 -0
- package/dist/src/lib/undelegateResourceTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/undelegateResourceTxBuilder.js +104 -0
- package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts +65 -0
- package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/unfreezeBalanceTxBuilder.js +210 -0
- package/dist/src/lib/utils.d.ts +92 -4
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +482 -47
- package/dist/src/lib/voteWitnessTxBuilder.d.ts +62 -0
- package/dist/src/lib/voteWitnessTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/voteWitnessTxBuilder.js +219 -0
- package/dist/src/lib/withdrawBuilder.d.ts +49 -0
- package/dist/src/lib/withdrawBuilder.d.ts.map +1 -0
- package/dist/src/lib/withdrawBuilder.js +167 -0
- package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts +49 -0
- package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts.map +1 -0
- package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.js +167 -0
- package/dist/src/lib/wrappedBuilder.d.ts +67 -1
- package/dist/src/lib/wrappedBuilder.d.ts.map +1 -1
- package/dist/src/lib/wrappedBuilder.js +114 -4
- package/dist/src/trx.d.ts +105 -4
- package/dist/src/trx.d.ts.map +1 -1
- package/dist/src/trx.js +519 -147
- package/dist/src/trxToken.d.ts +2 -2
- package/dist/src/trxToken.d.ts.map +1 -1
- package/dist/src/trxToken.js +47 -6
- package/dist/test/fixtures.d.ts +40 -0
- package/dist/test/fixtures.d.ts.map +1 -0
- package/dist/test/fixtures.js +46 -0
- package/dist/test/resources.d.ts +596 -0
- package/dist/test/resources.d.ts.map +1 -0
- package/dist/test/resources.js +759 -0
- package/dist/test/unit/index.d.ts +2 -0
- package/dist/test/unit/index.d.ts.map +1 -0
- package/dist/test/unit/index.js +19 -0
- package/dist/test/unit/keyPair.d.ts +2 -0
- package/dist/test/unit/keyPair.d.ts.map +1 -0
- package/dist/test/unit/keyPair.js +163 -0
- package/dist/test/unit/transaction.d.ts +2 -0
- package/dist/test/unit/transaction.d.ts.map +1 -0
- package/dist/test/unit/transaction.js +38 -0
- package/dist/test/unit/transactionBuilder/accountCreateTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/accountCreateTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/accountCreateTxBuilder.js +247 -0
- package/dist/test/unit/transactionBuilder/contractCallBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/contractCallBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/contractCallBuilder.js +315 -0
- package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.js +339 -0
- package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.js +365 -0
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +55 -0
- package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.js +339 -0
- package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.js +336 -0
- package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.js +277 -0
- package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.js +213 -0
- package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.js +213 -0
- package/dist/test/unit/transactionBuilder/wrappedBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder/wrappedBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder/wrappedBuilder.js +50 -0
- package/dist/test/unit/transactionBuilder.d.ts +2 -0
- package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
- package/dist/test/unit/transactionBuilder.js +178 -0
- package/dist/test/unit/trx.d.ts +2 -0
- package/dist/test/unit/trx.d.ts.map +1 -0
- package/dist/test/unit/trx.js +639 -0
- package/dist/test/unit/trxToken.d.ts +2 -0
- package/dist/test/unit/trxToken.d.ts.map +1 -0
- package/dist/test/unit/trxToken.js +119 -0
- package/dist/test/unit/util.d.ts +2 -0
- package/dist/test/unit/util.d.ts.map +1 -0
- package/dist/test/unit/util.js +141 -0
- package/dist/test/unit/verifyTransaction.d.ts +2 -0
- package/dist/test/unit/verifyTransaction.d.ts.map +1 -0
- package/dist/test/unit/verifyTransaction.js +593 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +22 -16
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -104
- package/resources/README.md +0 -31
- package/resources/protobuf/Contract.proto +0 -256
- package/resources/protobuf/Discover.proto +0 -44
- package/resources/protobuf/tron.d.ts +0 -11205
- package/resources/protobuf/tron.js +0 -33480
- package/resources/protobuf/tron.proto +0 -677
package/dist/src/trx.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -11,31 +15,54 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
11
15
|
}) : function(o, v) {
|
|
12
16
|
o["default"] = v;
|
|
13
17
|
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
21
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.Trx = exports.NodeTypes = exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = void 0;
|
|
36
|
+
exports.Trx = exports.NodeTypes = exports.DEFAULT_SCAN_FACTOR = exports.RECOVER_TRANSACTION_EXPIRY = exports.SAFE_TRON_TOKEN_TRANSACTION_FEE = exports.SAFE_TRON_TRANSACTION_FEE = exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = void 0;
|
|
23
37
|
/**
|
|
24
38
|
* @prettier
|
|
25
39
|
*/
|
|
26
40
|
const secp256k1 = __importStar(require("secp256k1"));
|
|
27
41
|
const crypto_1 = require("crypto");
|
|
28
|
-
const
|
|
42
|
+
const secp256k1_1 = require("@bitgo-beta/secp256k1");
|
|
29
43
|
const request = __importStar(require("superagent"));
|
|
30
44
|
const sdk_core_1 = require("@bitgo-beta/sdk-core");
|
|
45
|
+
const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
|
|
31
46
|
const lib_1 = require("./lib");
|
|
32
47
|
const builder_1 = require("./lib/builder");
|
|
48
|
+
const lodash_1 = require("lodash");
|
|
33
49
|
exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE = 1e6;
|
|
50
|
+
exports.SAFE_TRON_TRANSACTION_FEE = 2.1 * 1e6; // TRON foundation recommends 2.1 TRX as fees for guaranteed transaction
|
|
51
|
+
exports.SAFE_TRON_TOKEN_TRANSACTION_FEE = 100 * 1e6; // TRON foundation recommends 100 TRX as fees for guaranteed transaction
|
|
52
|
+
exports.RECOVER_TRANSACTION_EXPIRY = 86400000; // 24 hour
|
|
53
|
+
exports.DEFAULT_SCAN_FACTOR = 20; // default number of receive addresses to scan for funds
|
|
34
54
|
var NodeTypes;
|
|
35
55
|
(function (NodeTypes) {
|
|
36
56
|
NodeTypes[NodeTypes["Full"] = 0] = "Full";
|
|
37
57
|
NodeTypes[NodeTypes["Solidity"] = 1] = "Solidity";
|
|
38
|
-
})(NodeTypes
|
|
58
|
+
})(NodeTypes || (exports.NodeTypes = NodeTypes = {}));
|
|
59
|
+
function isTrxVerifyAddressOptions(params) {
|
|
60
|
+
return ('index' in params ||
|
|
61
|
+
'chain' in params ||
|
|
62
|
+
('coinSpecific' in params &&
|
|
63
|
+
params.coinSpecific !== undefined &&
|
|
64
|
+
('index' in params.coinSpecific || 'chain' in params.coinSpecific)));
|
|
65
|
+
}
|
|
39
66
|
class Trx extends sdk_core_1.BaseCoin {
|
|
40
67
|
constructor(bitgo, staticsCoin) {
|
|
41
68
|
super(bitgo);
|
|
@@ -60,6 +87,22 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
60
87
|
transactionDataAllowed() {
|
|
61
88
|
return true;
|
|
62
89
|
}
|
|
90
|
+
/** inherited doc */
|
|
91
|
+
getDefaultMultisigType() {
|
|
92
|
+
return sdk_core_1.multisigTypes.onchain;
|
|
93
|
+
}
|
|
94
|
+
/** @inheritDoc */
|
|
95
|
+
supportsTss() {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
/** @inheritDoc */
|
|
99
|
+
getMPCAlgorithm() {
|
|
100
|
+
return 'ecdsa';
|
|
101
|
+
}
|
|
102
|
+
/** @inheritDoc */
|
|
103
|
+
getHashFunction() {
|
|
104
|
+
return (0, crypto_1.createHash)('sha256');
|
|
105
|
+
}
|
|
63
106
|
static createInstance(bitgo, staticsCoin) {
|
|
64
107
|
return new Trx(bitgo, staticsCoin);
|
|
65
108
|
}
|
|
@@ -74,22 +117,26 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
74
117
|
allowsAccountConsolidations() {
|
|
75
118
|
return true;
|
|
76
119
|
}
|
|
120
|
+
/** @inheritDoc */
|
|
121
|
+
supportsResourceDelegation() {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
77
124
|
/**
|
|
78
|
-
* Checks if this is a valid base58
|
|
125
|
+
* Checks if this is a valid base58
|
|
79
126
|
* @param address
|
|
80
127
|
*/
|
|
81
128
|
isValidAddress(address) {
|
|
82
129
|
if (!address) {
|
|
83
130
|
return false;
|
|
84
131
|
}
|
|
85
|
-
return
|
|
132
|
+
return lib_1.Utils.isBase58Address(address);
|
|
86
133
|
}
|
|
87
134
|
/**
|
|
88
135
|
* Checks if this is a valid hex address
|
|
89
136
|
* @param address hex address
|
|
90
137
|
*/
|
|
91
138
|
isValidHexAddress(address) {
|
|
92
|
-
return
|
|
139
|
+
return /^41[0-9a-f]{40}$/i.test(address);
|
|
93
140
|
}
|
|
94
141
|
/**
|
|
95
142
|
* Generate ed25519 key pair
|
|
@@ -102,9 +149,9 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
102
149
|
if (!seed) {
|
|
103
150
|
// An extended private key has both a normal 256 bit private key and a 256 bit chain code, both of which must be
|
|
104
151
|
// random. 512 bits is therefore the maximum entropy and gives us maximum security against cracking.
|
|
105
|
-
seed = crypto_1.randomBytes(512 / 8);
|
|
152
|
+
seed = (0, crypto_1.randomBytes)(512 / 8);
|
|
106
153
|
}
|
|
107
|
-
const hd =
|
|
154
|
+
const hd = secp256k1_1.bip32.fromSeed(seed);
|
|
108
155
|
return {
|
|
109
156
|
pub: hd.neutered().toBase58(),
|
|
110
157
|
prv: hd.toBase58(),
|
|
@@ -112,7 +159,7 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
112
159
|
}
|
|
113
160
|
isValidXpub(xpub) {
|
|
114
161
|
try {
|
|
115
|
-
return
|
|
162
|
+
return secp256k1_1.bip32.fromBase58(xpub).isNeutered();
|
|
116
163
|
}
|
|
117
164
|
catch (e) {
|
|
118
165
|
return false;
|
|
@@ -129,11 +176,180 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
129
176
|
return {};
|
|
130
177
|
}
|
|
131
178
|
async isWalletAddress(params) {
|
|
132
|
-
|
|
179
|
+
const { address, keychains } = params;
|
|
180
|
+
if ((0, sdk_core_1.isTssVerifyAddressOptions)(params)) {
|
|
181
|
+
return (0, sdk_core_1.verifyMPCWalletAddress)({ ...params, keyCurve: 'secp256k1' }, this.isValidAddress.bind(this), (pubKey) => new lib_1.KeyPair({ pub: pubKey }).getAddress());
|
|
182
|
+
}
|
|
183
|
+
if (!isTrxVerifyAddressOptions(params)) {
|
|
184
|
+
throw new Error('Invalid or missing index for address verification');
|
|
185
|
+
}
|
|
186
|
+
const rawIndex = params.index ?? params.coinSpecific?.index;
|
|
187
|
+
const index = Number(rawIndex);
|
|
188
|
+
if (isNaN(index)) {
|
|
189
|
+
throw new Error('Invalid index. index must be a number.');
|
|
190
|
+
}
|
|
191
|
+
const chain = Number(params.chain ?? params.coinSpecific?.chain ?? 0);
|
|
192
|
+
if (!this.isValidAddress(address)) {
|
|
193
|
+
throw new Error(`Invalid address: ${address}`);
|
|
194
|
+
}
|
|
195
|
+
// Root address verification (Index 0)
|
|
196
|
+
if (index === 0) {
|
|
197
|
+
const bitgoPub = keychains && keychains.length > sdk_core_1.KeyIndices.BITGO ? keychains[sdk_core_1.KeyIndices.BITGO].pub : undefined;
|
|
198
|
+
if (!bitgoPub) {
|
|
199
|
+
throw new Error('BitGo public key required for root address verification');
|
|
200
|
+
}
|
|
201
|
+
return this.verifyRootAddress(address, bitgoPub);
|
|
202
|
+
}
|
|
203
|
+
// Receive address verification (Index > 0)
|
|
204
|
+
if (index > 0) {
|
|
205
|
+
const userPub = keychains && keychains.length > sdk_core_1.KeyIndices.USER ? keychains[sdk_core_1.KeyIndices.USER].pub : undefined;
|
|
206
|
+
if (!userPub) {
|
|
207
|
+
throw new Error('User public key required for receive address verification');
|
|
208
|
+
}
|
|
209
|
+
return this.verifyReceiveAddress(address, userPub, index, chain);
|
|
210
|
+
}
|
|
211
|
+
throw new Error('Invalid index for address verification');
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Cryptographically verify that an address is the root address derived from BitGo's public key
|
|
215
|
+
*/
|
|
216
|
+
verifyRootAddress(address, bitgoPub) {
|
|
217
|
+
if (!this.isValidXpub(bitgoPub)) {
|
|
218
|
+
throw new Error('Invalid bitgo public key');
|
|
219
|
+
}
|
|
220
|
+
const uncompressedPub = this.xpubToUncompressedPub(bitgoPub);
|
|
221
|
+
const byteArrayAddr = lib_1.Utils.getByteArrayFromHexAddress(uncompressedPub);
|
|
222
|
+
const rawAddress = lib_1.Utils.getRawAddressFromPubKey(byteArrayAddr);
|
|
223
|
+
const derivedAddress = lib_1.Utils.getBase58AddressFromByteArray(rawAddress);
|
|
224
|
+
return derivedAddress === address;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Cryptographically verify that an address is a receive address derived from user's key
|
|
228
|
+
*/
|
|
229
|
+
verifyReceiveAddress(address, userPub, index, chain) {
|
|
230
|
+
if (!this.isValidXpub(userPub)) {
|
|
231
|
+
throw new Error('Invalid user public key');
|
|
232
|
+
}
|
|
233
|
+
const derivationPath = `0/0/${chain}/${index}`;
|
|
234
|
+
const parentKey = secp256k1_1.bip32.fromBase58(userPub);
|
|
235
|
+
const childKey = parentKey.derivePath(derivationPath);
|
|
236
|
+
const derivedPubKeyHex = childKey.publicKey.toString('hex');
|
|
237
|
+
const keypair = new lib_1.KeyPair({ pub: derivedPubKeyHex });
|
|
238
|
+
const derivedAddress = keypair.getAddress();
|
|
239
|
+
return derivedAddress === address;
|
|
133
240
|
}
|
|
134
241
|
async verifyTransaction(params) {
|
|
242
|
+
const { txParams, txPrebuild, walletType } = params;
|
|
243
|
+
if (!txParams) {
|
|
244
|
+
throw new Error('missing txParams');
|
|
245
|
+
}
|
|
246
|
+
if (!txPrebuild) {
|
|
247
|
+
throw new Error('missing txPrebuild');
|
|
248
|
+
}
|
|
249
|
+
if (!txPrebuild.txHex) {
|
|
250
|
+
throw new Error('missing txHex in txPrebuild');
|
|
251
|
+
}
|
|
252
|
+
if (walletType === 'tss') {
|
|
253
|
+
// For TSS wallets, verifyTransaction is called from two places:
|
|
254
|
+
// 1. prebuildAndSignTransaction (wallet.ts) — txHex is serializedTxHex, a full JSON string
|
|
255
|
+
// containing { txID, raw_data, raw_data_hex }.
|
|
256
|
+
// 2. ECDSA signing flow (ecdsa.ts) — txHex is signableHex, the raw protobuf bytes (raw_data_hex).
|
|
257
|
+
// We need to extract the raw_data_hex in case 1 before decoding.
|
|
258
|
+
const rawDataHex = this.extractRawDataHex(txPrebuild.txHex);
|
|
259
|
+
const decodedTx = lib_1.Utils.decodeTransaction(rawDataHex);
|
|
260
|
+
// decodedTx uses a numeric enum for contract type (from protobuf decoding),
|
|
261
|
+
// unlike the multisig path which checks the string 'TransferContract' from node JSON.
|
|
262
|
+
if (decodedTx.contractType === lib_1.Enum.ContractType.Transfer) {
|
|
263
|
+
// For Transfer contracts, decoded contract is an array with one element.
|
|
264
|
+
// Addresses from decodeTransaction are already in base58 format (converted by decodeTransferContract).
|
|
265
|
+
if (!Array.isArray(decodedTx.contract) || decodedTx.contract.length !== 1) {
|
|
266
|
+
throw new Error('Invalid Transfer contract structure.');
|
|
267
|
+
}
|
|
268
|
+
return this.validateTransferContract(decodedTx.contract[0], txParams, true);
|
|
269
|
+
}
|
|
270
|
+
if (decodedTx.contractType === lib_1.Enum.ContractType.TriggerSmartContract) {
|
|
271
|
+
// TRC20 token transfers (TriggerSmartContract) must be verified via TrxToken.verifyTransaction,
|
|
272
|
+
// not here. Fail closed to prevent unvalidated token transfers from being silently signed.
|
|
273
|
+
throw new Error('TriggerSmartContract verification is not supported by native TRX. ' +
|
|
274
|
+
'TRC20 token transfers must be verified via TrxToken.verifyTransaction.');
|
|
275
|
+
}
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
// On-chain multisig path: txHex is a full transaction JSON string (with txID, raw_data, raw_data_hex).
|
|
279
|
+
// The builder parses this JSON and addresses remain in hex format from the node response.
|
|
280
|
+
const rawTx = txPrebuild.txHex;
|
|
281
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTx);
|
|
282
|
+
const tx = await txBuilder.build();
|
|
283
|
+
const txJson = tx.toJson();
|
|
284
|
+
if (!txJson.raw_data || !txJson.raw_data.contract || txJson.raw_data.contract.length !== 1) {
|
|
285
|
+
throw new Error('Number of contracts is greater than 1.');
|
|
286
|
+
}
|
|
287
|
+
const contract = txJson.raw_data.contract[0];
|
|
288
|
+
if (contract.type === 'TransferContract') {
|
|
289
|
+
return this.validateTransferContract(contract, txParams);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Extract the raw protobuf hex (raw_data_hex) from a TSS txHex.
|
|
297
|
+
*
|
|
298
|
+
* TSS verifyTransaction is called from two places:
|
|
299
|
+
* 1. prebuildAndSignTransaction — txHex is a full JSON string containing raw_data_hex.
|
|
300
|
+
* 2. ECDSA signing flow — txHex is already the raw protobuf hex (raw_data_hex).
|
|
301
|
+
*
|
|
302
|
+
* This helper handles both formats so callers don't duplicate the try/catch.
|
|
303
|
+
*/
|
|
304
|
+
extractRawDataHex(txHex) {
|
|
305
|
+
try {
|
|
306
|
+
return JSON.parse(txHex).raw_data_hex;
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
console.debug(`Could not parse txHex as JSON for coin ${this.getChain()}, using txHex directly`);
|
|
310
|
+
return txHex;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Validate Transfer contract (native TRX transfer).
|
|
315
|
+
* Shared by both on-chain multisig and TSS wallet verification paths.
|
|
316
|
+
*
|
|
317
|
+
* @param contract The contract object from the transaction
|
|
318
|
+
* @param txParams The original transaction parameters
|
|
319
|
+
* @param addressesInBase58 When true, addresses are already in base58 format (TSS path via protobuf decoding).
|
|
320
|
+
* When false (default), addresses are in hex and need conversion (on-chain multisig path via builder JSON).
|
|
321
|
+
*/
|
|
322
|
+
validateTransferContract(contract, txParams, addressesInBase58 = false) {
|
|
323
|
+
if (!('parameter' in contract) || !contract.parameter?.value) {
|
|
324
|
+
throw new Error('Invalid Transfer contract structure');
|
|
325
|
+
}
|
|
326
|
+
const value = contract.parameter.value;
|
|
327
|
+
// Validate amount
|
|
328
|
+
if (!value.amount || value.amount < 0) {
|
|
329
|
+
throw new Error('Invalid transfer amount');
|
|
330
|
+
}
|
|
331
|
+
// If txParams has recipients, validate against expected values
|
|
332
|
+
if (txParams.recipients && txParams.recipients.length === 1) {
|
|
333
|
+
const recipient = txParams.recipients[0];
|
|
334
|
+
const expectedAmount = recipient.amount.toString();
|
|
335
|
+
const expectedDestination = recipient.address;
|
|
336
|
+
const actualAmount = value.amount.toString();
|
|
337
|
+
const actualDestination = addressesInBase58 ? value.to_address : lib_1.Utils.getBase58AddressFromHex(value.to_address);
|
|
338
|
+
if (expectedAmount !== actualAmount) {
|
|
339
|
+
throw new Error('transaction amount in txPrebuild does not match the value given by client');
|
|
340
|
+
}
|
|
341
|
+
if (expectedDestination.toLowerCase() !== actualDestination.toLowerCase()) {
|
|
342
|
+
throw new Error('destination address does not match with the recipient address');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
135
345
|
return true;
|
|
136
346
|
}
|
|
347
|
+
/** @inheritDoc */
|
|
348
|
+
async getSignablePayload(serializedTx) {
|
|
349
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(serializedTx);
|
|
350
|
+
const rebuiltTransaction = await txBuilder.build();
|
|
351
|
+
return rebuiltTransaction.signablePayload;
|
|
352
|
+
}
|
|
137
353
|
/**
|
|
138
354
|
* Derive a user key using the chain path of the address
|
|
139
355
|
* @param key
|
|
@@ -141,7 +357,7 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
141
357
|
* @returns {string} derived private key
|
|
142
358
|
*/
|
|
143
359
|
deriveKeyWithPath({ key, path }) {
|
|
144
|
-
const keychain =
|
|
360
|
+
const keychain = secp256k1_1.bip32.fromBase58(key);
|
|
145
361
|
const derivedKeyNode = keychain.derivePath(path);
|
|
146
362
|
return derivedKeyNode.toBase58();
|
|
147
363
|
}
|
|
@@ -151,14 +367,12 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
151
367
|
* @param params
|
|
152
368
|
* @param params.txPrebuild {Object} prebuild object returned by platform
|
|
153
369
|
* @param params.prv {String} user prv
|
|
154
|
-
* @param params.wallet.addressVersion {String} this is the version of the Algorand multisig address generation format
|
|
155
370
|
* @returns Bluebird<SignedTransaction>
|
|
156
371
|
*/
|
|
157
372
|
async signTransaction(params) {
|
|
158
|
-
|
|
159
|
-
const txBuilder = builder_1.getBuilder(this.getChain()).from(params.txPrebuild.txHex);
|
|
373
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(params.txPrebuild.txHex);
|
|
160
374
|
let key;
|
|
161
|
-
const { chain, index } =
|
|
375
|
+
const { chain, index } = params.txPrebuild?.addressInfo ?? { chain: 0, index: 0 };
|
|
162
376
|
if (chain === 0 && index === 0) {
|
|
163
377
|
key = params.prv;
|
|
164
378
|
}
|
|
@@ -186,7 +400,7 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
186
400
|
*/
|
|
187
401
|
isValidXprv(prv) {
|
|
188
402
|
try {
|
|
189
|
-
return !
|
|
403
|
+
return !secp256k1_1.bip32.fromBase58(prv).isNeutered();
|
|
190
404
|
}
|
|
191
405
|
catch {
|
|
192
406
|
return false;
|
|
@@ -216,11 +430,10 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
216
430
|
* @param message
|
|
217
431
|
*/
|
|
218
432
|
async signMessage(key, message) {
|
|
219
|
-
var _a;
|
|
220
433
|
const toSign = this.toHexString(message);
|
|
221
434
|
let prv = key.prv;
|
|
222
435
|
if (this.isValidXprv(prv)) {
|
|
223
|
-
prv =
|
|
436
|
+
prv = secp256k1_1.bip32.fromBase58(prv).privateKey?.toString('hex');
|
|
224
437
|
}
|
|
225
438
|
if (!prv) {
|
|
226
439
|
throw new Error('no privateKey');
|
|
@@ -238,7 +451,7 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
238
451
|
if (!this.isValidXpub(xpub)) {
|
|
239
452
|
throw new Error('invalid xpub');
|
|
240
453
|
}
|
|
241
|
-
const publicKey =
|
|
454
|
+
const publicKey = secp256k1_1.bip32.fromBase58(xpub).publicKey;
|
|
242
455
|
return Buffer.from(secp256k1.publicKeyConvert(publicKey, false /* compressed */)).toString('hex');
|
|
243
456
|
}
|
|
244
457
|
/**
|
|
@@ -259,29 +472,29 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
259
472
|
if (!this.isValidXprv(xprv)) {
|
|
260
473
|
throw new Error('invalid xprv');
|
|
261
474
|
}
|
|
262
|
-
const hdNode =
|
|
475
|
+
const hdNode = secp256k1_1.bip32.fromBase58(xprv);
|
|
263
476
|
if (!hdNode.privateKey) {
|
|
264
477
|
throw new Error('no privateKey');
|
|
265
478
|
}
|
|
266
479
|
return hdNode.privateKey.toString('hex');
|
|
267
480
|
}
|
|
481
|
+
getNodeUrl(node) {
|
|
482
|
+
switch (node) {
|
|
483
|
+
case NodeTypes.Full:
|
|
484
|
+
return sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
|
|
485
|
+
case NodeTypes.Solidity:
|
|
486
|
+
return sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
|
|
487
|
+
default:
|
|
488
|
+
throw new Error('node type not found');
|
|
489
|
+
}
|
|
490
|
+
}
|
|
268
491
|
/**
|
|
269
492
|
* Make a query to Trongrid for information such as balance, token balance, solidity calls
|
|
270
493
|
* @param query {Object} key-value pairs of parameters to append after /api
|
|
271
494
|
* @returns {Object} response from Trongrid
|
|
272
495
|
*/
|
|
273
496
|
async recoveryPost(query) {
|
|
274
|
-
|
|
275
|
-
switch (query.node) {
|
|
276
|
-
case NodeTypes.Full:
|
|
277
|
-
nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
|
|
278
|
-
break;
|
|
279
|
-
case NodeTypes.Solidity:
|
|
280
|
-
nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
|
|
281
|
-
break;
|
|
282
|
-
default:
|
|
283
|
-
throw new Error('node type not found');
|
|
284
|
-
}
|
|
497
|
+
const nodeUri = this.getNodeUrl(query.node);
|
|
285
498
|
const response = await request
|
|
286
499
|
.post(nodeUri + query.path)
|
|
287
500
|
.type('json')
|
|
@@ -298,17 +511,7 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
298
511
|
* @returns {Object} response from Trongrid
|
|
299
512
|
*/
|
|
300
513
|
async recoveryGet(query) {
|
|
301
|
-
|
|
302
|
-
switch (query.node) {
|
|
303
|
-
case NodeTypes.Full:
|
|
304
|
-
nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.full;
|
|
305
|
-
break;
|
|
306
|
-
case NodeTypes.Solidity:
|
|
307
|
-
nodeUri = sdk_core_1.common.Environments[this.bitgo.getEnv()].tronNodes.solidity;
|
|
308
|
-
break;
|
|
309
|
-
default:
|
|
310
|
-
throw new Error('node type not found');
|
|
311
|
-
}
|
|
514
|
+
const nodeUri = this.getNodeUrl(query.node);
|
|
312
515
|
const response = await request
|
|
313
516
|
.get(nodeUri + query.path)
|
|
314
517
|
.type('json')
|
|
@@ -389,134 +592,294 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
389
592
|
}
|
|
390
593
|
});
|
|
391
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* Format for offline vault signing
|
|
597
|
+
* @param {BaseTransaction} tx
|
|
598
|
+
* @param {number} fee
|
|
599
|
+
* @param {number} recoveryAmount
|
|
600
|
+
* @returns {RecoveryTransaction}
|
|
601
|
+
*/
|
|
602
|
+
formatForOfflineVault(tx, fee, recoveryAmount, addressInfo) {
|
|
603
|
+
const txJSON = tx.toJson();
|
|
604
|
+
const format = {
|
|
605
|
+
txHex: JSON.stringify(txJSON),
|
|
606
|
+
recoveryAmount,
|
|
607
|
+
feeInfo: {
|
|
608
|
+
fee: `${fee}`,
|
|
609
|
+
},
|
|
610
|
+
tx: txJSON, // Leaving it as txJSON for backwards compatibility
|
|
611
|
+
coin: this.getChain(),
|
|
612
|
+
};
|
|
613
|
+
return addressInfo ? { ...format, addressInfo } : format;
|
|
614
|
+
}
|
|
392
615
|
/**
|
|
393
616
|
* Builds a funds recovery transaction without BitGo.
|
|
394
617
|
* We need to do three queries during this:
|
|
395
618
|
* 1) Node query - how much money is in the account
|
|
396
619
|
* 2) Build transaction - build our transaction for the amount
|
|
397
620
|
* 3) Send signed build - send our signed build to a public node
|
|
621
|
+
*
|
|
622
|
+
* Note 1: for base address recoveries, fund will be recovered to recovery destination if base address balance is
|
|
623
|
+
* more than 2.1 TRX for native TRX recovery and 100 TRX for token recover. For receive addresses, fund will be
|
|
624
|
+
* recovered to base address first then swept to base address(decided as the universal pattern in team meeting).
|
|
625
|
+
*
|
|
626
|
+
* Note 2: the function supports token sweep from base address.
|
|
627
|
+
* TODO: support token sweep from receive address.
|
|
628
|
+
*
|
|
398
629
|
* @param params
|
|
399
630
|
*/
|
|
400
631
|
async recover(params) {
|
|
401
|
-
const isKrsRecovery = sdk_core_1.getIsKrsRecovery(params);
|
|
402
|
-
const isUnsignedSweep = sdk_core_1.getIsUnsignedSweep(params);
|
|
632
|
+
const isKrsRecovery = (0, sdk_core_1.getIsKrsRecovery)(params);
|
|
633
|
+
const isUnsignedSweep = (0, sdk_core_1.getIsUnsignedSweep)(params);
|
|
403
634
|
if (!this.isValidAddress(params.recoveryDestination)) {
|
|
404
635
|
throw new Error('Invalid destination address!');
|
|
405
636
|
}
|
|
637
|
+
let startIdx = params.startingScanIndex;
|
|
638
|
+
if ((0, lodash_1.isUndefined)(startIdx)) {
|
|
639
|
+
startIdx = 1;
|
|
640
|
+
}
|
|
641
|
+
else if (!(0, lodash_1.isInteger)(startIdx) || startIdx < 0) {
|
|
642
|
+
throw new Error('Invalid starting index to scan for addresses');
|
|
643
|
+
}
|
|
644
|
+
let numIteration = params.scan;
|
|
645
|
+
if ((0, lodash_1.isUndefined)(numIteration)) {
|
|
646
|
+
numIteration = 20;
|
|
647
|
+
}
|
|
648
|
+
else if (typeof numIteration === 'string') {
|
|
649
|
+
numIteration = parseInt(numIteration, 10);
|
|
650
|
+
}
|
|
651
|
+
if (!(0, lodash_1.isInteger)(numIteration) || numIteration <= 0) {
|
|
652
|
+
throw new Error('Invalid scanning factor');
|
|
653
|
+
}
|
|
406
654
|
// get our user, backup keys
|
|
407
|
-
const keys = sdk_core_1.
|
|
655
|
+
const keys = await (0, sdk_core_1.getBip32KeysAsync)(this.bitgo, params, { requireBitGoXpub: false });
|
|
408
656
|
// we need to decode our bitgoKey to a base58 address
|
|
409
657
|
const bitgoHexAddr = this.pubToHexAddress(this.xpubToUncompressedPub(params.bitgoKey));
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
for
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
.
|
|
658
|
+
let recoveryFromAddrHex = bitgoHexAddr;
|
|
659
|
+
let recoveryToAddressHex = lib_1.Utils.getHexAddressFromBase58Address(params.recoveryDestination);
|
|
660
|
+
// call the node to get our account balance for base address
|
|
661
|
+
let account = await this.getAccountBalancesFromNode(lib_1.Utils.getBase58AddressFromHex(recoveryFromAddrHex));
|
|
662
|
+
let recoveryAmount = account.data[0].balance;
|
|
663
|
+
let userXPrv = keys[0].toBase58();
|
|
664
|
+
let isReceiveAddress = false;
|
|
665
|
+
let addressInfo;
|
|
666
|
+
const tokenContractAddr = params.tokenContractAddress;
|
|
667
|
+
// check for possible token recovery, recover the token provide by user
|
|
668
|
+
if (tokenContractAddr) {
|
|
669
|
+
let rawTokenTxn;
|
|
670
|
+
for (const token of account.data[0].trc20) {
|
|
671
|
+
if (token[tokenContractAddr]) {
|
|
672
|
+
const amount = token[tokenContractAddr];
|
|
673
|
+
const tokenContractAddrHex = lib_1.Utils.getHexAddressFromBase58Address(tokenContractAddr);
|
|
674
|
+
rawTokenTxn = (await this.getTriggerSmartContractTransaction(recoveryToAddressHex, recoveryFromAddrHex, amount, tokenContractAddrHex)).transaction;
|
|
675
|
+
recoveryAmount = parseInt(amount, 10);
|
|
676
|
+
break;
|
|
677
|
+
}
|
|
426
678
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
679
|
+
// build and sign token txns
|
|
680
|
+
if (rawTokenTxn) {
|
|
681
|
+
// Check there is sufficient of the native asset to cover fees
|
|
682
|
+
const trxBalance = account.data[0].balance;
|
|
683
|
+
if (trxBalance < exports.SAFE_TRON_TOKEN_TRANSACTION_FEE) {
|
|
684
|
+
throw new Error(`Amount of funds to recover ${trxBalance} is less than ${exports.SAFE_TRON_TOKEN_TRANSACTION_FEE} and wouldn't be able to fund a trc20 send`);
|
|
685
|
+
}
|
|
686
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTokenTxn);
|
|
687
|
+
// Default expiry is 1 minute which is too short for recovery purposes
|
|
688
|
+
// extend the expiry to 1 day
|
|
689
|
+
txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
|
|
690
|
+
// this tx should be enough to drop into a node
|
|
691
|
+
if (isUnsignedSweep) {
|
|
692
|
+
return this.formatForOfflineVault(await txBuilder.build(), exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount);
|
|
693
|
+
}
|
|
694
|
+
const userPrv = this.xprvToCompressedPrv(userXPrv);
|
|
695
|
+
txBuilder.sign({ key: userPrv });
|
|
696
|
+
// krs recoveries don't get signed
|
|
697
|
+
if (!isKrsRecovery && !isReceiveAddress) {
|
|
698
|
+
const backupXPrv = keys[1].toBase58();
|
|
699
|
+
const backupPrv = this.xprvToCompressedPrv(backupXPrv);
|
|
700
|
+
txBuilder.sign({ key: backupPrv });
|
|
701
|
+
}
|
|
702
|
+
return this.formatForOfflineVault(await txBuilder.build(), exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount);
|
|
433
703
|
}
|
|
434
|
-
else
|
|
435
|
-
|
|
436
|
-
const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TSdZwNqpHofzP6BsBKGQUWdBeJphLmF6id');
|
|
437
|
-
tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
|
|
438
|
-
.transaction);
|
|
704
|
+
else {
|
|
705
|
+
throw Error('Not found token to recover, please check token balance');
|
|
439
706
|
}
|
|
440
|
-
else if (token.TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs) {
|
|
441
|
-
const amount = token.TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs;
|
|
442
|
-
const contractAddr = lib_1.Utils.getHexAddressFromBase58Address('TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs');
|
|
443
|
-
tokenTxns.push((await this.getTriggerSmartContractTransaction(recoveryAddressHex, bitgoHexAddr, amount, contractAddr))
|
|
444
|
-
.transaction);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
// construct the tx -
|
|
448
|
-
// there's an assumption here being made about fees: for a wallet that hasn't been used in awhile, the implication is
|
|
449
|
-
// it has maximum bandwidth. thus, a recovery should cost the minimum amount (1e6 sun or 1 Tron)
|
|
450
|
-
if (exports.MINIMUM_TRON_MSIG_TRANSACTION_FEE > recoveryAmount) {
|
|
451
|
-
throw new Error('Amount of funds to recover wouldnt be able to fund a send');
|
|
452
707
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
activePermissionKeys.push({ address, weight });
|
|
470
|
-
}
|
|
471
|
-
this.checkPermissions(ownerKeys, keyHexAddresses);
|
|
472
|
-
this.checkPermissions(activePermissionKeys, keyHexAddresses);
|
|
473
|
-
// build and sign token txns
|
|
474
|
-
const finalTokenTxs = [];
|
|
475
|
-
for (const tokenTxn of tokenTxns) {
|
|
476
|
-
const txBuilder = builder_1.getBuilder(this.getChain()).from(tokenTxn);
|
|
477
|
-
// this tx should be enough to drop into a node
|
|
478
|
-
if (isUnsignedSweep) {
|
|
479
|
-
finalTokenTxs.push((await txBuilder.build()).toJson());
|
|
480
|
-
continue;
|
|
708
|
+
// let us recover the native Tron
|
|
709
|
+
if (recoveryAmount > exports.SAFE_TRON_TRANSACTION_FEE) {
|
|
710
|
+
const userXPub = keys[0].neutered().toBase58();
|
|
711
|
+
const backupXPub = keys[1].neutered().toBase58();
|
|
712
|
+
// check multisig permissions
|
|
713
|
+
const keyHexAddresses = [
|
|
714
|
+
this.pubToHexAddress(this.xpubToUncompressedPub(userXPub)),
|
|
715
|
+
this.pubToHexAddress(this.xpubToUncompressedPub(backupXPub)),
|
|
716
|
+
bitgoHexAddr,
|
|
717
|
+
];
|
|
718
|
+
// run checks to ensure this is a valid tx - permissions match our signer keys
|
|
719
|
+
const ownerKeys = [];
|
|
720
|
+
for (const key of account.data[0].owner_permission.keys) {
|
|
721
|
+
const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
|
|
722
|
+
const weight = key.weight;
|
|
723
|
+
ownerKeys.push({ address, weight });
|
|
481
724
|
}
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
725
|
+
const activePermissionKeys = [];
|
|
726
|
+
for (const key of account.data[0].active_permission[0].keys) {
|
|
727
|
+
const address = lib_1.Utils.getHexAddressFromBase58Address(key.address);
|
|
728
|
+
const weight = key.weight;
|
|
729
|
+
activePermissionKeys.push({ address, weight });
|
|
730
|
+
}
|
|
731
|
+
this.checkPermissions(ownerKeys, keyHexAddresses);
|
|
732
|
+
this.checkPermissions(activePermissionKeys, keyHexAddresses);
|
|
733
|
+
}
|
|
734
|
+
else {
|
|
735
|
+
// Check receive addresses for funds
|
|
736
|
+
// Check for first derived wallet with funds
|
|
737
|
+
// Receive addresses are derived from the user key
|
|
738
|
+
for (let i = startIdx; i < numIteration + startIdx; i++) {
|
|
739
|
+
const derivationPath = `0/0/0/${i}`;
|
|
740
|
+
const userKey = keys[0].derivePath(derivationPath);
|
|
741
|
+
const xpub = userKey.neutered();
|
|
742
|
+
const receiveAddress = this.pubToHexAddress(this.xpubToUncompressedPub(xpub.toBase58()));
|
|
743
|
+
const address = lib_1.Utils.getBase58AddressFromHex(receiveAddress);
|
|
744
|
+
// call the node to get our account balance
|
|
745
|
+
const accountInfo = await this.getAccountBalancesFromNode(address);
|
|
746
|
+
if (accountInfo.data[0] && accountInfo.data[0].balance > exports.SAFE_TRON_TRANSACTION_FEE) {
|
|
747
|
+
account = accountInfo;
|
|
748
|
+
recoveryAmount = accountInfo.data[0].balance;
|
|
749
|
+
userXPrv = userKey.toBase58(); // assign derived userXPrx
|
|
750
|
+
isReceiveAddress = true;
|
|
751
|
+
recoveryFromAddrHex = receiveAddress;
|
|
752
|
+
recoveryToAddressHex = bitgoHexAddr;
|
|
753
|
+
addressInfo = {
|
|
754
|
+
address,
|
|
755
|
+
chain: 0,
|
|
756
|
+
index: i,
|
|
757
|
+
};
|
|
758
|
+
break;
|
|
759
|
+
}
|
|
489
760
|
}
|
|
490
|
-
finalTokenTxs.push((await txBuilder.build()).toJson());
|
|
491
761
|
}
|
|
492
|
-
//
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
};
|
|
762
|
+
// a sweep potentially needs to pay for multi-sig transfer, destination account activation and bandwidth
|
|
763
|
+
// TRON foundation recommends 2.1 TRX for guaranteed confirmation
|
|
764
|
+
if (!recoveryAmount || exports.SAFE_TRON_TRANSACTION_FEE >= recoveryAmount) {
|
|
765
|
+
throw new Error(`Amount of funds to recover ${recoveryAmount} is less than ${exports.SAFE_TRON_TRANSACTION_FEE} and wouldn't be able to fund a send`);
|
|
497
766
|
}
|
|
498
|
-
const recoveryAmountMinusFees = recoveryAmount - exports.
|
|
499
|
-
const buildTx = await this.getBuildTransaction(
|
|
767
|
+
const recoveryAmountMinusFees = recoveryAmount - exports.SAFE_TRON_TRANSACTION_FEE;
|
|
768
|
+
const buildTx = await this.getBuildTransaction(recoveryToAddressHex, recoveryFromAddrHex, recoveryAmountMinusFees);
|
|
500
769
|
// construct our tx
|
|
501
|
-
const txBuilder = builder_1.getBuilder(this.getChain()).from(buildTx);
|
|
770
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(buildTx);
|
|
771
|
+
// Default expiry is 1 minute which is too short for recovery purposes
|
|
772
|
+
// extend the expiry to 1 day
|
|
773
|
+
txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
|
|
774
|
+
const tx = await txBuilder.build();
|
|
502
775
|
// this tx should be enough to drop into a node
|
|
503
776
|
if (isUnsignedSweep) {
|
|
504
|
-
return
|
|
505
|
-
tx: (await txBuilder.build()).toJson(),
|
|
506
|
-
recoveryAmount: recoveryAmountMinusFees,
|
|
507
|
-
};
|
|
777
|
+
return this.formatForOfflineVault(tx, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo);
|
|
508
778
|
}
|
|
509
779
|
const userPrv = this.xprvToCompressedPrv(userXPrv);
|
|
510
780
|
txBuilder.sign({ key: userPrv });
|
|
511
781
|
// krs recoveries don't get signed
|
|
512
|
-
if (!isKrsRecovery) {
|
|
782
|
+
if (!isKrsRecovery && !isReceiveAddress) {
|
|
513
783
|
const backupXPrv = keys[1].toBase58();
|
|
514
784
|
const backupPrv = this.xprvToCompressedPrv(backupXPrv);
|
|
515
785
|
txBuilder.sign({ key: backupPrv });
|
|
516
786
|
}
|
|
787
|
+
const txSigned = await txBuilder.build();
|
|
788
|
+
return this.formatForOfflineVault(txSigned, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmountMinusFees, addressInfo);
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Builds native TRX recoveries of receive addresses in batch without BitGo.
|
|
792
|
+
* Funds will be recovered to base address first. You need to initiate another sweep txn after that.
|
|
793
|
+
* Note: there will be another recoverTokenConsolidations function to support token recover from receive addresses.
|
|
794
|
+
*
|
|
795
|
+
* @param {ConsolidationRecoveryOptions} params - options for consolidation recovery.
|
|
796
|
+
* @param {string} [params.startingScanIndex] - receive address index to start scanning from. default to 1 (inclusive).
|
|
797
|
+
* @param {string} [params.endingScanIndex] - receive address index to end scanning at. default to startingScanIndex + 20 (exclusive).
|
|
798
|
+
*/
|
|
799
|
+
async recoverConsolidations(params) {
|
|
800
|
+
const isUnsignedConsolidations = (0, sdk_core_1.getIsUnsignedSweep)(params);
|
|
801
|
+
const startIdx = params.startingScanIndex || 1;
|
|
802
|
+
const endIdx = params.endingScanIndex || startIdx + exports.DEFAULT_SCAN_FACTOR;
|
|
803
|
+
if (startIdx < 1 || endIdx <= startIdx || endIdx - startIdx > 10 * exports.DEFAULT_SCAN_FACTOR) {
|
|
804
|
+
throw new Error(`Invalid starting or ending index to scan for addresses. startingScanIndex: ${startIdx}, endingScanIndex: ${endIdx}.`);
|
|
805
|
+
}
|
|
806
|
+
const keys = await (0, sdk_core_1.getBip32KeysAsync)(this.bitgo, params, { requireBitGoXpub: false });
|
|
807
|
+
const baseAddrHex = this.pubToHexAddress(this.xpubToUncompressedPub(params.bitgoKey));
|
|
808
|
+
const txnsBatch = [];
|
|
809
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
810
|
+
const derivationPath = `0/0/0/${i}`;
|
|
811
|
+
const userKey = keys[0].derivePath(derivationPath);
|
|
812
|
+
const userKeyXPub = userKey.neutered();
|
|
813
|
+
const receiveAddressHex = this.pubToHexAddress(this.xpubToUncompressedPub(userKeyXPub.toBase58()));
|
|
814
|
+
const receiveAddress = lib_1.Utils.getBase58AddressFromHex(receiveAddressHex);
|
|
815
|
+
// call the node to get our account balance
|
|
816
|
+
const accountInfo = await this.getAccountBalancesFromNode(receiveAddress);
|
|
817
|
+
if (accountInfo.data[0] && accountInfo.data[0].balance > exports.SAFE_TRON_TRANSACTION_FEE) {
|
|
818
|
+
let recoveryAmount = 0;
|
|
819
|
+
// Tokens must be consolidate before the native asset. First construct token txns
|
|
820
|
+
let rawTokenTxn;
|
|
821
|
+
// check for possible token recovery, recover the token provide by user
|
|
822
|
+
if (params.tokenContractAddress) {
|
|
823
|
+
if (accountInfo.data[0].balance > exports.SAFE_TRON_TOKEN_TRANSACTION_FEE && accountInfo.data[0].trc20[0]) {
|
|
824
|
+
const tokenDataArray = accountInfo.data[0].trc20;
|
|
825
|
+
for (const tokenData of tokenDataArray) {
|
|
826
|
+
const contractAddress = Object.keys(tokenData);
|
|
827
|
+
if (params.tokenContractAddress === contractAddress[0]) {
|
|
828
|
+
const amount = tokenData[contractAddress[0]];
|
|
829
|
+
const tokenContractAddrHex = lib_1.Utils.getHexAddressFromBase58Address(contractAddress[0]);
|
|
830
|
+
rawTokenTxn = (await this.getTriggerSmartContractTransaction(baseAddrHex, receiveAddressHex, amount, tokenContractAddrHex)).transaction;
|
|
831
|
+
recoveryAmount = parseInt(amount, 10);
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
// build and sign token txns
|
|
837
|
+
if (rawTokenTxn) {
|
|
838
|
+
const addressInfo = {
|
|
839
|
+
address: receiveAddress,
|
|
840
|
+
chain: 0,
|
|
841
|
+
index: i,
|
|
842
|
+
};
|
|
843
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(rawTokenTxn);
|
|
844
|
+
// Default expiry is 1 minute which is too short for recovery purposes
|
|
845
|
+
// extend the expiry to 1 day
|
|
846
|
+
txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
|
|
847
|
+
// this tx should be enough to drop into a node
|
|
848
|
+
if (!isUnsignedConsolidations) {
|
|
849
|
+
const userPrv = this.xprvToCompressedPrv(userKey.toBase58());
|
|
850
|
+
// receive address only needs to be signed by user key
|
|
851
|
+
txBuilder.sign({ key: userPrv });
|
|
852
|
+
}
|
|
853
|
+
const tx = await txBuilder.build();
|
|
854
|
+
txnsBatch.push(this.formatForOfflineVault(tx, exports.SAFE_TRON_TOKEN_TRANSACTION_FEE, recoveryAmount, addressInfo));
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
const addressBalance = accountInfo.data[0].balance;
|
|
859
|
+
const addressInfo = {
|
|
860
|
+
address: receiveAddress,
|
|
861
|
+
chain: 0,
|
|
862
|
+
index: i,
|
|
863
|
+
};
|
|
864
|
+
const recoveryAmount = addressBalance - exports.SAFE_TRON_TRANSACTION_FEE;
|
|
865
|
+
const buildTx = await this.getBuildTransaction(baseAddrHex, receiveAddressHex, recoveryAmount);
|
|
866
|
+
// construct our tx
|
|
867
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(buildTx);
|
|
868
|
+
// Default expiry is 1 minute which is too short for recovery purposes
|
|
869
|
+
// extend the expiry to 1 day
|
|
870
|
+
txBuilder.extendValidTo(exports.RECOVER_TRANSACTION_EXPIRY);
|
|
871
|
+
if (!isUnsignedConsolidations) {
|
|
872
|
+
const userPrv = this.xprvToCompressedPrv(userKey.toBase58());
|
|
873
|
+
// receive address only needs to be signed by user key
|
|
874
|
+
txBuilder.sign({ key: userPrv });
|
|
875
|
+
}
|
|
876
|
+
const tx = await txBuilder.build();
|
|
877
|
+
txnsBatch.push(this.formatForOfflineVault(tx, exports.SAFE_TRON_TRANSACTION_FEE, recoveryAmount, addressInfo));
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
}
|
|
517
881
|
return {
|
|
518
|
-
|
|
519
|
-
recoveryAmount: recoveryAmountMinusFees,
|
|
882
|
+
transactions: txnsBatch,
|
|
520
883
|
};
|
|
521
884
|
}
|
|
522
885
|
/**
|
|
@@ -528,7 +891,7 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
528
891
|
if (!txHex || !params.feeInfo) {
|
|
529
892
|
throw new Error('missing explain tx parameters');
|
|
530
893
|
}
|
|
531
|
-
const txBuilder = builder_1.getBuilder(this.getChain()).from(txHex);
|
|
894
|
+
const txBuilder = (0, builder_1.getBuilder)(this.getChain()).from(txHex);
|
|
532
895
|
const tx = await txBuilder.build();
|
|
533
896
|
const outputs = [
|
|
534
897
|
{
|
|
@@ -551,13 +914,22 @@ class Trx extends sdk_core_1.BaseCoin {
|
|
|
551
914
|
id: tx.id,
|
|
552
915
|
outputs,
|
|
553
916
|
outputAmount: outputs[0].amount,
|
|
554
|
-
changeOutputs: [],
|
|
555
|
-
changeAmount: '0',
|
|
917
|
+
changeOutputs: [], // account based does not use change outputs
|
|
918
|
+
changeAmount: '0', // account base does not make change
|
|
556
919
|
fee: params.feeInfo,
|
|
557
920
|
timestamp: tx.validFrom,
|
|
558
921
|
expiration: tx.validTo,
|
|
559
922
|
};
|
|
560
923
|
}
|
|
924
|
+
/** @inheritDoc */
|
|
925
|
+
auditDecryptedKey({ multiSigType, publicKey, prv }) {
|
|
926
|
+
if (multiSigType === 'tss') {
|
|
927
|
+
(0, sdk_lib_mpc_1.auditEcdsaPrivateKey)(prv, publicKey);
|
|
928
|
+
}
|
|
929
|
+
else {
|
|
930
|
+
throw new sdk_core_1.MethodNotImplementedError();
|
|
931
|
+
}
|
|
932
|
+
}
|
|
561
933
|
}
|
|
562
934
|
exports.Trx = Trx;
|
|
563
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyeC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0dBRUc7QUFDSCxxREFBdUM7QUFDdkMsbUNBQXFDO0FBRXJDLG1EQUF1RDtBQUN2RCxvREFBc0M7QUFDdEMsbURBbUI4QjtBQUM5QiwrQkFBeUQ7QUFDekQsMkNBQTJDO0FBRzlCLFFBQUEsaUNBQWlDLEdBQUcsR0FBRyxDQUFDO0FBc0RyRCxJQUFZLFNBR1g7QUFIRCxXQUFZLFNBQVM7SUFDbkIseUNBQUksQ0FBQTtJQUNKLGlEQUFRLENBQUE7QUFDVixDQUFDLEVBSFcsU0FBUyxHQUFULGlCQUFTLEtBQVQsaUJBQVMsUUFHcEI7QUFTRCxNQUFhLEdBQUksU0FBUSxtQkFBUTtJQUcvQixZQUFZLEtBQWdCLEVBQUUsV0FBdUM7UUFDbkUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7U0FDdkU7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNsQyxDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7SUFDaEMsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxXQUFXO1FBQ1QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztJQUNwQyxDQUFDO0lBRUQsYUFBYTtRQUNYLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLHNCQUFzQjtRQUNwQixPQUFPLElBQUksQ0FBQztJ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NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBDb2luRmFtaWx5LCBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IGJpcDMyLCBuZXR3b3JrcyB9IGZyb20gJ0BiaXRnby1iZXRhL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBjb21tb24sXG4gIGdldEJpcDMyS2V5cyxcbiAgZ2V0SXNLcnNSZWNvdmVyeSxcbiAgZ2V0SXNVbnNpZ25lZFN3ZWVwLFxuICBLZXlQYWlyLFxuICBNZXRob2ROb3RJbXBsZW1lbnRlZEVycm9yLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUcmFuc2FjdGlvbkZlZSxcbiAgVHJhbnNhY3Rpb25QcmVidWlsZCBhcyBCYXNlVHJhbnNhY3Rpb25QcmVidWlsZCxcbiAgVHJhbnNhY3Rpb25SZWNpcGllbnQgYXMgUmVjaXBpZW50LFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBJbnRlcmZhY2UsIFV0aWxzLCBXcmFwcGVkQnVpbGRlciB9IGZyb20gJy4vbGliJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2xpYi9idWlsZGVyJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uUmVjZWlwdCB9IGZyb20gJy4vbGliL2lmYWNlJztcblxuZXhwb3J0IGNvbnN0IE1JTklNVU1fVFJPTl9NU0lHX1RSQU5TQUNUSU9OX0ZFRSA9IDFlNjtcblxuZXhwb3J0IGludGVyZmFjZSBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyBleHRlbmRzIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICBwcnY6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUeEluZm8ge1xuICByZWNpcGllbnRzOiBSZWNpcGllbnRbXTtcbiAgZnJvbTogc3RyaW5nO1xuICB0eGlkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkcmVzc0luZm8ge1xuICBhZGRyZXNzOiBzdHJpbmc7XG4gIGNoYWluOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJvblRyYW5zYWN0aW9uRXhwbGFuYXRpb24gZXh0ZW5kcyBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uIHtcbiAgZXhwaXJhdGlvbjogbnVtYmVyO1xuICB0aW1lc3RhbXA6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uUHJlYnVpbGQge1xuICB0eEhleDogc3RyaW5nO1xuICB0eEluZm86IFR4SW5mbztcbiAgYWRkcmVzc0luZm8/OiBBZGRyZXNzSW5mbztcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4SGV4Pzogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgaGFsZlNpZ25lZD86IHtcbiAgICB0eEhleDogc3RyaW5nOyAvLyB0eEhleCBpcyBwb29ybHkgbmFtZWQgaGVyZTsgaXQgaXMganVzdCBhIHdyYXBwZWQgSlNPTiBvYmplY3RcbiAgfTtcbiAgZmVlSW5mbzogVHJhbnNhY3Rpb25GZWU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3ZlcnlPcHRpb25zIHtcbiAgdXNlcktleTogc3RyaW5nOyAvLyBCb3ggQVxuICBiYWNrdXBLZXk6IHN0cmluZzsgLy8gQm94IEJcbiAgYml0Z29LZXk6IHN0cmluZzsgLy8gQm94IEMgLSB0aGlzIGlzIGJpdGdvJ3MgeHB1YiBhbmQgd2lsbCBiZSB1c2VkIHRvIGRlcml2ZSB0aGVpciByb290IGFkZHJlc3NcbiAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogc3RyaW5nOyAvLyBiYXNlNTggYWRkcmVzc1xuICBrcnNQcm92aWRlcj86IHN0cmluZztcbiAgd2FsbGV0UGFzc3BocmFzZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyeVRyYW5zYWN0aW9uIHtcbiAgdHg/OiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICByZWNvdmVyeUFtb3VudD86IG51bWJlcjtcbiAgdG9rZW5UeHM/OiBUcmFuc2FjdGlvblJlY2VpcHRbXTtcbn1cblxuZXhwb3J0IGVudW0gTm9kZVR5cGVzIHtcbiAgRnVsbCxcbiAgU29saWRpdHksXG59XG5cbi8qKlxuICogVGhpcyBzdHJ1Y3R1cmUgaXMgbm90IGEgY29tcGxldGUgbW9kZWwgb2YgdGhlIEFjY291bnRSZXNwb25zZSBmcm9tIGEgbm9kZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY2NvdW50UmVzcG9uc2Uge1xuICBkYXRhOiBbSW50ZXJmYWNlLkFjY291bnRJbmZvXTtcbn1cblxuZXhwb3J0IGNsYXNzIFRyeCBleHRlbmRzIEJhc2VDb2luIHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdGF0aWNzQ29pbjogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPjtcblxuICBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pIHtcbiAgICBzdXBlcihiaXRnbyk7XG5cbiAgICBpZiAoIXN0YXRpY3NDb2luKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgcmVxdWlyZWQgY29uc3RydWN0b3IgcGFyYW1ldGVyIHN0YXRpY3NDb2luJyk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RhdGljc0NvaW4gPSBzdGF0aWNzQ29pbjtcbiAgfVxuXG4gIGdldENoYWluKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5uYW1lO1xuICB9XG5cbiAgZ2V0RmFtaWx5KCk6IENvaW5GYW1pbHkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mYW1pbHk7XG4gIH1cblxuICBnZXRGdWxsTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGljc0NvaW4uZnVsbE5hbWU7XG4gIH1cblxuICBnZXRCYXNlRmFjdG9yKCkge1xuICAgIHJldHVybiBNYXRoLnBvdygxMCwgdGhpcy5fc3RhdGljc0NvaW4uZGVjaW1hbFBsYWNlcyk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdHJhbnNhY3Rpb25EYXRhQWxsb3dlZCgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBUcngoYml0Z28sIHN0YXRpY3NDb2luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGJhc2U1OCBvciBoZXggYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFhZGRyZXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmlzVmFsaWRIZXhBZGRyZXNzKGFkZHJlc3MpIHx8IFV0aWxzLmlzQmFzZTU4QWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGhleCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhZGRyZXNzIGhleCBhZGRyZXNzXG4gICAqL1xuICBpc1ZhbGlkSGV4QWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gYWRkcmVzcy5sZW5ndGggPT09IDQyICYmIC9eKDB4KT8oWzAtOWEtZl17Mn0pKyQvaS50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGVkMjU1MTkga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiwgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIC8vIFRPRE86IG1vdmUgdGhpcyBhbmQgYWRkcmVzcyBjcmVhdGlvbiBsb2dpYyB0byBhY2NvdW50LWxpYlxuICAgIGlmICghc2VlZCkge1xuICAgICAgLy8gQW4gZXh0ZW5kZWQgcHJpdmF0ZSBrZXkgaGFzIGJvdGggYSBub3JtYWwgMjU2IGJpdCBwcml2YXRlIGtleSBhbmQgYSAyNTYgYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZVxuICAgICAgLy8gcmFuZG9tLiA1MTIgYml0cyBpcyB0aGVyZWZvcmUgdGhlIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBoZCA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGhkLm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogaGQudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgaXNWYWxpZFhwdWIoeHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzVmFsaWRYcHViKHB1YikpIHtcbiAgICAgIC8vIHhwdWJzIGNhbiBiZSBjb252ZXJ0ZWQgaW50byByZWd1bGFyIHB1YnMsIHNvIHRlY2huaWNhbGx5IGl0IGlzIGEgdmFsaWQgcHViXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoJ14wNFthLXpBLVowLTldezEyOH0kJykudGVzdChwdWIpO1xuICB9XG5cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdGhyb3cgbmV3IE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IoKTtcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGVyaXZlIGEgdXNlciBrZXkgdXNpbmcgdGhlIGNoYWluIHBhdGggb2YgdGhlIGFkZHJlc3NcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gcGF0aFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBkZXJpdmVkIHByaXZhdGUga2V5XG4gICAqL1xuICBkZXJpdmVLZXlXaXRoUGF0aCh7IGtleSwgcGF0aCB9OiB7IGtleTogc3RyaW5nOyBwYXRoOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgY29uc3Qga2V5Y2hhaW4gPSBiaXAzMi5mcm9tQmFzZTU4KGtleSk7XG4gICAgY29uc3QgZGVyaXZlZEtleU5vZGUgPSBrZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpO1xuICAgIHJldHVybiBkZXJpdmVkS2V5Tm9kZS50b0Jhc2U1OCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge09iamVjdH0gcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHBsYXRmb3JtXG4gICAqIEBwYXJhbSBwYXJhbXMucHJ2IHtTdHJpbmd9IHVzZXIgcHJ2XG4gICAqIEBwYXJhbSBwYXJhbXMud2FsbGV0LmFkZHJlc3NWZXJzaW9uIHtTdHJpbmd9IHRoaXMgaXMgdGhlIHZlcnNpb24gb2YgdGhlIEFsZ29yYW5kIG11bHRpc2lnIGFkZHJlc3MgZ2VuZXJhdGlvbiBmb3JtYXRcbiAgICogQHJldHVybnMgQmx1ZWJpcmQ8U2lnbmVkVHJhbnNhY3Rpb24+XG4gICAqL1xuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBUcm9uU2lnblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8U2lnbmVkVHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbShwYXJhbXMudHhQcmVidWlsZC50eEhleCk7XG5cbiAgICBsZXQga2V5O1xuICAgIGNvbnN0IHsgY2hhaW4sIGluZGV4IH0gPSBwYXJhbXMudHhQcmVidWlsZD8uYWRkcmVzc0luZm8gPz8geyBjaGFpbjogMCwgaW5kZXg6IDAgfTtcbiAgICBpZiAoY2hhaW4gPT09IDAgJiYgaW5kZXggPT09IDApIHtcbiAgICAgIGtleSA9IHBhcmFtcy5wcnY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gYDAvMC8ke2NoYWlufS8ke2luZGV4fWA7XG4gICAgICBrZXkgPSB0aGlzLmRlcml2ZUtleVdpdGhQYXRoKHsga2V5OiBwYXJhbXMucHJ2LCBwYXRoOiBkZXJpdmF0aW9uUGF0aCB9KTtcbiAgICB9XG4gICAgdHhCdWlsZGVyLnNpZ24oeyBrZXkgfSk7XG5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgdHhIZXg6IEpTT04uc3RyaW5naWZ5KHRyYW5zYWN0aW9uLnRvSnNvbigpKSxcbiAgICB9O1xuICAgIGlmICh0cmFuc2FjdGlvbi50b0pzb24oKS5zaWduYXR1cmUubGVuZ3RoID49IDIpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG4gICAgLy8gSGFsZiBzaWduZWQgdHJhbnNhY3Rpb25cbiAgICByZXR1cm4ge1xuICAgICAgaGFsZlNpZ25lZDogcmVzcG9uc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgc2VlZCBmb3IgdGhlIGNvaW5cbiAgICpcbiAgICogQHBhcmFtIHBydiAtIHRoZSBwcnYgdG8gYmUgY2hlY2tlZFxuICAgKi9cbiAgaXNWYWxpZFhwcnYocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICFiaXAzMi5mcm9tQmFzZTU4KHBydikuaXNOZXV0ZXJlZCgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgbWVzc2FnZSB0byBzdHJpbmcgaW4gaGV4YWRlY2ltYWwgZm9ybWF0LlxuICAgKlxuICAgKiBAcGFyYW0gbWVzc2FnZSB7QnVmZmVyfFN0cmluZ30gbWVzc2FnZSB0byBzaWduXG4gICAqIEByZXR1cm4gdGhlIG1lc3NhZ2UgYXMgYSBoZXhhZGVjaW1hbCBzdHJpbmdcbiAgICovXG4gIHRvSGV4U3RyaW5nKG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKG1lc3NhZ2UpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihtZXNzYWdlKSkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2UudG9TdHJpbmcoJ2hleCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgbWVzc2FnZWQgcGFzc2VkIHRvIHNpZ25NZXNzYWdlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNpZ24gbWVzc2FnZSB3aXRoIHByaXZhdGUga2V5XG4gICAqXG4gICAqIEBwYXJhbSBrZXlcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICovXG4gIGFzeW5jIHNpZ25NZXNzYWdlKGtleTogS2V5UGFpciwgbWVzc2FnZTogc3RyaW5nIHwgQnVmZmVyKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBjb25zdCB0b1NpZ24gPSB0aGlzLnRvSGV4U3RyaW5nKG1lc3NhZ2UpO1xuXG4gICAgbGV0IHBydjogc3RyaW5nIHwgdW5kZWZpbmVkID0ga2V5LnBydjtcbiAgICBpZiAodGhpcy5pc1ZhbGlkWHBydihwcnYpKSB7XG4gICAgICBwcnYgPSBiaXAzMi5mcm9tQmFzZTU4KHBydikucHJpdmF0ZUtleT8udG9TdHJpbmcoJ2hleCcpO1xuICAgIH1cblxuICAgIGlmICghcHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgbGV0IHNpZyA9IFV0aWxzLnNpZ25TdHJpbmcodG9TaWduLCBwcnYsIHRydWUpO1xuXG4gICAgLy8gcmVtb3ZlIHRoZSBwcmVjZWRpbmcgMHhcbiAgICBzaWcgPSBzaWcucmVwbGFjZSgvXjB4LywgJycpO1xuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNpZywgJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIGFuIHhwdWIgdG8gYSB1bmNvbXByZXNzZWQgcHViXG4gICAqIEBwYXJhbSB4cHViXG4gICAqL1xuICB4cHViVG9VbmNvbXByZXNzZWRQdWIoeHB1Yjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuaXNWYWxpZFhwdWIoeHB1YikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCB4cHViJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcHVibGljS2V5ID0gYmlwMzIuZnJvbUJhc2U1OCh4cHViLCBuZXR3b3Jrcy5iaXRjb2luKS5wdWJsaWNLZXk7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNlY3AyNTZrMS5wdWJsaWNLZXlDb252ZXJ0KHB1YmxpY0tleSwgZmFsc2UgLyogY29tcHJlc3NlZCAqLykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RpZnkgcHJlYnVpbGQgYmVmb3JlIHNlbmRpbmcgaXQgdG8gdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGJ1aWxkUGFyYW1zIFRoZSB3aGl0ZWxpc3RlZCBwYXJhbWV0ZXJzIGZvciB0aGlzIHByZWJ1aWxkXG4gICAqL1xuICBhc3luYyBnZXRFeHRyYVByZWJ1aWxkUGFyYW1zKGJ1aWxkUGFyYW1zOiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgIGlmIChidWlsZFBhcmFtcy5yZWNpcGllbnRzWzBdLmRhdGEgJiYgYnVpbGRQYXJhbXMuZmVlTGltaXQpIHtcbiAgICAgIGJ1aWxkUGFyYW1zLnJlY2lwaWVudHNbMF0uZmVlTGltaXQgPSBidWlsZFBhcmFtcy5mZWVMaW1pdDtcbiAgICB9XG4gIH1cblxuICBwdWJUb0hleEFkZHJlc3MocHViOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJ5dGVBcnJheUFkZHIgPSBVdGlscy5nZXRCeXRlQXJyYXlGcm9tSGV4QWRkcmVzcyhwdWIpO1xuICAgIGNvbnN0IHJhd0FkZHJlc3MgPSBVdGlscy5nZXRSYXdBZGRyZXNzRnJvbVB1YktleShieXRlQXJyYXlBZGRyKTtcbiAgICByZXR1cm4gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CeXRlQXJyYXkocmF3QWRkcmVzcyk7XG4gIH1cblxuICB4cHJ2VG9Db21wcmVzc2VkUHJ2KHhwcnY6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRYcHJ2KHhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgeHBydicpO1xuICAgIH1cblxuICAgIGNvbnN0IGhkTm9kZSA9IGJpcDMyLmZyb21CYXNlNTgoeHBydiwgbmV0d29ya3MuYml0Y29pbik7XG4gICAgaWYgKCFoZE5vZGUucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIHJldHVybiBoZE5vZGUucHJpdmF0ZUtleS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5UG9zdChxdWVyeTogeyBwYXRoOiBzdHJpbmc7IGpzb25PYmo6IGFueTsgbm9kZTogTm9kZVR5cGVzIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGxldCBub2RlVXJpID0gJyc7XG4gICAgc3dpdGNoIChxdWVyeS5ub2RlKSB7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5GdWxsOlxuICAgICAgICBub2RlVXJpID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuZnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5Tb2xpZGl0eTpcbiAgICAgICAgbm9kZVVyaSA9IGNvbW1vbi5FbnZpcm9ubWVudHNbdGhpcy5iaXRnby5nZXRFbnYoKV0udHJvbk5vZGVzLnNvbGlkaXR5O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm9kZSB0eXBlIG5vdCBmb3VuZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFxuICAgICAgLnBvc3Qobm9kZVVyaSArIHF1ZXJ5LnBhdGgpXG4gICAgICAudHlwZSgnanNvbicpXG4gICAgICAuc2VuZChxdWVyeS5qc29uT2JqKTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY291bGQgbm90IHJlYWNoIFRyb24gbm9kZScpO1xuICAgIH1cblxuICAgIC8vIHVuZm9ydHVuYXRlbHksIGl0IGRvZXNuJ3QgbG9vayBsaWtlIG1vc3QgVFJPTiBub2RlcyByZXR1cm4gdmFsaWQganNvbiBhcyBib2R5XG4gICAgcmV0dXJuIEpTT04ucGFyc2UocmVzcG9uc2UudGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBhIHF1ZXJ5IHRvIFRyb25ncmlkIGZvciBpbmZvcm1hdGlvbiBzdWNoIGFzIGJhbGFuY2UsIHRva2VuIGJhbGFuY2UsIHNvbGlkaXR5IGNhbGxzXG4gICAqIEBwYXJhbSBxdWVyeSB7T2JqZWN0fSBrZXktdmFsdWUgcGFpcnMgb2YgcGFyYW1ldGVycyB0byBhcHBlbmQgYWZ0ZXIgL2FwaVxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSByZXNwb25zZSBmcm9tIFRyb25ncmlkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlY292ZXJ5R2V0KHF1ZXJ5OiB7IHBhdGg6IHN0cmluZzsganNvbk9iajogYW55OyBub2RlOiBOb2RlVHlwZXMgfSk6IFByb21pc2U8YW55PiB7XG4gICAgbGV0IG5vZGVVcmkgPSAnJztcbiAgICBzd2l0Y2ggKHF1ZXJ5Lm5vZGUpIHtcbiAgICAgIGNhc2UgTm9kZVR5cGVzLkZ1bGw6XG4gICAgICAgIG5vZGVVcmkgPSBjb21tb24uRW52aXJvbm1lbnRzW3RoaXMuYml0Z28uZ2V0RW52KCldLnRyb25Ob2Rlcy5mdWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTm9kZVR5cGVzLlNvbGlkaXR5OlxuICAgICAgICBub2RlVXJpID0gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuc29saWRpdHk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIHR5cGUgbm90IGZvdW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAuZ2V0KG5vZGVVcmkgKyBxdWVyeS5wYXRoKVxuICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgLnNlbmQocXVlcnkuanNvbk9iaik7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFjaCBUcm9uIG5vZGUnKTtcbiAgICB9XG5cbiAgICAvLyB1bmZvcnR1bmF0ZWx5LCBpdCBkb2Vzbid0IGxvb2sgbGlrZSBtb3N0IFRST04gbm9kZXMgcmV0dXJuIHZhbGlkIGpzb24gYXMgYm9keVxuICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJ5IG91ciBleHBsb3JlciBmb3IgdGhlIGJhbGFuY2Ugb2YgYW4gYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzcyB7U3RyaW5nfSB0aGUgYWRkcmVzcyBlbmNvZGVkIGluIGhleFxuICAgKiBAcmV0dXJucyB7QmlnTnVtYmVyfSBhZGRyZXNzIGJhbGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxBY2NvdW50UmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeUdldCh7XG4gICAgICBwYXRoOiAnL3YxL2FjY291bnRzLycgKyBhZGRyZXNzLFxuICAgICAganNvbk9iajoge30sXG4gICAgICBub2RlOiBOb2RlVHlwZXMuRnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgb3VyIGJ1aWxkIHRyYW5zYWN0aW9uIGZyb20gYSBub2RlLlxuICAgKiBAcGFyYW0gdG9BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGZyb21BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRCdWlsZFRyYW5zYWN0aW9uKFxuICAgIHRvQWRkcjogc3RyaW5nLFxuICAgIGZyb21BZGRyOiBzdHJpbmcsXG4gICAgYW1vdW50OiBudW1iZXJcbiAgKTogUHJvbWlzZTxJbnRlcmZhY2UuVHJhbnNhY3Rpb25SZWNlaXB0PiB7XG4gICAgLy8gb3VyIGFkZHJlc3NlcyBzaG91bGQgYmUgYmFzZTU4LCB3ZSdsbCBoYXZlIHRvIGVuY29kZSB0byBoZXhcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvY3JlYXRldHJhbnNhY3Rpb24nLFxuICAgICAganNvbk9iajoge1xuICAgICAgICB0b19hZGRyZXNzOiB0b0FkZHIsXG4gICAgICAgIG93bmVyX2FkZHJlc3M6IGZyb21BZGRyLFxuICAgICAgICBhbW91bnQsXG4gICAgICB9LFxuICAgICAgbm9kZTogTm9kZVR5cGVzLkZ1bGwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG91ciBidWlsZCB0cmFuc2FjdGlvbiBmcm9tIGEgbm9kZS5cbiAgICogQHBhcmFtIHRvQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBmcm9tQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihcbiAgICB0b0FkZHI6IHN0cmluZyxcbiAgICBmcm9tQWRkcjogc3RyaW5nLFxuICAgIGFtb3VudDogc3RyaW5nLFxuICAgIGNvbnRyYWN0QWRkcjogc3RyaW5nXG4gICk6IFByb21pc2U8eyB0cmFuc2FjdGlvbjogSW50ZXJmYWNlLlRyYW5zYWN0aW9uUmVjZWlwdCB9PiB7XG4gICAgY29uc3QgZnVuY3Rpb25TZWxlY3RvciA9ICd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJztcbiAgICBjb25zdCB0eXBlcyA9IFsnYWRkcmVzcycsICd1aW50MjU2J107XG4gICAgY29uc3QgdmFsdWVzID0gW3RvQWRkciwgYW1vdW50XTtcbiAgICBjb25zdCBwYXJhbWV0ZXIgPSBVdGlscy5lbmNvZGVEYXRhUGFyYW1zKHR5cGVzLCB2YWx1ZXMsICcnKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvdHJpZ2dlcnNtYXJ0Y29udHJhY3QnLFxuICAgICAganNvbk9iajoge1xuICAgICAgICBvd25lcl9hZGRyZXNzOiBmcm9tQWRkcixcbiAgICAgICAgY29udHJhY3RfYWRkcmVzczogY29udHJhY3RBZGRyLFxuICAgICAgICBmdW5jdGlvbl9zZWxlY3RvcjogZnVuY3Rpb25TZWxlY3RvcixcbiAgICAgICAgcGFyYW1ldGVyOiBwYXJhbWV0ZXIsXG4gICAgICAgIGZlZV9saW1pdDogMTAwMDAwMDAwLFxuICAgICAgfSxcbiAgICAgIG5vZGU6IE5vZGVUeXBlcy5GdWxsLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiBhbnkga2V5cyBpbiB0aGUgb3duZXJLZXlzIGNvbGxlY3Rpb24gZG9uJ3QgbWF0Y2ggdGhlIGtleXMgYXJyYXkgd2UgcGFzc1xuICAgKiBAcGFyYW0gb3duZXJLZXlzXG4gICAqIEBwYXJhbSBrZXlzXG4gICAqL1xuICBjaGVja1Blcm1pc3Npb25zKG93bmVyS2V5czogeyBhZGRyZXNzOiBzdHJpbmc7IHdlaWdodDogbnVtYmVyIH1bXSwga2V5czogc3RyaW5nW10pIHtcbiAgICBrZXlzID0ga2V5cy5tYXAoKGspID0+IGsudG9VcHBlckNhc2UoKSk7XG5cbiAgICBvd25lcktleXMubWFwKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGhleEtleSA9IGtleS5hZGRyZXNzLnRvVXBwZXJDYXNlKCk7XG4gICAgICBpZiAoIWtleXMuaW5jbHVkZXMoaGV4S2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHB1YiBhZGRyZXNzICR7aGV4S2V5fSBub3QgZm91bmQgaW4gYWNjb3VudGApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LndlaWdodCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ293bmVyIHBlcm1pc3Npb24gaXMgaW52YWxpZCBmb3IgdGhpcyBzdHJ1Y3R1cmUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBmdW5kcyByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvLlxuICAgKiBXZSBuZWVkIHRvIGRvIHRocmVlIHF1ZXJpZXMgZHVyaW5nIHRoaXM6XG4gICAqIDEpIE5vZGUgcXVlcnkgLSBob3cgbXVjaCBtb25leSBpcyBpbiB0aGUgYWNjb3VudFxuICAgKiAyKSBCdWlsZCB0cmFuc2FjdGlvbiAtIGJ1aWxkIG91ciB0cmFuc2FjdGlvbiBmb3IgdGhlIGFtb3VudFxuICAgKiAzKSBTZW5kIHNpZ25lZCBidWlsZCAtIHNlbmQgb3VyIHNpZ25lZCBidWlsZCB0byBhIHB1YmxpYyBub2RlXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPFJlY292ZXJ5VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpc0tyc1JlY292ZXJ5ID0gZ2V0SXNLcnNSZWNvdmVyeShwYXJhbXMpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9IGdldElzVW5zaWduZWRTd2VlcChwYXJhbXMpO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MhJyk7XG4gICAgfVxuXG4gICAgLy8gZ2V0IG91ciB1c2VyLCBiYWNrdXAga2V5c1xuICAgIGNvbnN0IGtleXMgPSBnZXRCaXAzMktleXModGhpcy5iaXRnbywgcGFyYW1zLCB7IHJlcXVpcmVCaXRHb1hwdWI6IGZhbHNlIH0pO1xuXG4gICAgLy8gd2UgbmVlZCB0byBkZWNvZGUgb3VyIGJpdGdvS2V5IHRvIGEgYmFzZTU4IGFkZHJlc3NcbiAgICBjb25zdCBiaXRnb0hleEFkZHIgPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1YihwYXJhbXMuYml0Z29LZXkpKTtcbiAgICBjb25zdCByZWNvdmVyeUFkZHJlc3NIZXggPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuXG4gICAgLy8gY2FsbCB0aGUgbm9kZSB0byBnZXQgb3VyIGFjY291bnQgYmFsYW5jZVxuICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCB0aGlzLmdldEFjY291bnRCYWxhbmNlc0Zyb21Ob2RlKFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KGJpdGdvSGV4QWRkcikpO1xuICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gYWNjb3VudC5kYXRhWzBdLmJhbGFuY2U7XG5cbiAgICBjb25zdCB1c2VyWFB1YiA9IGtleXNbMF0ubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuICAgIGNvbnN0IHVzZXJYUHJ2ID0ga2V5c1swXS50b0Jhc2U1OCgpO1xuICAgIGNvbnN0IGJhY2t1cFhQdWIgPSBrZXlzWzFdLm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcblxuICAgIC8vIGZpcnN0IGNvbnN0cnVjdCB0b2tlbiB0eG5zXG4gICAgY29uc3QgdG9rZW5UeG5zOiBhbnkgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRva2VuIG9mIGFjY291bnQuZGF0YVswXS50cmMyMCkge1xuICAgICAgLy8gbWFpbm5ldCB0b2tlbnNcbiAgICAgIGlmICh0b2tlbi5URWt4aVRlaG56U21TZTJYcXJCajR3MzJSVU45NjZyZHo4KSB7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHRva2VuLlRFa3hpVGVobnpTbVNlMlhxckJqNHczMlJVTjk2NnJkejg7XG4gICAgICAgIGNvbnN0IGNvbnRyYWN0QWRkciA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcygnVEVreGlUZWhuelNtU2UyWHFyQmo0dzMyUlVOOTY2cmR6OCcpO1xuICAgICAgICB0b2tlblR4bnMucHVzaChcbiAgICAgICAgICAoYXdhaXQgdGhpcy5nZXRUcmlnZ2VyU21hcnRDb250cmFjdFRyYW5zYWN0aW9uKHJlY292ZXJ5QWRkcmVzc0hleCwgYml0Z29IZXhBZGRyLCBhbW91bnQsIGNvbnRyYWN0QWRkcikpXG4gICAgICAgICAgICAudHJhbnNhY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4uVFI3TkhxamVLUXhHVENpOHE4Wlk0cEw4b3RTemdqTGo2dCkge1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbi5UUjdOSHFqZUtReEdUQ2k4cThaWTRwTDhvdFN6Z2pMajZ0O1xuICAgICAgICBjb25zdCBjb250cmFjdEFkZHIgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoJ1RSN05IcWplS1F4R1RDaThxOFpZNHBMOG90U3pnakxqNnQnKTtcbiAgICAgICAgdG9rZW5UeG5zLnB1c2goXG4gICAgICAgICAgKGF3YWl0IHRoaXMuZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihyZWNvdmVyeUFkZHJlc3NIZXgsIGJpdGdvSGV4QWRkciwgYW1vdW50LCBjb250cmFjdEFkZHIpKVxuICAgICAgICAgICAgLnRyYW5zYWN0aW9uXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gdGVzdG5ldCB0b2tlbnNcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4uVFNkWndOcXBIb2Z6UDZCc0JLR1FVV2RCZUpwaExtRjZpZCkge1xuICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbi5UU2Rad05xcEhvZnpQNkJzQktHUVVXZEJlSnBoTG1GNmlkO1xuICAgICAgICBjb25zdCBjb250cmFjdEFkZHIgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MoJ1RTZFp3TnFwSG9melA2QnNCS0dRVVdkQmVKcGhMbUY2aWQnKTtcbiAgICAgICAgdG9rZW5UeG5zLnB1c2goXG4gICAgICAgICAgKGF3YWl0IHRoaXMuZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihyZWNvdmVyeUFkZHJlc3NIZXgsIGJpdGdvSGV4QWRkciwgYW1vdW50LCBjb250cmFjdEFkZHIpKVxuICAgICAgICAgICAgLnRyYW5zYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHRva2VuLlRHM1hYeUV4QmtQcDluemRhakRac296RXU0QmthU0pvenMpIHtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gdG9rZW4uVEczWFh5RXhCa1BwOW56ZGFqRFpzb3pFdTRCa2FTSm96cztcbiAgICAgICAgY29uc3QgY29udHJhY3RBZGRyID0gVXRpbHMuZ2V0SGV4QWRkcmVzc0Zyb21CYXNlNThBZGRyZXNzKCdURzNYWHlFeEJrUHA5bnpkYWpEWnNvekV1NEJrYVNKb3pzJyk7XG4gICAgICAgIHRva2VuVHhucy5wdXNoKFxuICAgICAgICAgIChhd2FpdCB0aGlzLmdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24ocmVjb3ZlcnlBZGRyZXNzSGV4LCBiaXRnb0hleEFkZHIsIGFtb3VudCwgY29udHJhY3RBZGRyKSlcbiAgICAgICAgICAgIC50cmFuc2FjdGlvblxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zdHJ1Y3QgdGhlIHR4IC1cbiAgICAvLyB0aGVyZSdzIGFuIGFzc3VtcHRpb24gaGVyZSBiZWluZyBtYWRlIGFib3V0IGZlZXM6IGZvciBhIHdhbGxldCB0aGF0IGhhc24ndCBiZWVuIHVzZWQgaW4gYXdoaWxlLCB0aGUgaW1wbGljYXRpb24gaXNcbiAgICAvLyBpdCBoYXMgbWF4aW11bSBiYW5kd2lkdGguIHRodXMsIGEgcmVjb3Zlcnkgc2hvdWxkIGNvc3QgdGhlIG1pbmltdW0gYW1vdW50ICgxZTYgc3VuIG9yIDEgVHJvbilcbiAgICBpZiAoTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFID4gcmVjb3ZlcnlBbW91bnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW1vdW50IG9mIGZ1bmRzIHRvIHJlY292ZXIgd291bGRudCBiZSBhYmxlIHRvIGZ1bmQgYSBzZW5kJyk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5SGV4QWRkcmVzc2VzID0gW1xuICAgICAgdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIodXNlclhQdWIpKSxcbiAgICAgIHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKGJhY2t1cFhQdWIpKSxcbiAgICAgIGJpdGdvSGV4QWRkcixcbiAgICBdO1xuXG4gICAgLy8gcnVuIGNoZWNrcyB0byBlbnN1cmUgdGhpcyBpcyBhIHZhbGlkIHR4IC0gcGVybWlzc2lvbnMgbWF0Y2ggb3VyIHNpZ25lciBrZXlzXG4gICAgY29uc3Qgb3duZXJLZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudC5kYXRhWzBdLm93bmVyX3Blcm1pc3Npb24ua2V5cykge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcyhrZXkuYWRkcmVzcyk7XG4gICAgICBjb25zdCB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuICAgICAgb3duZXJLZXlzLnB1c2goeyBhZGRyZXNzLCB3ZWlnaHQgfSk7XG4gICAgfVxuICAgIGNvbnN0IGFjdGl2ZVBlcm1pc3Npb25LZXlzOiB7IGFkZHJlc3M6IHN0cmluZzsgd2VpZ2h0OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgb2YgYWNjb3VudC5kYXRhWzBdLmFjdGl2ZV9wZXJtaXNzaW9uWzBdLmtleXMpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3Moa2V5LmFkZHJlc3MpO1xuICAgICAgY29uc3Qgd2VpZ2h0ID0ga2V5LndlaWdodDtcbiAgICAgIGFjdGl2ZVBlcm1pc3Npb25LZXlzLnB1c2goeyBhZGRyZXNzLCB3ZWlnaHQgfSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tQZXJtaXNzaW9ucyhvd25lcktleXMsIGtleUhleEFkZHJlc3Nlcyk7XG4gICAgdGhpcy5jaGVja1Blcm1pc3Npb25zKGFjdGl2ZVBlcm1pc3Npb25LZXlzLCBrZXlIZXhBZGRyZXNzZXMpO1xuXG4gICAgLy8gYnVpbGQgYW5kIHNpZ24gdG9rZW4gdHhuc1xuICAgIGNvbnN0IGZpbmFsVG9rZW5UeHM6IGFueSA9IFtdO1xuICAgIGZvciAoY29uc3QgdG9rZW5UeG4gb2YgdG9rZW5UeG5zKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0b2tlblR4bik7XG5cbiAgICAgIC8vIHRoaXMgdHggc2hvdWxkIGJlIGVub3VnaCB0byBkcm9wIGludG8gYSBub2RlXG4gICAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICAgIGZpbmFsVG9rZW5UeHMucHVzaCgoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpLnRvSnNvbigpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVzZXJQcnYgPSB0aGlzLnhwcnZUb0NvbXByZXNzZWRQcnYodXNlclhQcnYpO1xuXG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcblxuICAgICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgICAgaWYgKCFpc0tyc1JlY292ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGJhY2t1cFhQcnYgPSBrZXlzWzFdLnRvQmFzZTU4KCk7XG4gICAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogYmFja3VwUHJ2IH0pO1xuICAgICAgfVxuICAgICAgZmluYWxUb2tlblR4cy5wdXNoKChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCkpO1xuICAgIH1cblxuICAgIC8vIHRva2VucyBtdXN0IGJlIHJlY292ZXJlZCBiZWZvcmUgdGhlIG5hdGl2ZSBhc3NldCwgc28gdGhhdCB0aGVyZSBpcyBzdWZmaWNpZW50IG9mIHRoZSBuYXRpdmUgYXNzZXQgdG8gY292ZXIgZmVlc1xuICAgIGlmIChmaW5hbFRva2VuVHhzLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRva2VuVHhzOiBmaW5hbFRva2VuVHhzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCByZWNvdmVyeUFtb3VudE1pbnVzRmVlcyA9IHJlY292ZXJ5QW1vdW50IC0gTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFO1xuICAgIGNvbnN0IGJ1aWxkVHggPSBhd2FpdCB0aGlzLmdldEJ1aWxkVHJhbnNhY3Rpb24ocmVjb3ZlcnlBZGRyZXNzSGV4LCBiaXRnb0hleEFkZHIsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzKTtcblxuICAgIC8vIGNvbnN0cnVjdCBvdXIgdHhcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSAoZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpIGFzIFdyYXBwZWRCdWlsZGVyKS5mcm9tKGJ1aWxkVHgpO1xuXG4gICAgLy8gdGhpcyB0eCBzaG91bGQgYmUgZW5vdWdoIHRvIGRyb3AgaW50byBhIG5vZGVcbiAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eDogKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0pzb24oKSxcbiAgICAgICAgcmVjb3ZlcnlBbW91bnQ6IHJlY292ZXJ5QW1vdW50TWludXNGZWVzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJYUHJ2KTtcblxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuXG4gICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgIGlmICghaXNLcnNSZWNvdmVyeSkge1xuICAgICAgY29uc3QgYmFja3VwWFBydiA9IGtleXNbMV0udG9CYXNlNTgoKTtcbiAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IGJhY2t1cFBydiB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHg6IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkudG9Kc29uKCksXG4gICAgICByZWNvdmVyeUFtb3VudDogcmVjb3ZlcnlBbW91bnRNaW51c0ZlZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgVHJvbiB0cmFuc2FjdGlvbiBmcm9tIHR4SGV4XG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGV4cGxhaW5UcmFuc2FjdGlvbihwYXJhbXM6IEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFRyb25UcmFuc2FjdGlvbkV4cGxhbmF0aW9uPiB7XG4gICAgY29uc3QgdHhIZXggPSBwYXJhbXMudHhIZXggfHwgKHBhcmFtcy5oYWxmU2lnbmVkICYmIHBhcmFtcy5oYWxmU2lnbmVkLnR4SGV4KTtcbiAgICBpZiAoIXR4SGV4IHx8ICFwYXJhbXMuZmVlSW5mbykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH1cbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0eEhleCk7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAge1xuICAgICAgICBhbW91bnQ6IHR4Lm91dHB1dHNbMF0udmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgYWRkcmVzczogdHgub3V0cHV0c1swXS5hZGRyZXNzLCAvLyBTaG91bGQgdHVybiBpdCBpbnRvIGEgcmVhZGFibGUgZm9ybWF0LCBha2EgYmFzZTU4XG4gICAgICB9LFxuICAgIF07XG5cbiAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAnaWQnLFxuICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICdvdXRwdXRzJyxcbiAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICdmZWUnLFxuICAgICAgJ3RpbWVzdGFtcCcsXG4gICAgICAnZXhwaXJhdGlvbicsXG4gICAgXTtcblxuICAgIHJldHVybiB7XG4gICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICBpZDogdHguaWQsXG4gICAgICBvdXRwdXRzLFxuICAgICAgb3V0cHV0QW1vdW50OiBvdXRwdXRzWzBdLmFtb3VudCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLCAvLyBhY2NvdW50IGJhc2VkIGRvZXMgbm90IHVzZSBjaGFuZ2Ugb3V0cHV0c1xuICAgICAgY2hhbmdlQW1vdW50OiAnMCcsIC8vIGFjY291bnQgYmFzZSBkb2VzIG5vdCBtYWtlIGNoYW5nZVxuICAgICAgZmVlOiBwYXJhbXMuZmVlSW5mbyxcbiAgICAgIHRpbWVzdGFtcDogdHgudmFsaWRGcm9tLFxuICAgICAgZXhwaXJhdGlvbjogdHgudmFsaWRUbyxcbiAgICB9O1xuICB9XG59XG4iXX0=
|
|
935
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyeC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7R0FFRztBQUNILHFEQUF1QztBQUN2QyxtQ0FBdUQ7QUFFdkQscURBQThDO0FBQzlDLG9EQUFzQztBQUN0QyxtREE0QjhCO0FBQzlCLHlEQUErRDtBQUMvRCwrQkFBdUY7QUFFdkYsMkNBQTJDO0FBQzNDLG1DQUFnRDtBQUVuQyxRQUFBLGlDQUFpQyxHQUFHLEdBQUcsQ0FBQztBQUN4QyxRQUFBLHlCQUF5QixHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyx3RUFBd0U7QUFDL0csUUFBQSwrQkFBK0IsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsd0VBQXdFO0FBQ3JILFFBQUEsMEJBQTBCLEdBQUcsUUFBUSxDQUFDLENBQUMsVUFBVTtBQUNqRCxRQUFBLG1CQUFtQixHQUFHLEVBQUUsQ0FBQyxDQUFDLHdEQUF3RDtBQThFL0YsSUFBWSxTQUdYO0FBSEQsV0FBWSxTQUFTO0lBQ25CLHlDQUFJLENBQUE7SUFDSixpREFBUSxDQUFBO0FBQ1YsQ0FBQyxFQUhXLFNBQVMseUJBQVQsU0FBUyxRQUdwQjtBQWtCRCxTQUFTLHlCQUF5QixDQUFDLE1BQTRCO0lBQzdELE9BQU8sQ0FDTCxPQUFPLElBQUksTUFBTTtRQUNqQixPQUFPLElBQUksTUFBTTtRQUNqQixDQUFDLGNBQWMsSUFBSSxNQUFNO1lBQ3ZCLE1BQU0sQ0FBQyxZQUFZLEtBQUssU0FBUztZQUNqQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsWUFBWSxJQUFJLE9BQU8sSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FDdEUsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFhLEdBQUksU0FBUSxtQkFBUTtJQUcvQixZQUFZLEtBQWdCLEVBQUUsV0FBdUM7UUFDbkUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7SUFDbEMsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztJQUNsQyxDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUM7SUFDcEMsQ0FBQztJQUVELGFBQWE7UUFDWCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixzQkFBc0I7UUFDcEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLHNCQUFzQjtRQUNwQixPQUFPLHdCQUFhLENBQUMsT0FBTyxDQUFDO0lBQy9CLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixlQUFlO1FBQ2IsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixlQUFlO1FBQ2IsT0FBTyxJQUFBLG1CQUFVLEVBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBZ0IsRUFBRSxXQUF1QztRQUM3RSxPQUFPLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsd0JBQXdCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGtCQUFrQjtJQUNsQiwyQkFBMkI7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsa0JBQWtCO0lBQ2xCLDBCQUEwQjtRQUN4QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSCxjQUFjLENBQUMsT0FBZTtRQUM1QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxPQUFPLFdBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7T0FHRztJQUNILGlCQUFpQixDQUFDLE9BQWU7UUFDL0IsT0FBTyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsZUFBZSxDQUFDLElBQWE7UUFDM0IsNERBQTREO1FBQzVELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLGdIQUFnSDtZQUNoSCxvR0FBb0c7WUFDcEcsSUFBSSxHQUFHLElBQUEsb0JBQVcsRUFBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUNELE1BQU0sRUFBRSxHQUFHLGlCQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE9BQU87WUFDTCxHQUFHLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRTtZQUM3QixHQUFHLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRTtTQUNuQixDQUFDO0lBQ0osQ0FBQztJQUVELFdBQVcsQ0FBQyxJQUFZO1FBQ3RCLElBQUksQ0FBQztZQUNILE9BQU8saUJBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDN0MsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0lBRUQsVUFBVSxDQUFDLEdBQVc7UUFDcEIsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDMUIsNkVBQTZFO1lBQzdFLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sSUFBSSxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUErQjtRQUNwRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQTRCO1FBQ2hELE1BQU0sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBRXRDLElBQUksSUFBQSxvQ0FBeUIsRUFBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE9BQU8sSUFBQSxpQ0FBc0IsRUFDM0IsRUFBRSxHQUFHLE1BQU0sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLEVBQ3BDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUM5QixDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsSUFBSSxhQUFXLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FDbEUsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUN2QyxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUM7UUFDNUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzVELENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztRQUV0RSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELHNDQUFzQztRQUN0QyxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNoQixNQUFNLFFBQVEsR0FBRyxTQUFTLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxxQkFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLHFCQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDaEgsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztZQUM3RSxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFFRCwyQ0FBMkM7UUFDM0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDZCxNQUFNLE9BQU8sR0FBRyxTQUFTLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxxQkFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLHFCQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDN0csSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQztZQUMvRSxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsd0NBQXdDLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxPQUFlLEVBQUUsUUFBZ0I7UUFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUNELE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3RCxNQUFNLGFBQWEsR0FBRyxXQUFLLENBQUMsMEJBQTBCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDeEUsTUFBTSxVQUFVLEdBQUcsV0FBSyxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sY0FBYyxHQUFHLFdBQUssQ0FBQyw2QkFBNkIsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN2RSxPQUFPLGNBQWMsS0FBSyxPQUFPLENBQUM7SUFDcEMsQ0FBQztJQUVEOztPQUVHO0lBQ0ssb0JBQW9CLENBQUMsT0FBZSxFQUFFLE9BQWUsRUFBRSxLQUFhLEVBQUUsS0FBYTtRQUN6RixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBQ0QsTUFBTSxjQUFjLEdBQUcsT0FBTyxLQUFLLElBQUksS0FBSyxFQUFFLENBQUM7UUFDL0MsTUFBTSxTQUFTLEdBQUcsaUJBQUssQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUMsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN0RCxNQUFNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVELE1BQU0sT0FBTyxHQUFHLElBQUksYUFBVyxDQUFDLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQztRQUMzRCxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDNUMsT0FBTyxjQUFjLEtBQUssT0FBTyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCLENBQUMsTUFBZ0M7UUFDdEQsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBRXBELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELElBQUksVUFBVSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ3pCLGdFQUFnRTtZQUNoRSwyRkFBMkY7WUFDM0Ysa0RBQWtEO1lBQ2xELGtHQUFrRztZQUNsRyxpRUFBaUU7WUFDakUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1RCxNQUFNLFNBQVMsR0FBRyxXQUFLLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFdEQsNEVBQTRFO1lBQzVFLHNGQUFzRjtZQUN0RixJQUFJLFNBQVMsQ0FBQyxZQUFZLEtBQUssVUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDMUQseUVBQXlFO2dCQUN6RSx1R0FBdUc7Z0JBQ3ZHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDMUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO2dCQUMxRCxDQUFDO2dCQUNELE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzlFLENBQUM7WUFFRCxJQUFJLFNBQVMsQ0FBQyxZQUFZLEtBQUssVUFBSSxDQUFDLFlBQVksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO2dCQUN0RSxnR0FBZ0c7Z0JBQ2hHLDJGQUEyRjtnQkFDM0YsTUFBTSxJQUFJLEtBQUssQ0FDYixvRUFBb0U7b0JBQ2xFLHdFQUF3RSxDQUMzRSxDQUFDO1lBQ0osQ0FBQztZQUVELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELHVHQUF1RztRQUN2RywwRkFBMEY7UUFDMUYsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUMvQixNQUFNLFNBQVMsR0FBRyxJQUFBLG9CQUFVLEVBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFELE1BQU0sRUFBRSxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25DLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUUzQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzRixNQUFNLElBQUksS0FBSyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDNUQsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdDLElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxrQkFBa0IsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMzRCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNPLGlCQUFpQixDQUFDLEtBQWE7UUFDdkMsSUFBSSxDQUFDO1lBQ0gsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksQ0FBQztRQUN4QyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxDQUFDLEtBQUssQ0FBQywwQ0FBMEMsSUFBSSxDQUFDLFFBQVEsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO1lBQ2pHLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNLLHdCQUF3QixDQUFDLFFBQWEsRUFBRSxRQUFhLEVBQUUsaUJBQWlCLEdBQUcsS0FBSztRQUN0RixJQUFJLENBQUMsQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQzdELE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFvQixDQUFDO1FBRXRELGtCQUFrQjtRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUM3QyxDQUFDO1FBRUQsK0RBQStEO1FBQy9ELElBQUksUUFBUSxDQUFDLFVBQVUsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1RCxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbkQsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDO1lBQzlDLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDN0MsTUFBTSxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsV0FBSyxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUVqSCxJQUFJLGNBQWMsS0FBSyxZQUFZLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQywyRUFBMkUsQ0FBQyxDQUFDO1lBQy9GLENBQUM7WUFFRCxJQUFJLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxLQUFLLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQzFFLE1BQU0sSUFBSSxLQUFLLENBQUMsK0RBQStELENBQUMsQ0FBQztZQUNuRixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGtCQUFrQjtJQUNsQixLQUFLLENBQUMsa0JBQWtCLENBQUMsWUFBb0I7UUFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBQSxvQkFBVSxFQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqRSxNQUFNLGtCQUFrQixHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25ELE9BQU8sa0JBQWtCLENBQUMsZUFBZSxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGlCQUFpQixDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBaUM7UUFDNUQsTUFBTSxRQUFRLEdBQUcsaUJBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkMsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxPQUFPLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBa0M7UUFDdEQsTUFBTSxTQUFTLEdBQUcsSUFBQSxvQkFBVSxFQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTVFLElBQUksR0FBRyxDQUFDO1FBQ1IsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLFdBQVcsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2xGLElBQUksS0FBSyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDL0IsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDbkIsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLGNBQWMsR0FBRyxPQUFPLEtBQUssSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUMvQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRXhCLE1BQU0sV0FBVyxHQUFHLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzVDLE1BQU0sUUFBUSxHQUFHO1lBQ2YsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQzVDLENBQUM7UUFDRixJQUFJLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQy9DLE9BQU8sUUFBUSxDQUFDO1FBQ2xCLENBQUM7UUFDRCwwQkFBMEI7UUFDMUIsT0FBTztZQUNMLFVBQVUsRUFBRSxRQUFRO1NBQ3JCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFdBQVcsQ0FBQyxHQUFXO1FBQ3JCLElBQUksQ0FBQztZQUNILE9BQU8sQ0FBQyxpQkFBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUM3QyxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsV0FBVyxDQUFDLE9BQXdCO1FBQ2xDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDaEMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxDQUFDO2FBQU0sSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDcEMsT0FBTyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzVELENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVksRUFBRSxPQUF3QjtRQUN0RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXpDLElBQUksR0FBRyxHQUF1QixHQUFHLENBQUMsR0FBRyxDQUFDO1FBQ3RDLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFCLEdBQUcsR0FBRyxpQkFBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFELENBQUM7UUFFRCxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDVCxNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxJQUFJLEdBQUcsR0FBRyxXQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFOUMsMEJBQTBCO1FBQzFCLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUU3QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxxQkFBcUIsQ0FBQyxJQUFZO1FBQ2hDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsaUJBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ25ELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BHLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsc0JBQXNCLENBQUMsV0FBZ0I7UUFDM0MsSUFBSSxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDM0QsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQztRQUM1RCxDQUFDO0lBQ0gsQ0FBQztJQUVELGVBQWUsQ0FBQyxHQUFXO1FBQ3pCLE1BQU0sYUFBYSxHQUFHLFdBQUssQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM1RCxNQUFNLFVBQVUsR0FBRyxXQUFLLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEUsT0FBTyxXQUFLLENBQUMsMEJBQTBCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELG1CQUFtQixDQUFDLElBQVk7UUFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxpQkFBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVPLFVBQVUsQ0FBQyxJQUFlO1FBQ2hDLFFBQVEsSUFBSSxFQUFFLENBQUM7WUFDYixLQUFLLFNBQVMsQ0FBQyxJQUFJO2dCQUNqQixPQUFPLGlCQUFNLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2pFLEtBQUssU0FBUyxDQUFDLFFBQVE7Z0JBQ3JCLE9BQU8saUJBQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7WUFDckU7Z0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzNDLENBQUM7SUFDSCxDQUFDO0lBQ0Q7Ozs7T0FJRztJQUNLLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBc0Q7UUFDL0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFNUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPO2FBQzNCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQzthQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDO2FBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV2QixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUMvQyxDQUFDO1FBRUQsZ0ZBQWdGO1FBQ2hGLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxLQUFLLENBQUMsV0FBVyxDQUFDLEtBQXNEO1FBQzlFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTVDLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTzthQUMzQixHQUFHLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7YUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQzthQUNaLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFdkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNqQixNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUVELGdGQUFnRjtRQUNoRixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssS0FBSyxDQUFDLDBCQUEwQixDQUFDLE9BQWU7UUFDdEQsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUM7WUFDNUIsSUFBSSxFQUFFLGVBQWUsR0FBRyxPQUFPO1lBQy9CLE9BQU8sRUFBRSxFQUFFO1lBQ1gsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1NBQ3JCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLEtBQUssQ0FBQyxtQkFBbUIsQ0FDL0IsTUFBYyxFQUNkLFFBQWdCLEVBQ2hCLE1BQWM7UUFFZCw4REFBOEQ7UUFDOUQsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDN0IsSUFBSSxFQUFFLDJCQUEyQjtZQUNqQyxPQUFPLEVBQUU7Z0JBQ1AsVUFBVSxFQUFFLE1BQU07Z0JBQ2xCLGFBQWEsRUFBRSxRQUFRO2dCQUN2QixNQUFNO2FBQ1A7WUFDRCxJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUk7U0FDckIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssS0FBSyxDQUFDLGtDQUFrQyxDQUM5QyxNQUFjLEVBQ2QsUUFBZ0IsRUFDaEIsTUFBYyxFQUNkLFlBQW9CO1FBRXBCLE1BQU0sZ0JBQWdCLEdBQUcsMkJBQTJCLENBQUM7UUFDckQsTUFBTSxLQUFLLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDckMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEMsTUFBTSxTQUFTLEdBQUcsV0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUQsT0FBTyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDN0IsSUFBSSxFQUFFLDhCQUE4QjtZQUNwQyxPQUFPLEVBQUU7Z0JBQ1AsYUFBYSxFQUFFLFFBQVE7Z0JBQ3ZCLGdCQUFnQixFQUFFLFlBQVk7Z0JBQzlCLGlCQUFpQixFQUFFLGdCQUFnQjtnQkFDbkMsU0FBUyxFQUFFLFNBQVM7Z0JBQ3BCLFNBQVMsRUFBRSxTQUFTO2FBQ3JCO1lBQ0QsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJO1NBQ3JCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsZ0JBQWdCLENBQUMsU0FBZ0QsRUFBRSxJQUFjO1FBQy9FLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUV4QyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDcEIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsTUFBTSx1QkFBdUIsQ0FBQyxDQUFDO1lBQ2hFLENBQUM7WUFFRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztZQUNwRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gscUJBQXFCLENBQ25CLEVBQW1CLEVBQ25CLEdBQVcsRUFDWCxjQUFzQixFQUN0QixXQUF5QjtRQUV6QixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDM0IsTUFBTSxNQUFNLEdBQUc7WUFDYixLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7WUFDN0IsY0FBYztZQUNkLE9BQU8sRUFBRTtnQkFDUCxHQUFHLEVBQUUsR0FBRyxHQUFHLEVBQUU7YUFDZDtZQUNELEVBQUUsRUFBRSxNQUFNLEVBQUUsbURBQW1EO1lBQy9ELElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFO1NBQ3RCLENBQUM7UUFDRixPQUFPLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzNELENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7O09BZUc7SUFDSCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQXVCO1FBQ25DLE1BQU0sYUFBYSxHQUFHLElBQUEsMkJBQWdCLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0MsTUFBTSxlQUFlLEdBQUcsSUFBQSw2QkFBa0IsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDO1lBQ3JELE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDO1FBQ3hDLElBQUksSUFBQSxvQkFBVyxFQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDMUIsUUFBUSxHQUFHLENBQUMsQ0FBQztRQUNmLENBQUM7YUFBTSxJQUFJLENBQUMsSUFBQSxrQkFBUyxFQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNoRCxNQUFNLElBQUksS0FBSyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUVELElBQUksWUFBWSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDL0IsSUFBSSxJQUFBLG9CQUFXLEVBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM5QixZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLENBQUM7YUFBTSxJQUFJLE9BQU8sWUFBWSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzVDLFlBQVksR0FBRyxRQUFRLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLENBQUM7UUFFRCxJQUFJLENBQUMsSUFBQSxrQkFBUyxFQUFDLFlBQVksQ0FBQyxJQUFJLFlBQVksSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUVELDRCQUE0QjtRQUM1QixNQUFNLElBQUksR0FBRyxNQUFNLElBQUEsNEJBQWlCLEVBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBRXRGLHFEQUFxRDtRQUNyRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUN2RixJQUFJLG1CQUFtQixHQUFHLFlBQVksQ0FBQztRQUN2QyxJQUFJLG9CQUFvQixHQUFHLFdBQUssQ0FBQyw4QkFBOEIsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUU1Riw0REFBNEQ7UUFDNUQsSUFBSSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsMEJBQTBCLENBQUMsV0FBSyxDQUFDLHVCQUF1QixDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztRQUN4RyxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUU3QyxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEMsSUFBSSxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxXQUFvQyxDQUFDO1FBQ3pDLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDO1FBQ3RELHVFQUF1RTtRQUN2RSxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDdEIsSUFBSSxXQUE0QixDQUFDO1lBQ2pDLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxLQUFLLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO29CQUM3QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztvQkFDeEMsTUFBTSxvQkFBb0IsR0FBRyxXQUFLLENBQUMsOEJBQThCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztvQkFDckYsV0FBVyxHQUFHLENBQ1osTUFBTSxJQUFJLENBQUMsa0NBQWtDLENBQzNDLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDbkIsTUFBTSxFQUNOLG9CQUFvQixDQUNyQixDQUNGLENBQUMsV0FBVyxDQUFDO29CQUNkLGNBQWMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUN0QyxNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1lBRUQsNEJBQTRCO1lBQzVCLElBQUksV0FBVyxFQUFFLENBQUM7Z0JBQ2hCLDhEQUE4RDtnQkFDOUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQzNDLElBQUksVUFBVSxHQUFHLHVDQUErQixFQUFFLENBQUM7b0JBQ2pELE1BQU0sSUFBSSxLQUFLLENBQ2IsOEJBQThCLFVBQVUsaUJBQWlCLHVDQUErQiw0Q0FBNEMsQ0FDckksQ0FBQztnQkFDSixDQUFDO2dCQUVELE1BQU0sU0FBUyxHQUFHLElBQUEsb0JBQVUsRUFBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ2hFLHNFQUFzRTtnQkFDdEUsNkJBQTZCO2dCQUM3QixTQUFTLENBQUMsYUFBYSxDQUFDLGtDQUEwQixDQUFDLENBQUM7Z0JBQ3BELCtDQUErQztnQkFDL0MsSUFBSSxlQUFlLEVBQUUsQ0FBQztvQkFDcEIsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsdUNBQStCLEVBQUUsY0FBYyxDQUFDLENBQUM7Z0JBQzlHLENBQUM7Z0JBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUVuRCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBRWpDLGtDQUFrQztnQkFDbEMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7b0JBQ3hDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDdEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUV2RCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7Z0JBQ3JDLENBQUM7Z0JBQ0QsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsdUNBQStCLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFDOUcsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sS0FBSyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7WUFDeEUsQ0FBQztRQUNILENBQUM7UUFDRCxpQ0FBaUM7UUFDakMsSUFBSSxjQUFjLEdBQUcsaUNBQXlCLEVBQUUsQ0FBQztZQUMvQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDL0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBRWpELDZCQUE2QjtZQUM3QixNQUFNLGVBQWUsR0FBRztnQkFDdEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzFELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUM1RCxZQUFZO2FBQ2IsQ0FBQztZQUNGLDhFQUE4RTtZQUM5RSxNQUFNLFNBQVMsR0FBMEMsRUFBRSxDQUFDO1lBQzVELEtBQUssTUFBTSxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDeEQsTUFBTSxPQUFPLEdBQUcsV0FBSyxDQUFDLDhCQUE4QixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbEUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQztnQkFDMUIsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3RDLENBQUM7WUFDRCxNQUFNLG9CQUFvQixHQUEwQyxFQUFFLENBQUM7WUFDdkUsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUM1RCxNQUFNLE9BQU8sR0FBRyxXQUFLLENBQUMsOEJBQThCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNsRSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO2dCQUMxQixvQkFBb0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUNqRCxDQUFDO1lBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDL0QsQ0FBQzthQUFNLENBQUM7WUFDTixvQ0FBb0M7WUFDcEMsNENBQTRDO1lBQzVDLGtEQUFrRDtZQUNsRCxLQUFLLElBQUksQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLEdBQUcsWUFBWSxHQUFHLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUN4RCxNQUFNLGNBQWMsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUNuRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pGLE1BQU0sT0FBTyxHQUFHLFdBQUssQ0FBQyx1QkFBdUIsQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDOUQsMkNBQTJDO2dCQUMzQyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFbkUsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLGlDQUF5QixFQUFFLENBQUM7b0JBQ25GLE9BQU8sR0FBRyxXQUFXLENBQUM7b0JBQ3RCLGNBQWMsR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztvQkFDN0MsUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLDBCQUEwQjtvQkFDekQsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO29CQUN4QixtQkFBbUIsR0FBRyxjQUFjLENBQUM7b0JBQ3JDLG9CQUFvQixHQUFHLFlBQVksQ0FBQztvQkFDcEMsV0FBVyxHQUFHO3dCQUNaLE9BQU87d0JBQ1AsS0FBSyxFQUFFLENBQUM7d0JBQ1IsS0FBSyxFQUFFLENBQUM7cUJBQ1QsQ0FBQztvQkFDRixNQUFNO2dCQUNSLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELHdHQUF3RztRQUN4RyxpRUFBaUU7UUFDakUsSUFBSSxDQUFDLGNBQWMsSUFBSSxpQ0FBeUIsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuRSxNQUFNLElBQUksS0FBSyxDQUNiLDhCQUE4QixjQUFjLGlCQUFpQixpQ0FBeUIsc0NBQXNDLENBQzdILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSx1QkFBdUIsR0FBRyxjQUFjLEdBQUcsaUNBQXlCLENBQUM7UUFDM0UsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsb0JBQW9CLEVBQUUsbUJBQW1CLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztRQUVuSCxtQkFBbUI7UUFDbkIsTUFBTSxTQUFTLEdBQUksSUFBQSxvQkFBVSxFQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBb0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDaEYsc0VBQXNFO1FBQ3RFLDZCQUE2QjtRQUM3QixTQUFTLENBQUMsYUFBYSxDQUFDLGtDQUEwQixDQUFDLENBQUM7UUFDcEQsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFbkMsK0NBQStDO1FBQy9DLElBQUksZUFBZSxFQUFFLENBQUM7WUFDcEIsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsRUFBRSxFQUFFLGlDQUF5QixFQUFFLHVCQUF1QixFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ3pHLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbkQsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBRWpDLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUN4QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXZELFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekMsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxFQUFFLGlDQUF5QixFQUFFLHVCQUF1QixFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQy9HLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxNQUFvQztRQUM5RCxNQUFNLHdCQUF3QixHQUFHLElBQUEsNkJBQWtCLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDNUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixJQUFJLENBQUMsQ0FBQztRQUMvQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsZUFBZSxJQUFJLFFBQVEsR0FBRywyQkFBbUIsQ0FBQztRQUV4RSxJQUFJLFFBQVEsR0FBRyxDQUFDLElBQUksTUFBTSxJQUFJLFFBQVEsSUFBSSxNQUFNLEdBQUcsUUFBUSxHQUFHLEVBQUUsR0FBRywyQkFBbUIsRUFBRSxDQUFDO1lBQ3ZGLE1BQU0sSUFBSSxLQUFLLENBQ2IsOEVBQThFLFFBQVEsc0JBQXNCLE1BQU0sR0FBRyxDQUN0SCxDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBQSw0QkFBaUIsRUFBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLGdCQUFnQixFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDdEYsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFdEYsTUFBTSxTQUFTLEdBQTBCLEVBQUUsQ0FBQztRQUM1QyxLQUFLLElBQUksQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDdkMsTUFBTSxjQUFjLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ25ELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN2QyxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkcsTUFBTSxjQUFjLEdBQUcsV0FBSyxDQUFDLHVCQUF1QixDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDeEUsMkNBQTJDO1lBQzNDLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLDBCQUEwQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRTFFLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxpQ0FBeUIsRUFBRSxDQUFDO2dCQUNuRixJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7Z0JBQ3ZCLGlGQUFpRjtnQkFDakYsSUFBSSxXQUE0QixDQUFDO2dCQUVqQyx1RUFBdUU7Z0JBQ3ZFLElBQUksTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUM7b0JBQ2hDLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsdUNBQStCLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzt3QkFDbEcsTUFBTSxjQUFjLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7d0JBQ2pELEtBQUssTUFBTSxTQUFTLElBQUksY0FBYyxFQUFFLENBQUM7NEJBQ3ZDLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFrQixDQUFDOzRCQUNoRSxJQUFJLE1BQU0sQ0FBQyxvQkFBb0IsS0FBSyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQ0FDdkQsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUM3QyxNQUFNLG9CQUFvQixHQUFHLFdBQUssQ0FBQyw4QkFBOEIsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDdEYsV0FBVyxHQUFHLENBQ1osTUFBTSxJQUFJLENBQUMsa0NBQWtDLENBQzNDLFdBQVcsRUFDWCxpQkFBaUIsRUFDakIsTUFBTSxFQUNOLG9CQUFvQixDQUNyQixDQUNGLENBQUMsV0FBVyxDQUFDO2dDQUNkLGNBQWMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dDQUN0QyxNQUFNOzRCQUNSLENBQUM7d0JBQ0gsQ0FBQztvQkFDSCxDQUFDO29CQUNELDRCQUE0QjtvQkFDNUIsSUFBSSxXQUFXLEVBQUUsQ0FBQzt3QkFDaEIsTUFBTSxXQUFXLEdBQUc7NEJBQ2xCLE9BQU8sRUFBRSxjQUFjOzRCQUN2QixLQUFLLEVBQUUsQ0FBQzs0QkFDUixLQUFLLEVBQUUsQ0FBQzt5QkFDVCxDQUFDO3dCQUNGLE1BQU0sU0FBUyxHQUFHLElBQUEsb0JBQVUsRUFBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7d0JBQ2hFLHNFQUFzRTt3QkFDdEUsNkJBQTZCO3dCQUM3QixTQUFTLENBQUMsYUFBYSxDQUFDLGtDQUEwQixDQUFDLENBQUM7d0JBQ3BELCtDQUErQzt3QkFDL0MsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7NEJBQzlCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQzs0QkFDN0Qsc0RBQXNEOzRCQUN0RCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7d0JBQ25DLENBQUM7d0JBQ0QsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7d0JBQ25DLFNBQVMsQ0FBQyxJQUFJLENBQ1osSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsRUFBRSx1Q0FBK0IsRUFBRSxjQUFjLEVBQUUsV0FBVyxDQUFDLENBQzdGLENBQUM7b0JBQ0osQ0FBQztnQkFDSCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxjQUFjLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7b0JBQ25ELE1BQU0sV0FBVyxHQUFHO3dCQUNsQixPQUFPLEVBQUUsY0FBYzt3QkFDdkIsS0FBSyxFQUFFLENBQUM7d0JBQ1IsS0FBSyxFQUFFLENBQUM7cUJBQ1QsQ0FBQztvQkFDRixNQUFNLGNBQWMsR0FBRyxjQUFjLEdBQUcsaUNBQXlCLENBQUM7b0JBQ2xFLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxjQUFjLENBQUMsQ0FBQztvQkFDL0YsbUJBQW1CO29CQUNuQixNQUFNLFNBQVMsR0FBSSxJQUFBLG9CQUFVLEVBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDaEYsc0VBQXNFO29CQUN0RSw2QkFBNkI7b0JBQzdCLFNBQVMsQ0FBQyxhQUFhLENBQUMsa0NBQTBCLENBQUMsQ0FBQztvQkFFcEQsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7d0JBQzlCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQzt3QkFDN0Qsc0RBQXNEO3dCQUN0RCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7b0JBQ25DLENBQUM7b0JBQ0QsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ25DLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxpQ0FBeUIsRUFBRSxjQUFjLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDekcsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTztZQUNMLFlBQVksRUFBRSxTQUFTO1NBQ3hCLENBQUM7SUFDSixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQWlDO1FBQ3hELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0UsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLElBQUEsb0JBQVUsRUFBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUQsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkMsTUFBTSxPQUFPLEdBQUc7WUFDZDtnQkFDRSxNQUFNLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFO2dCQUN0QyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsb0RBQW9EO2FBQ3JGO1NBQ0YsQ0FBQztRQUVGLE1BQU0sWUFBWSxHQUFHO1lBQ25CLElBQUk7WUFDSixjQUFjO1lBQ2QsY0FBYztZQUNkLFNBQVM7WUFDVCxlQUFlO1lBQ2YsS0FBSztZQUNMLFdBQVc7WUFDWCxZQUFZO1NBQ2IsQ0FBQztRQUVGLE9BQU87WUFDTCxZQUFZO1lBQ1osRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFO1lBQ1QsT0FBTztZQUNQLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTTtZQUMvQixhQUFhLEVBQUUsRUFBRSxFQUFFLDRDQUE0QztZQUMvRCxZQUFZLEVBQUUsR0FBRyxFQUFFLG9DQUFvQztZQUN2RCxHQUFHLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDbkIsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTO1lBQ3ZCLFVBQVUsRUFBRSxFQUFFLENBQUMsT0FBTztTQUN2QixDQUFDO0lBQ0osQ0FBQztJQUVELGtCQUFrQjtJQUNsQixpQkFBaUIsQ0FBQyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUEyQjtRQUN6RSxJQUFJLFlBQVksS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUMzQixJQUFBLGtDQUFvQixFQUFDLEdBQWEsRUFBRSxTQUFtQixDQUFDLENBQUM7UUFDM0QsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLElBQUksb0NBQXlCLEVBQUUsQ0FBQztRQUN4QyxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBNy9CRCxrQkE2L0JDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgeyBjcmVhdGVIYXNoLCBIYXNoLCByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBDb2luRmFtaWx5LCBCYXNlQ29pbiBhcyBTdGF0aWNzQmFzZUNvaW4gfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IGJpcDMyIH0gZnJvbSAnQGJpdGdvLWJldGEvc2VjcDI1NmsxJztcbmltcG9ydCAqIGFzIHJlcXVlc3QgZnJvbSAnc3VwZXJhZ2VudCc7XG5pbXBvcnQge1xuICBCYXNlQ29pbixcbiAgQml0R29CYXNlLFxuICBjb21tb24sXG4gIGdldEJpcDMyS2V5c0FzeW5jLFxuICBnZXRJc0tyc1JlY292ZXJ5LFxuICBnZXRJc1Vuc2lnbmVkU3dlZXAsXG4gIEtleVBhaXIsXG4gIEtleUluZGljZXMsXG4gIE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIE1QQ0FsZ29yaXRobSxcbiAgUGFyc2VkVHJhbnNhY3Rpb24sXG4gIFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zLFxuICBTaWduZWRUcmFuc2FjdGlvbixcbiAgU2lnblRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbixcbiAgVHJhbnNhY3Rpb25GZWUsXG4gIFRyYW5zYWN0aW9uUHJlYnVpbGQgYXMgQmFzZVRyYW5zYWN0aW9uUHJlYnVpbGQsXG4gIFRyYW5zYWN0aW9uUmVjaXBpZW50IGFzIFJlY2lwaWVudCxcbiAgVmVyaWZ5QWRkcmVzc09wdGlvbnMsXG4gIFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgQmFzZVRyYW5zYWN0aW9uLFxuICBNdWx0aXNpZ1R5cGUsXG4gIG11bHRpc2lnVHlwZXMsXG4gIEF1ZGl0RGVjcnlwdGVkS2V5UGFyYW1zLFxuICBBZGRyZXNzQ29pblNwZWNpZmljLFxuICB2ZXJpZnlNUENXYWxsZXRBZGRyZXNzLFxuICBpc1Rzc1ZlcmlmeUFkZHJlc3NPcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBhdWRpdEVjZHNhUHJpdmF0ZUtleSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1saWItbXBjJztcbmltcG9ydCB7IEVudW0sIEludGVyZmFjZSwgVXRpbHMsIFdyYXBwZWRCdWlsZGVyLCBLZXlQYWlyIGFzIFRyb25LZXlQYWlyIH0gZnJvbSAnLi9saWInO1xuaW1wb3J0IHsgVmFsdWVGaWVsZHMsIFRyYW5zYWN0aW9uUmVjZWlwdCB9IGZyb20gJy4vbGliL2lmYWNlJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2xpYi9idWlsZGVyJztcbmltcG9ydCB7IGlzSW50ZWdlciwgaXNVbmRlZmluZWQgfSBmcm9tICdsb2Rhc2gnO1xuXG5leHBvcnQgY29uc3QgTUlOSU1VTV9UUk9OX01TSUdfVFJBTlNBQ1RJT05fRkVFID0gMWU2O1xuZXhwb3J0IGNvbnN0IFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUgPSAyLjEgKiAxZTY7IC8vIFRST04gZm91bmRhdGlvbiByZWNvbW1lbmRzIDIuMSBUUlggYXMgZmVlcyBmb3IgZ3VhcmFudGVlZCB0cmFuc2FjdGlvblxuZXhwb3J0IGNvbnN0IFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUgPSAxMDAgKiAxZTY7IC8vIFRST04gZm91bmRhdGlvbiByZWNvbW1lbmRzIDEwMCBUUlggYXMgZmVlcyBmb3IgZ3VhcmFudGVlZCB0cmFuc2FjdGlvblxuZXhwb3J0IGNvbnN0IFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZID0gODY0MDAwMDA7IC8vIDI0IGhvdXJcbmV4cG9ydCBjb25zdCBERUZBVUxUX1NDQU5fRkFDVE9SID0gMjA7IC8vIGRlZmF1bHQgbnVtYmVyIG9mIHJlY2VpdmUgYWRkcmVzc2VzIHRvIHNjYW4gZm9yIGZ1bmRzXG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJvblNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBTaWduVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhQcmVidWlsZDogVHJhbnNhY3Rpb25QcmVidWlsZDtcbiAgcHJ2OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHhJbmZvIHtcbiAgcmVjaXBpZW50czogUmVjaXBpZW50W107XG4gIGZyb206IHN0cmluZztcbiAgdHhpZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFkZHJlc3NJbmZvIHtcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjaGFpbjogbnVtYmVyO1xuICBpbmRleDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyb25UcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGV4dGVuZHMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiB7XG4gIGV4cGlyYXRpb246IG51bWJlcjtcbiAgdGltZXN0YW1wOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25QcmVidWlsZCBleHRlbmRzIEJhc2VUcmFuc2FjdGlvblByZWJ1aWxkIHtcbiAgdHhIZXg6IHN0cmluZztcbiAgdHhJbmZvOiBUeEluZm87XG4gIGFkZHJlc3NJbmZvPzogQWRkcmVzc0luZm87XG4gIGZlZUluZm86IFRyYW5zYWN0aW9uRmVlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eEhleD86IHN0cmluZzsgLy8gdHhIZXggaXMgcG9vcmx5IG5hbWVkIGhlcmU7IGl0IGlzIGp1c3QgYSB3cmFwcGVkIEpTT04gb2JqZWN0XG4gIGhhbGZTaWduZWQ/OiB7XG4gICAgdHhIZXg6IHN0cmluZzsgLy8gdHhIZXggaXMgcG9vcmx5IG5hbWVkIGhlcmU7IGl0IGlzIGp1c3QgYSB3cmFwcGVkIEpTT04gb2JqZWN0XG4gIH07XG4gIGZlZUluZm86IFRyYW5zYWN0aW9uRmVlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY292ZXJ5T3B0aW9ucyB7XG4gIHVzZXJLZXk6IHN0cmluZzsgLy8gQm94IEFcbiAgYmFja3VwS2V5OiBzdHJpbmc7IC8vIEJveCBCXG4gIGJpdGdvS2V5OiBzdHJpbmc7IC8vIEJveCBDIC0gdGhpcyBpcyBiaXRnbydzIHhwdWIgYW5kIHdpbGwgYmUgdXNlZCB0byBkZXJpdmUgdGhlaXIgcm9vdCBhZGRyZXNzXG4gIHJlY292ZXJ5RGVzdGluYXRpb246IHN0cmluZzsgLy8gYmFzZTU4IGFkZHJlc3NcbiAga3JzUHJvdmlkZXI/OiBzdHJpbmc7XG4gIHRva2VuQ29udHJhY3RBZGRyZXNzPzogc3RyaW5nO1xuICB3YWxsZXRQYXNzcGhyYXNlPzogc3RyaW5nO1xuICBzdGFydGluZ1NjYW5JbmRleD86IG51bWJlcjtcbiAgc2Nhbj86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zIHtcbiAgdXNlcktleTogc3RyaW5nO1xuICBiYWNrdXBLZXk6IHN0cmluZztcbiAgYml0Z29LZXk6IHN0cmluZztcbiAgdG9rZW5Db250cmFjdEFkZHJlc3M/OiBzdHJpbmc7XG4gIHN0YXJ0aW5nU2NhbkluZGV4PzogbnVtYmVyOyAvLyBkZWZhdWx0IHRvIDEgKGluY2x1c2l2ZSlcbiAgZW5kaW5nU2NhbkluZGV4PzogbnVtYmVyOyAvLyBkZWZhdWx0IHRvIHN0YXJ0aW5nU2NhbkluZGV4ICsgMjAgKGV4Y2x1c2l2ZSlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb25zb2xpZGF0aW9uUmVjb3ZlcnlCYXRjaCB7XG4gIHRyYW5zYWN0aW9uczogUmVjb3ZlcnlUcmFuc2FjdGlvbltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZlZUluZm8ge1xuICBmZWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyeVRyYW5zYWN0aW9uIHtcbiAgdHhIZXg/OiBzdHJpbmc7XG4gIGZlZUluZm8/OiBGZWVJbmZvO1xuICBjb2luPzogc3RyaW5nO1xuICB0eD86IFRyYW5zYWN0aW9uUHJlYnVpbGQ7XG4gIHJlY292ZXJ5QW1vdW50PzogbnVtYmVyO1xuICB0b2tlblR4cz86IFRyYW5zYWN0aW9uUmVjZWlwdFtdO1xuICBhZGRyZXNzSW5mbz86IEFkZHJlc3NJbmZvO1xufVxuXG5leHBvcnQgZW51bSBOb2RlVHlwZXMge1xuICBGdWxsLFxuICBTb2xpZGl0eSxcbn1cblxuLyoqXG4gKiBUaGlzIHN0cnVjdHVyZSBpcyBub3QgYSBjb21wbGV0ZSBtb2RlbCBvZiB0aGUgQWNjb3VudFJlc3BvbnNlIGZyb20gYSBub2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjY291bnRSZXNwb25zZSB7XG4gIGRhdGE6IFtJbnRlcmZhY2UuQWNjb3VudEluZm9dO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyeFZlcmlmeUFkZHJlc3NPcHRpb25zIGV4dGVuZHMgVmVyaWZ5QWRkcmVzc09wdGlvbnMge1xuICBpbmRleD86IG51bWJlciB8IHN0cmluZztcbiAgY2hhaW4/OiBudW1iZXI7XG4gIGNvaW5TcGVjaWZpYz86IEFkZHJlc3NDb2luU3BlY2lmaWMgJiB7XG4gICAgaW5kZXg/OiBudW1iZXIgfCBzdHJpbmc7XG4gICAgY2hhaW4/OiBudW1iZXI7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzVHJ4VmVyaWZ5QWRkcmVzc09wdGlvbnMocGFyYW1zOiBWZXJpZnlBZGRyZXNzT3B0aW9ucyk6IHBhcmFtcyBpcyBUcnhWZXJpZnlBZGRyZXNzT3B0aW9ucyB7XG4gIHJldHVybiAoXG4gICAgJ2luZGV4JyBpbiBwYXJhbXMgfHxcbiAgICAnY2hhaW4nIGluIHBhcmFtcyB8fFxuICAgICgnY29pblNwZWNpZmljJyBpbiBwYXJhbXMgJiZcbiAgICAgIHBhcmFtcy5jb2luU3BlY2lmaWMgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgKCdpbmRleCcgaW4gcGFyYW1zLmNvaW5TcGVjaWZpYyB8fCAnY2hhaW4nIGluIHBhcmFtcy5jb2luU3BlY2lmaWMpKVxuICApO1xufVxuXG5leHBvcnQgY2xhc3MgVHJ4IGV4dGVuZHMgQmFzZUNvaW4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgX3N0YXRpY3NDb2luOiBSZWFkb25seTxTdGF0aWNzQmFzZUNvaW4+O1xuXG4gIGNvbnN0cnVjdG9yKGJpdGdvOiBCaXRHb0Jhc2UsIHN0YXRpY3NDb2luPzogUmVhZG9ubHk8U3RhdGljc0Jhc2VDb2luPikge1xuICAgIHN1cGVyKGJpdGdvKTtcblxuICAgIGlmICghc3RhdGljc0NvaW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyByZXF1aXJlZCBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgc3RhdGljc0NvaW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0aWNzQ29pbiA9IHN0YXRpY3NDb2luO1xuICB9XG5cbiAgZ2V0Q2hhaW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLm5hbWU7XG4gIH1cblxuICBnZXRGYW1pbHkoKTogQ29pbkZhbWlseSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRpY3NDb2luLmZhbWlseTtcbiAgfVxuXG4gIGdldEZ1bGxOYW1lKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0aWNzQ29pbi5mdWxsTmFtZTtcbiAgfVxuXG4gIGdldEJhc2VGYWN0b3IoKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCB0aGlzLl9zdGF0aWNzQ29pbi5kZWNpbWFsUGxhY2VzKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB0cmFuc2FjdGlvbkRhdGFBbGxvd2VkKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgZ2V0RGVmYXVsdE11bHRpc2lnVHlwZSgpOiBNdWx0aXNpZ1R5cGUge1xuICAgIHJldHVybiBtdWx0aXNpZ1R5cGVzLm9uY2hhaW47XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgc3VwcG9ydHNUc3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgZ2V0TVBDQWxnb3JpdGhtKCk6IE1QQ0FsZ29yaXRobSB7XG4gICAgcmV0dXJuICdlY2RzYSc7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgZ2V0SGFzaEZ1bmN0aW9uKCk6IEhhc2gge1xuICAgIHJldHVybiBjcmVhdGVIYXNoKCdzaGEyNTYnKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlLCBzdGF0aWNzQ29pbj86IFJlYWRvbmx5PFN0YXRpY3NCYXNlQ29pbj4pOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBUcngoYml0Z28sIHN0YXRpY3NDb2luKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBzdXBwb3J0c1Jlc291cmNlRGVsZWdhdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGJhc2U1OFxuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKi9cbiAgaXNWYWxpZEFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFhZGRyZXNzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIFV0aWxzLmlzQmFzZTU4QWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhpcyBpcyBhIHZhbGlkIGhleCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhZGRyZXNzIGhleCBhZGRyZXNzXG4gICAqL1xuICBpc1ZhbGlkSGV4QWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gL140MVswLTlhLWZdezQwfSQvaS50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIGVkMjU1MTkga2V5IHBhaXJcbiAgICpcbiAgICogQHBhcmFtIHNlZWRcbiAgICogQHJldHVybnMge09iamVjdH0gb2JqZWN0IHdpdGggZ2VuZXJhdGVkIHB1YiwgcHJ2XG4gICAqL1xuICBnZW5lcmF0ZUtleVBhaXIoc2VlZD86IEJ1ZmZlcik6IEtleVBhaXIge1xuICAgIC8vIFRPRE86IG1vdmUgdGhpcyBhbmQgYWRkcmVzcyBjcmVhdGlvbiBsb2dpYyB0byBhY2NvdW50LWxpYlxuICAgIGlmICghc2VlZCkge1xuICAgICAgLy8gQW4gZXh0ZW5kZWQgcHJpdmF0ZSBrZXkgaGFzIGJvdGggYSBub3JtYWwgMjU2IGJpdCBwcml2YXRlIGtleSBhbmQgYSAyNTYgYml0IGNoYWluIGNvZGUsIGJvdGggb2Ygd2hpY2ggbXVzdCBiZVxuICAgICAgLy8gcmFuZG9tLiA1MTIgYml0cyBpcyB0aGVyZWZvcmUgdGhlIG1heGltdW0gZW50cm9weSBhbmQgZ2l2ZXMgdXMgbWF4aW11bSBzZWN1cml0eSBhZ2FpbnN0IGNyYWNraW5nLlxuICAgICAgc2VlZCA9IHJhbmRvbUJ5dGVzKDUxMiAvIDgpO1xuICAgIH1cbiAgICBjb25zdCBoZCA9IGJpcDMyLmZyb21TZWVkKHNlZWQpO1xuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGhkLm5ldXRlcmVkKCkudG9CYXNlNTgoKSxcbiAgICAgIHBydjogaGQudG9CYXNlNTgoKSxcbiAgICB9O1xuICB9XG5cbiAgaXNWYWxpZFhwdWIoeHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBiaXAzMi5mcm9tQmFzZTU4KHhwdWIpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaXNWYWxpZFB1YihwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLmlzVmFsaWRYcHViKHB1YikpIHtcbiAgICAgIC8vIHhwdWJzIGNhbiBiZSBjb252ZXJ0ZWQgaW50byByZWd1bGFyIHB1YnMsIHNvIHRlY2huaWNhbGx5IGl0IGlzIGEgdmFsaWQgcHViXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAoJ14wNFthLXpBLVowLTldezEyOH0kJykudGVzdChwdWIpO1xuICB9XG5cbiAgYXN5bmMgcGFyc2VUcmFuc2FjdGlvbihwYXJhbXM6IFBhcnNlVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxQYXJzZWRUcmFuc2FjdGlvbj4ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGFzeW5jIGlzV2FsbGV0QWRkcmVzcyhwYXJhbXM6IFZlcmlmeUFkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgeyBhZGRyZXNzLCBrZXljaGFpbnMgfSA9IHBhcmFtcztcblxuICAgIGlmIChpc1Rzc1ZlcmlmeUFkZHJlc3NPcHRpb25zKHBhcmFtcykpIHtcbiAgICAgIHJldHVybiB2ZXJpZnlNUENXYWxsZXRBZGRyZXNzKFxuICAgICAgICB7IC4uLnBhcmFtcywga2V5Q3VydmU6ICdzZWNwMjU2azEnIH0sXG4gICAgICAgIHRoaXMuaXNWYWxpZEFkZHJlc3MuYmluZCh0aGlzKSxcbiAgICAgICAgKHB1YktleTogc3RyaW5nKSA9PiBuZXcgVHJvbktleVBhaXIoeyBwdWI6IHB1YktleSB9KS5nZXRBZGRyZXNzKClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKCFpc1RyeFZlcmlmeUFkZHJlc3NPcHRpb25zKHBhcmFtcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBvciBtaXNzaW5nIGluZGV4IGZvciBhZGRyZXNzIHZlcmlmaWNhdGlvbicpO1xuICAgIH1cblxuICAgIGNvbnN0IHJhd0luZGV4ID0gcGFyYW1zLmluZGV4ID8/IHBhcmFtcy5jb2luU3BlY2lmaWM/LmluZGV4O1xuICAgIGNvbnN0IGluZGV4ID0gTnVtYmVyKHJhd0luZGV4KTtcbiAgICBpZiAoaXNOYU4oaW5kZXgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5kZXguIGluZGV4IG11c3QgYmUgYSBudW1iZXIuJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY2hhaW4gPSBOdW1iZXIocGFyYW1zLmNoYWluID8/IHBhcmFtcy5jb2luU3BlY2lmaWM/LmNoYWluID8/IDApO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgIH1cblxuICAgIC8vIFJvb3QgYWRkcmVzcyB2ZXJpZmljYXRpb24gKEluZGV4IDApXG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICBjb25zdCBiaXRnb1B1YiA9IGtleWNoYWlucyAmJiBrZXljaGFpbnMubGVuZ3RoID4gS2V5SW5kaWNlcy5CSVRHTyA/IGtleWNoYWluc1tLZXlJbmRpY2VzLkJJVEdPXS5wdWIgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoIWJpdGdvUHViKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQml0R28gcHVibGljIGtleSByZXF1aXJlZCBmb3Igcm9vdCBhZGRyZXNzIHZlcmlmaWNhdGlvbicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMudmVyaWZ5Um9vdEFkZHJlc3MoYWRkcmVzcywgYml0Z29QdWIpO1xuICAgIH1cblxuICAgIC8vIFJlY2VpdmUgYWRkcmVzcyB2ZXJpZmljYXRpb24gKEluZGV4ID4gMClcbiAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICBjb25zdCB1c2VyUHViID0ga2V5Y2hhaW5zICYmIGtleWNoYWlucy5sZW5ndGggPiBLZXlJbmRpY2VzLlVTRVIgPyBrZXljaGFpbnNbS2V5SW5kaWNlcy5VU0VSXS5wdWIgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoIXVzZXJQdWIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVc2VyIHB1YmxpYyBrZXkgcmVxdWlyZWQgZm9yIHJlY2VpdmUgYWRkcmVzcyB2ZXJpZmljYXRpb24nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnZlcmlmeVJlY2VpdmVBZGRyZXNzKGFkZHJlc3MsIHVzZXJQdWIsIGluZGV4LCBjaGFpbik7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGluZGV4IGZvciBhZGRyZXNzIHZlcmlmaWNhdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyeXB0b2dyYXBoaWNhbGx5IHZlcmlmeSB0aGF0IGFuIGFkZHJlc3MgaXMgdGhlIHJvb3QgYWRkcmVzcyBkZXJpdmVkIGZyb20gQml0R28ncyBwdWJsaWMga2V5XG4gICAqL1xuICBwcml2YXRlIHZlcmlmeVJvb3RBZGRyZXNzKGFkZHJlc3M6IHN0cmluZywgYml0Z29QdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkWHB1YihiaXRnb1B1YikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBiaXRnbyBwdWJsaWMga2V5Jyk7XG4gICAgfVxuICAgIGNvbnN0IHVuY29tcHJlc3NlZFB1YiA9IHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKGJpdGdvUHViKTtcbiAgICBjb25zdCBieXRlQXJyYXlBZGRyID0gVXRpbHMuZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3ModW5jb21wcmVzc2VkUHViKTtcbiAgICBjb25zdCByYXdBZGRyZXNzID0gVXRpbHMuZ2V0UmF3QWRkcmVzc0Zyb21QdWJLZXkoYnl0ZUFycmF5QWRkcik7XG4gICAgY29uc3QgZGVyaXZlZEFkZHJlc3MgPSBVdGlscy5nZXRCYXNlNThBZGRyZXNzRnJvbUJ5dGVBcnJheShyYXdBZGRyZXNzKTtcbiAgICByZXR1cm4gZGVyaXZlZEFkZHJlc3MgPT09IGFkZHJlc3M7XG4gIH1cblxuICAvKipcbiAgICogQ3J5cHRvZ3JhcGhpY2FsbHkgdmVyaWZ5IHRoYXQgYW4gYWRkcmVzcyBpcyBhIHJlY2VpdmUgYWRkcmVzcyBkZXJpdmVkIGZyb20gdXNlcidzIGtleVxuICAgKi9cbiAgcHJpdmF0ZSB2ZXJpZnlSZWNlaXZlQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcsIHVzZXJQdWI6IHN0cmluZywgaW5kZXg6IG51bWJlciwgY2hhaW46IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkWHB1Yih1c2VyUHViKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHVzZXIgcHVibGljIGtleScpO1xuICAgIH1cbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IGAwLzAvJHtjaGFpbn0vJHtpbmRleH1gO1xuICAgIGNvbnN0IHBhcmVudEtleSA9IGJpcDMyLmZyb21CYXNlNTgodXNlclB1Yik7XG4gICAgY29uc3QgY2hpbGRLZXkgPSBwYXJlbnRLZXkuZGVyaXZlUGF0aChkZXJpdmF0aW9uUGF0aCk7XG4gICAgY29uc3QgZGVyaXZlZFB1YktleUhleCA9IGNoaWxkS2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3Qga2V5cGFpciA9IG5ldyBUcm9uS2V5UGFpcih7IHB1YjogZGVyaXZlZFB1YktleUhleCB9KTtcbiAgICBjb25zdCBkZXJpdmVkQWRkcmVzcyA9IGtleXBhaXIuZ2V0QWRkcmVzcygpO1xuICAgIHJldHVybiBkZXJpdmVkQWRkcmVzcyA9PT0gYWRkcmVzcztcbiAgfVxuXG4gIGFzeW5jIHZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtczogVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3QgeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgd2FsbGV0VHlwZSB9ID0gcGFyYW1zO1xuXG4gICAgaWYgKCF0eFBhcmFtcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4UGFyYW1zJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0eFByZWJ1aWxkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdHhQcmVidWlsZCcpO1xuICAgIH1cblxuICAgIGlmICghdHhQcmVidWlsZC50eEhleCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHR4SGV4IGluIHR4UHJlYnVpbGQnKTtcbiAgICB9XG5cbiAgICBpZiAod2FsbGV0VHlwZSA9PT0gJ3RzcycpIHtcbiAgICAgIC8vIEZvciBUU1Mgd2FsbGV0cywgdmVyaWZ5VHJhbnNhY3Rpb24gaXMgY2FsbGVkIGZyb20gdHdvIHBsYWNlczpcbiAgICAgIC8vIDEuIHByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uICh3YWxsZXQudHMpIOKAlCB0eEhleCBpcyBzZXJpYWxpemVkVHhIZXgsIGEgZnVsbCBKU09OIHN0cmluZ1xuICAgICAgLy8gICAgY29udGFpbmluZyB7IHR4SUQsIHJhd19kYXRhLCByYXdfZGF0YV9oZXggfS5cbiAgICAgIC8vIDIuIEVDRFNBIHNpZ25pbmcgZmxvdyAoZWNkc2EudHMpIOKAlCB0eEhleCBpcyBzaWduYWJsZUhleCwgdGhlIHJhdyBwcm90b2J1ZiBieXRlcyAocmF3X2RhdGFfaGV4KS5cbiAgICAgIC8vIFdlIG5lZWQgdG8gZXh0cmFjdCB0aGUgcmF3X2RhdGFfaGV4IGluIGNhc2UgMSBiZWZvcmUgZGVjb2RpbmcuXG4gICAgICBjb25zdCByYXdEYXRhSGV4ID0gdGhpcy5leHRyYWN0UmF3RGF0YUhleCh0eFByZWJ1aWxkLnR4SGV4KTtcbiAgICAgIGNvbnN0IGRlY29kZWRUeCA9IFV0aWxzLmRlY29kZVRyYW5zYWN0aW9uKHJhd0RhdGFIZXgpO1xuXG4gICAgICAvLyBkZWNvZGVkVHggdXNlcyBhIG51bWVyaWMgZW51bSBmb3IgY29udHJhY3QgdHlwZSAoZnJvbSBwcm90b2J1ZiBkZWNvZGluZyksXG4gICAgICAvLyB1bmxpa2UgdGhlIG11bHRpc2lnIHBhdGggd2hpY2ggY2hlY2tzIHRoZSBzdHJpbmcgJ1RyYW5zZmVyQ29udHJhY3QnIGZyb20gbm9kZSBKU09OLlxuICAgICAgaWYgKGRlY29kZWRUeC5jb250cmFjdFR5cGUgPT09IEVudW0uQ29udHJhY3RUeXBlLlRyYW5zZmVyKSB7XG4gICAgICAgIC8vIEZvciBUcmFuc2ZlciBjb250cmFjdHMsIGRlY29kZWQgY29udHJhY3QgaXMgYW4gYXJyYXkgd2l0aCBvbmUgZWxlbWVudC5cbiAgICAgICAgLy8gQWRkcmVzc2VzIGZyb20gZGVjb2RlVHJhbnNhY3Rpb24gYXJlIGFscmVhZHkgaW4gYmFzZTU4IGZvcm1hdCAoY29udmVydGVkIGJ5IGRlY29kZVRyYW5zZmVyQ29udHJhY3QpLlxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGVjb2RlZFR4LmNvbnRyYWN0KSB8fCBkZWNvZGVkVHguY29udHJhY3QubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFRyYW5zZmVyIGNvbnRyYWN0IHN0cnVjdHVyZS4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVRyYW5zZmVyQ29udHJhY3QoZGVjb2RlZFR4LmNvbnRyYWN0WzBdLCB0eFBhcmFtcywgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWNvZGVkVHguY29udHJhY3RUeXBlID09PSBFbnVtLkNvbnRyYWN0VHlwZS5UcmlnZ2VyU21hcnRDb250cmFjdCkge1xuICAgICAgICAvLyBUUkMyMCB0b2tlbiB0cmFuc2ZlcnMgKFRyaWdnZXJTbWFydENvbnRyYWN0KSBtdXN0IGJlIHZlcmlmaWVkIHZpYSBUcnhUb2tlbi52ZXJpZnlUcmFuc2FjdGlvbixcbiAgICAgICAgLy8gbm90IGhlcmUuIEZhaWwgY2xvc2VkIHRvIHByZXZlbnQgdW52YWxpZGF0ZWQgdG9rZW4gdHJhbnNmZXJzIGZyb20gYmVpbmcgc2lsZW50bHkgc2lnbmVkLlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ1RyaWdnZXJTbWFydENvbnRyYWN0IHZlcmlmaWNhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGJ5IG5hdGl2ZSBUUlguICcgK1xuICAgICAgICAgICAgJ1RSQzIwIHRva2VuIHRyYW5zZmVycyBtdXN0IGJlIHZlcmlmaWVkIHZpYSBUcnhUb2tlbi52ZXJpZnlUcmFuc2FjdGlvbi4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIE9uLWNoYWluIG11bHRpc2lnIHBhdGg6IHR4SGV4IGlzIGEgZnVsbCB0cmFuc2FjdGlvbiBKU09OIHN0cmluZyAod2l0aCB0eElELCByYXdfZGF0YSwgcmF3X2RhdGFfaGV4KS5cbiAgICAvLyBUaGUgYnVpbGRlciBwYXJzZXMgdGhpcyBKU09OIGFuZCBhZGRyZXNzZXMgcmVtYWluIGluIGhleCBmb3JtYXQgZnJvbSB0aGUgbm9kZSByZXNwb25zZS5cbiAgICBjb25zdCByYXdUeCA9IHR4UHJlYnVpbGQudHhIZXg7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocmF3VHgpO1xuICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG5cbiAgICBpZiAoIXR4SnNvbi5yYXdfZGF0YSB8fCAhdHhKc29uLnJhd19kYXRhLmNvbnRyYWN0IHx8IHR4SnNvbi5yYXdfZGF0YS5jb250cmFjdC5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTnVtYmVyIG9mIGNvbnRyYWN0cyBpcyBncmVhdGVyIHRoYW4gMS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250cmFjdCA9IHR4SnNvbi5yYXdfZGF0YS5jb250cmFjdFswXTtcblxuICAgIGlmIChjb250cmFjdC50eXBlID09PSAnVHJhbnNmZXJDb250cmFjdCcpIHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlVHJhbnNmZXJDb250cmFjdChjb250cmFjdCwgdHhQYXJhbXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCB0aGUgcmF3IHByb3RvYnVmIGhleCAocmF3X2RhdGFfaGV4KSBmcm9tIGEgVFNTIHR4SGV4LlxuICAgKlxuICAgKiBUU1MgdmVyaWZ5VHJhbnNhY3Rpb24gaXMgY2FsbGVkIGZyb20gdHdvIHBsYWNlczpcbiAgICogICAxLiBwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbiDigJQgdHhIZXggaXMgYSBmdWxsIEpTT04gc3RyaW5nIGNvbnRhaW5pbmcgcmF3X2RhdGFfaGV4LlxuICAgKiAgIDIuIEVDRFNBIHNpZ25pbmcgZmxvdyDigJQgdHhIZXggaXMgYWxyZWFkeSB0aGUgcmF3IHByb3RvYnVmIGhleCAocmF3X2RhdGFfaGV4KS5cbiAgICpcbiAgICogVGhpcyBoZWxwZXIgaGFuZGxlcyBib3RoIGZvcm1hdHMgc28gY2FsbGVycyBkb24ndCBkdXBsaWNhdGUgdGhlIHRyeS9jYXRjaC5cbiAgICovXG4gIHByb3RlY3RlZCBleHRyYWN0UmF3RGF0YUhleCh0eEhleDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UodHhIZXgpLnJhd19kYXRhX2hleDtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnNvbGUuZGVidWcoYENvdWxkIG5vdCBwYXJzZSB0eEhleCBhcyBKU09OIGZvciBjb2luICR7dGhpcy5nZXRDaGFpbigpfSwgdXNpbmcgdHhIZXggZGlyZWN0bHlgKTtcbiAgICAgIHJldHVybiB0eEhleDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgVHJhbnNmZXIgY29udHJhY3QgKG5hdGl2ZSBUUlggdHJhbnNmZXIpLlxuICAgKiBTaGFyZWQgYnkgYm90aCBvbi1jaGFpbiBtdWx0aXNpZyBhbmQgVFNTIHdhbGxldCB2ZXJpZmljYXRpb24gcGF0aHMuXG4gICAqXG4gICAqIEBwYXJhbSBjb250cmFjdCBUaGUgY29udHJhY3Qgb2JqZWN0IGZyb20gdGhlIHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB0eFBhcmFtcyBUaGUgb3JpZ2luYWwgdHJhbnNhY3Rpb24gcGFyYW1ldGVyc1xuICAgKiBAcGFyYW0gYWRkcmVzc2VzSW5CYXNlNTggV2hlbiB0cnVlLCBhZGRyZXNzZXMgYXJlIGFscmVhZHkgaW4gYmFzZTU4IGZvcm1hdCAoVFNTIHBhdGggdmlhIHByb3RvYnVmIGRlY29kaW5nKS5cbiAgICogICBXaGVuIGZhbHNlIChkZWZhdWx0KSwgYWRkcmVzc2VzIGFyZSBpbiBoZXggYW5kIG5lZWQgY29udmVyc2lvbiAob24tY2hhaW4gbXVsdGlzaWcgcGF0aCB2aWEgYnVpbGRlciBKU09OKS5cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVUcmFuc2ZlckNvbnRyYWN0KGNvbnRyYWN0OiBhbnksIHR4UGFyYW1zOiBhbnksIGFkZHJlc3Nlc0luQmFzZTU4ID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICBpZiAoISgncGFyYW1ldGVyJyBpbiBjb250cmFjdCkgfHwgIWNvbnRyYWN0LnBhcmFtZXRlcj8udmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBUcmFuc2ZlciBjb250cmFjdCBzdHJ1Y3R1cmUnKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZSA9IGNvbnRyYWN0LnBhcmFtZXRlci52YWx1ZSBhcyBWYWx1ZUZpZWxkcztcblxuICAgIC8vIFZhbGlkYXRlIGFtb3VudFxuICAgIGlmICghdmFsdWUuYW1vdW50IHx8IHZhbHVlLmFtb3VudCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0cmFuc2ZlciBhbW91bnQnKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0eFBhcmFtcyBoYXMgcmVjaXBpZW50cywgdmFsaWRhdGUgYWdhaW5zdCBleHBlY3RlZCB2YWx1ZXNcbiAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cyAmJiB0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgcmVjaXBpZW50ID0gdHhQYXJhbXMucmVjaXBpZW50c1swXTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkQW1vdW50ID0gcmVjaXBpZW50LmFtb3VudC50b1N0cmluZygpO1xuICAgICAgY29uc3QgZXhwZWN0ZWREZXN0aW5hdGlvbiA9IHJlY2lwaWVudC5hZGRyZXNzO1xuICAgICAgY29uc3QgYWN0dWFsQW1vdW50ID0gdmFsdWUuYW1vdW50LnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBhY3R1YWxEZXN0aW5hdGlvbiA9IGFkZHJlc3Nlc0luQmFzZTU4ID8gdmFsdWUudG9fYWRkcmVzcyA6IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHZhbHVlLnRvX2FkZHJlc3MpO1xuXG4gICAgICBpZiAoZXhwZWN0ZWRBbW91bnQgIT09IGFjdHVhbEFtb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoZSB2YWx1ZSBnaXZlbiBieSBjbGllbnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV4cGVjdGVkRGVzdGluYXRpb24udG9Mb3dlckNhc2UoKSAhPT0gYWN0dWFsRGVzdGluYXRpb24udG9Mb3dlckNhc2UoKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Rlc3RpbmF0aW9uIGFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggd2l0aCB0aGUgcmVjaXBpZW50IGFkZHJlc3MnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdERvYyAqL1xuICBhc3luYyBnZXRTaWduYWJsZVBheWxvYWQoc2VyaWFsaXplZFR4OiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIodGhpcy5nZXRDaGFpbigpKS5mcm9tKHNlcmlhbGl6ZWRUeCk7XG4gICAgY29uc3QgcmVidWlsdFRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgcmV0dXJuIHJlYnVpbHRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG4gIH1cblxuICAvKipcbiAgICogRGVyaXZlIGEgdXNlciBrZXkgdXNpbmcgdGhlIGNoYWluIHBhdGggb2YgdGhlIGFkZHJlc3NcbiAgICogQHBhcmFtIGtleVxuICAgKiBAcGFyYW0gcGF0aFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBkZXJpdmVkIHByaXZhdGUga2V5XG4gICAqL1xuICBkZXJpdmVLZXlXaXRoUGF0aCh7IGtleSwgcGF0aCB9OiB7IGtleTogc3RyaW5nOyBwYXRoOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgY29uc3Qga2V5Y2hhaW4gPSBiaXAzMi5mcm9tQmFzZTU4KGtleSk7XG4gICAgY29uc3QgZGVyaXZlZEtleU5vZGUgPSBrZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpO1xuICAgIHJldHVybiBkZXJpdmVkS2V5Tm9kZS50b0Jhc2U1OCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge09iamVjdH0gcHJlYnVpbGQgb2JqZWN0IHJldHVybmVkIGJ5IHBsYXRmb3JtXG4gICAqIEBwYXJhbSBwYXJhbXMucHJ2IHtTdHJpbmd9IHVzZXIgcHJ2XG4gICAqIEByZXR1cm5zIEJsdWViaXJkPFNpZ25lZFRyYW5zYWN0aW9uPlxuICAgKi9cbiAgYXN5bmMgc2lnblRyYW5zYWN0aW9uKHBhcmFtczogVHJvblNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFNpZ25lZFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocGFyYW1zLnR4UHJlYnVpbGQudHhIZXgpO1xuXG4gICAgbGV0IGtleTtcbiAgICBjb25zdCB7IGNoYWluLCBpbmRleCB9ID0gcGFyYW1zLnR4UHJlYnVpbGQ/LmFkZHJlc3NJbmZvID8/IHsgY2hhaW46IDAsIGluZGV4OiAwIH07XG4gICAgaWYgKGNoYWluID09PSAwICYmIGluZGV4ID09PSAwKSB7XG4gICAgICBrZXkgPSBwYXJhbXMucHJ2O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9IGAwLzAvJHtjaGFpbn0vJHtpbmRleH1gO1xuICAgICAga2V5ID0gdGhpcy5kZXJpdmVLZXlXaXRoUGF0aCh7IGtleTogcGFyYW1zLnBydiwgcGF0aDogZGVyaXZhdGlvblBhdGggfSk7XG4gICAgfVxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5IH0pO1xuXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHtcbiAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh0cmFuc2FjdGlvbi50b0pzb24oKSksXG4gICAgfTtcbiAgICBpZiAodHJhbnNhY3Rpb24udG9Kc29uKCkuc2lnbmF0dXJlLmxlbmd0aCA+PSAyKSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfVxuICAgIC8vIEhhbGYgc2lnbmVkIHRyYW5zYWN0aW9uXG4gICAgcmV0dXJuIHtcbiAgICAgIGhhbGZTaWduZWQ6IHJlc3BvbnNlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHNlZWQgZm9yIHRoZSBjb2luXG4gICAqXG4gICAqIEBwYXJhbSBwcnYgLSB0aGUgcHJ2IHRvIGJlIGNoZWNrZWRcbiAgICovXG4gIGlzVmFsaWRYcHJ2KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAhYmlwMzIuZnJvbUJhc2U1OChwcnYpLmlzTmV1dGVyZWQoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBhIG1lc3NhZ2UgdG8gc3RyaW5nIGluIGhleGFkZWNpbWFsIGZvcm1hdC5cbiAgICpcbiAgICogQHBhcmFtIG1lc3NhZ2Uge0J1ZmZlcnxTdHJpbmd9IG1lc3NhZ2UgdG8gc2lnblxuICAgKiBAcmV0dXJuIHRoZSBtZXNzYWdlIGFzIGEgaGV4YWRlY2ltYWwgc3RyaW5nXG4gICAqL1xuICB0b0hleFN0cmluZyhtZXNzYWdlOiBzdHJpbmcgfCBCdWZmZXIpOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbShtZXNzYWdlKS50b1N0cmluZygnaGV4Jyk7XG4gICAgfSBlbHNlIGlmIChCdWZmZXIuaXNCdWZmZXIobWVzc2FnZSkpIHtcbiAgICAgIHJldHVybiBtZXNzYWdlLnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1lc3NhZ2VkIHBhc3NlZCB0byBzaWduTWVzc2FnZScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIG1lc3NhZ2Ugd2l0aCBwcml2YXRlIGtleVxuICAgKlxuICAgKiBAcGFyYW0ga2V5XG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqL1xuICBhc3luYyBzaWduTWVzc2FnZShrZXk6IEtleVBhaXIsIG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgdG9TaWduID0gdGhpcy50b0hleFN0cmluZyhtZXNzYWdlKTtcblxuICAgIGxldCBwcnY6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGtleS5wcnY7XG4gICAgaWYgKHRoaXMuaXNWYWxpZFhwcnYocHJ2KSkge1xuICAgICAgcHJ2ID0gYmlwMzIuZnJvbUJhc2U1OChwcnYpLnByaXZhdGVLZXk/LnRvU3RyaW5nKCdoZXgnKTtcbiAgICB9XG5cbiAgICBpZiAoIXBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIGxldCBzaWcgPSBVdGlscy5zaWduU3RyaW5nKHRvU2lnbiwgcHJ2LCB0cnVlKTtcblxuICAgIC8vIHJlbW92ZSB0aGUgcHJlY2VkaW5nIDB4XG4gICAgc2lnID0gc2lnLnJlcGxhY2UoL14weC8sICcnKTtcblxuICAgIHJldHVybiBCdWZmZXIuZnJvbShzaWcsICdoZXgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiB4cHViIHRvIGEgdW5jb21wcmVzc2VkIHB1YlxuICAgKiBAcGFyYW0geHB1YlxuICAgKi9cbiAgeHB1YlRvVW5jb21wcmVzc2VkUHViKHhwdWI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmlzVmFsaWRYcHViKHhwdWIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgeHB1YicpO1xuICAgIH1cblxuICAgIGNvbnN0IHB1YmxpY0tleSA9IGJpcDMyLmZyb21CYXNlNTgoeHB1YikucHVibGljS2V5O1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShzZWNwMjU2azEucHVibGljS2V5Q29udmVydChwdWJsaWNLZXksIGZhbHNlIC8qIGNvbXByZXNzZWQgKi8pKS50b1N0cmluZygnaGV4Jyk7XG4gIH1cblxuICAvKipcbiAgICogTW9kaWZ5IHByZWJ1aWxkIGJlZm9yZSBzZW5kaW5nIGl0IHRvIHRoZSBzZXJ2ZXIuXG4gICAqIEBwYXJhbSBidWlsZFBhcmFtcyBUaGUgd2hpdGVsaXN0ZWQgcGFyYW1ldGVycyBmb3IgdGhpcyBwcmVidWlsZFxuICAgKi9cbiAgYXN5bmMgZ2V0RXh0cmFQcmVidWlsZFBhcmFtcyhidWlsZFBhcmFtczogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICBpZiAoYnVpbGRQYXJhbXMucmVjaXBpZW50c1swXS5kYXRhICYmIGJ1aWxkUGFyYW1zLmZlZUxpbWl0KSB7XG4gICAgICBidWlsZFBhcmFtcy5yZWNpcGllbnRzWzBdLmZlZUxpbWl0ID0gYnVpbGRQYXJhbXMuZmVlTGltaXQ7XG4gICAgfVxuICB9XG5cbiAgcHViVG9IZXhBZGRyZXNzKHB1Yjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBieXRlQXJyYXlBZGRyID0gVXRpbHMuZ2V0Qnl0ZUFycmF5RnJvbUhleEFkZHJlc3MocHViKTtcbiAgICBjb25zdCByYXdBZGRyZXNzID0gVXRpbHMuZ2V0UmF3QWRkcmVzc0Zyb21QdWJLZXkoYnl0ZUFycmF5QWRkcik7XG4gICAgcmV0dXJuIFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQnl0ZUFycmF5KHJhd0FkZHJlc3MpO1xuICB9XG5cbiAgeHBydlRvQ29tcHJlc3NlZFBydih4cHJ2OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5pc1ZhbGlkWHBydih4cHJ2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHhwcnYnKTtcbiAgICB9XG5cbiAgICBjb25zdCBoZE5vZGUgPSBiaXAzMi5mcm9tQmFzZTU4KHhwcnYpO1xuICAgIGlmICghaGROb2RlLnByaXZhdGVLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gcHJpdmF0ZUtleScpO1xuICAgIH1cbiAgICByZXR1cm4gaGROb2RlLnByaXZhdGVLZXkudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXROb2RlVXJsKG5vZGU6IE5vZGVUeXBlcyk6IHN0cmluZyB7XG4gICAgc3dpdGNoIChub2RlKSB7XG4gICAgICBjYXNlIE5vZGVUeXBlcy5GdWxsOlxuICAgICAgICByZXR1cm4gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuZnVsbDtcbiAgICAgIGNhc2UgTm9kZVR5cGVzLlNvbGlkaXR5OlxuICAgICAgICByZXR1cm4gY29tbW9uLkVudmlyb25tZW50c1t0aGlzLmJpdGdvLmdldEVudigpXS50cm9uTm9kZXMuc29saWRpdHk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vZGUgdHlwZSBub3QgZm91bmQnKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIE1ha2UgYSBxdWVyeSB0byBUcm9uZ3JpZCBmb3IgaW5mb3JtYXRpb24gc3VjaCBhcyBiYWxhbmNlLCB0b2tlbiBiYWxhbmNlLCBzb2xpZGl0eSBjYWxsc1xuICAgKiBAcGFyYW0gcXVlcnkge09iamVjdH0ga2V5LXZhbHVlIHBhaXJzIG9mIHBhcmFtZXRlcnMgdG8gYXBwZW5kIGFmdGVyIC9hcGlcbiAgICogQHJldHVybnMge09iamVjdH0gcmVzcG9uc2UgZnJvbSBUcm9uZ3JpZFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWNvdmVyeVBvc3QocXVlcnk6IHsgcGF0aDogc3RyaW5nOyBqc29uT2JqOiBhbnk7IG5vZGU6IE5vZGVUeXBlcyB9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBub2RlVXJpID0gdGhpcy5nZXROb2RlVXJsKHF1ZXJ5Lm5vZGUpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAucG9zdChub2RlVXJpICsgcXVlcnkucGF0aClcbiAgICAgIC50eXBlKCdqc29uJylcbiAgICAgIC5zZW5kKHF1ZXJ5Lmpzb25PYmopO1xuXG4gICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmVhY2ggVHJvbiBub2RlJyk7XG4gICAgfVxuXG4gICAgLy8gdW5mb3J0dW5hdGVseSwgaXQgZG9lc24ndCBsb29rIGxpa2UgbW9zdCBUUk9OIG5vZGVzIHJldHVybiB2YWxpZCBqc29uIGFzIGJvZHlcbiAgICByZXR1cm4gSlNPTi5wYXJzZShyZXNwb25zZS50ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlIGEgcXVlcnkgdG8gVHJvbmdyaWQgZm9yIGluZm9ybWF0aW9uIHN1Y2ggYXMgYmFsYW5jZSwgdG9rZW4gYmFsYW5jZSwgc29saWRpdHkgY2FsbHNcbiAgICogQHBhcmFtIHF1ZXJ5IHtPYmplY3R9IGtleS12YWx1ZSBwYWlycyBvZiBwYXJhbWV0ZXJzIHRvIGFwcGVuZCBhZnRlciAvYXBpXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IHJlc3BvbnNlIGZyb20gVHJvbmdyaWRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVjb3ZlcnlHZXQocXVlcnk6IHsgcGF0aDogc3RyaW5nOyBqc29uT2JqOiBhbnk7IG5vZGU6IE5vZGVUeXBlcyB9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBub2RlVXJpID0gdGhpcy5nZXROb2RlVXJsKHF1ZXJ5Lm5vZGUpO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0XG4gICAgICAuZ2V0KG5vZGVVcmkgKyBxdWVyeS5wYXRoKVxuICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgLnNlbmQocXVlcnkuanNvbk9iaik7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFjaCBUcm9uIG5vZGUnKTtcbiAgICB9XG5cbiAgICAvLyB1bmZvcnR1bmF0ZWx5LCBpdCBkb2Vzbid0IGxvb2sgbGlrZSBtb3N0IFRST04gbm9kZXMgcmV0dXJuIHZhbGlkIGpzb24gYXMgYm9keVxuICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlLnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFF1ZXJ5IG91ciBleHBsb3JlciBmb3IgdGhlIGJhbGFuY2Ugb2YgYW4gYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzcyB7U3RyaW5nfSB0aGUgYWRkcmVzcyBlbmNvZGVkIGluIGhleFxuICAgKiBAcmV0dXJucyB7QmlnTnVtYmVyfSBhZGRyZXNzIGJhbGFuY2VcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUoYWRkcmVzczogc3RyaW5nKTogUHJvbWlzZTxBY2NvdW50UmVzcG9uc2U+IHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeUdldCh7XG4gICAgICBwYXRoOiAnL3YxL2FjY291bnRzLycgKyBhZGRyZXNzLFxuICAgICAganNvbk9iajoge30sXG4gICAgICBub2RlOiBOb2RlVHlwZXMuRnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgb3VyIGJ1aWxkIHRyYW5zYWN0aW9uIGZyb20gYSBub2RlLlxuICAgKiBAcGFyYW0gdG9BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGZyb21BZGRyIGhleC1lbmNvZGVkIGFkZHJlc3NcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRCdWlsZFRyYW5zYWN0aW9uKFxuICAgIHRvQWRkcjogc3RyaW5nLFxuICAgIGZyb21BZGRyOiBzdHJpbmcsXG4gICAgYW1vdW50OiBudW1iZXJcbiAgKTogUHJvbWlzZTxJbnRlcmZhY2UuVHJhbnNhY3Rpb25SZWNlaXB0PiB7XG4gICAgLy8gb3VyIGFkZHJlc3NlcyBzaG91bGQgYmUgYmFzZTU4LCB3ZSdsbCBoYXZlIHRvIGVuY29kZSB0byBoZXhcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvY3JlYXRldHJhbnNhY3Rpb24nLFxuICAgICAganNvbk9iajoge1xuICAgICAgICB0b19hZGRyZXNzOiB0b0FkZHIsXG4gICAgICAgIG93bmVyX2FkZHJlc3M6IGZyb21BZGRyLFxuICAgICAgICBhbW91bnQsXG4gICAgICB9LFxuICAgICAgbm9kZTogTm9kZVR5cGVzLkZ1bGwsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIG91ciBidWlsZCB0cmFuc2FjdGlvbiBmcm9tIGEgbm9kZS5cbiAgICogQHBhcmFtIHRvQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBmcm9tQWRkciBoZXgtZW5jb2RlZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhbW91bnRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0VHJpZ2dlclNtYXJ0Q29udHJhY3RUcmFuc2FjdGlvbihcbiAgICB0b0FkZHI6IHN0cmluZyxcbiAgICBmcm9tQWRkcjogc3RyaW5nLFxuICAgIGFtb3VudDogc3RyaW5nLFxuICAgIGNvbnRyYWN0QWRkcjogc3RyaW5nXG4gICk6IFByb21pc2U8eyB0cmFuc2FjdGlvbjogSW50ZXJmYWNlLlRyYW5zYWN0aW9uUmVjZWlwdCB9PiB7XG4gICAgY29uc3QgZnVuY3Rpb25TZWxlY3RvciA9ICd0cmFuc2ZlcihhZGRyZXNzLHVpbnQyNTYpJztcbiAgICBjb25zdCB0eXBlcyA9IFsnYWRkcmVzcycsICd1aW50MjU2J107XG4gICAgY29uc3QgdmFsdWVzID0gW3RvQWRkciwgYW1vdW50XTtcbiAgICBjb25zdCBwYXJhbWV0ZXIgPSBVdGlscy5lbmNvZGVEYXRhUGFyYW1zKHR5cGVzLCB2YWx1ZXMsICcnKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yZWNvdmVyeVBvc3Qoe1xuICAgICAgcGF0aDogJy93YWxsZXQvdHJpZ2dlcnNtYXJ0Y29udHJhY3QnLFxuICAgICAganNvbk9iajoge1xuICAgICAgICBvd25lcl9hZGRyZXNzOiBmcm9tQWRkcixcbiAgICAgICAgY29udHJhY3RfYWRkcmVzczogY29udHJhY3RBZGRyLFxuICAgICAgICBmdW5jdGlvbl9zZWxlY3RvcjogZnVuY3Rpb25TZWxlY3RvcixcbiAgICAgICAgcGFyYW1ldGVyOiBwYXJhbWV0ZXIsXG4gICAgICAgIGZlZV9saW1pdDogMTAwMDAwMDAwLFxuICAgICAgfSxcbiAgICAgIG5vZGU6IE5vZGVUeXBlcy5GdWxsLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiBhbnkga2V5cyBpbiB0aGUgb3duZXJLZXlzIGNvbGxlY3Rpb24gZG9uJ3QgbWF0Y2ggdGhlIGtleXMgYXJyYXkgd2UgcGFzc1xuICAgKiBAcGFyYW0gb3duZXJLZXlzXG4gICAqIEBwYXJhbSBrZXlzXG4gICAqL1xuICBjaGVja1Blcm1pc3Npb25zKG93bmVyS2V5czogeyBhZGRyZXNzOiBzdHJpbmc7IHdlaWdodDogbnVtYmVyIH1bXSwga2V5czogc3RyaW5nW10pIHtcbiAgICBrZXlzID0ga2V5cy5tYXAoKGspID0+IGsudG9VcHBlckNhc2UoKSk7XG5cbiAgICBvd25lcktleXMubWFwKChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGhleEtleSA9IGtleS5hZGRyZXNzLnRvVXBwZXJDYXNlKCk7XG4gICAgICBpZiAoIWtleXMuaW5jbHVkZXMoaGV4S2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHB1YiBhZGRyZXNzICR7aGV4S2V5fSBub3QgZm91bmQgaW4gYWNjb3VudGApO1xuICAgICAgfVxuXG4gICAgICBpZiAoa2V5LndlaWdodCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ293bmVyIHBlcm1pc3Npb24gaXMgaW52YWxpZCBmb3IgdGhpcyBzdHJ1Y3R1cmUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JtYXQgZm9yIG9mZmxpbmUgdmF1bHQgc2lnbmluZ1xuICAgKiBAcGFyYW0ge0Jhc2VUcmFuc2FjdGlvbn0gdHhcbiAgICogQHBhcmFtIHtudW1iZXJ9IGZlZVxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVjb3ZlcnlBbW91bnRcbiAgICogQHJldHVybnMge1JlY292ZXJ5VHJhbnNhY3Rpb259XG4gICAqL1xuICBmb3JtYXRGb3JPZmZsaW5lVmF1bHQoXG4gICAgdHg6IEJhc2VUcmFuc2FjdGlvbixcbiAgICBmZWU6IG51bWJlcixcbiAgICByZWNvdmVyeUFtb3VudDogbnVtYmVyLFxuICAgIGFkZHJlc3NJbmZvPzogQWRkcmVzc0luZm9cbiAgKTogUmVjb3ZlcnlUcmFuc2FjdGlvbiB7XG4gICAgY29uc3QgdHhKU09OID0gdHgudG9Kc29uKCk7XG4gICAgY29uc3QgZm9ybWF0ID0ge1xuICAgICAgdHhIZXg6IEpTT04uc3RyaW5naWZ5KHR4SlNPTiksXG4gICAgICByZWNvdmVyeUFtb3VudCxcbiAgICAgIGZlZUluZm86IHtcbiAgICAgICAgZmVlOiBgJHtmZWV9YCxcbiAgICAgIH0sXG4gICAgICB0eDogdHhKU09OLCAvLyBMZWF2aW5nIGl0IGFzIHR4SlNPTiBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICAgIGNvaW46IHRoaXMuZ2V0Q2hhaW4oKSxcbiAgICB9O1xuICAgIHJldHVybiBhZGRyZXNzSW5mbyA/IHsgLi4uZm9ybWF0LCBhZGRyZXNzSW5mbyB9IDogZm9ybWF0O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIGZ1bmRzIHJlY292ZXJ5IHRyYW5zYWN0aW9uIHdpdGhvdXQgQml0R28uXG4gICAqIFdlIG5lZWQgdG8gZG8gdGhyZWUgcXVlcmllcyBkdXJpbmcgdGhpczpcbiAgICogMSkgTm9kZSBxdWVyeSAtIGhvdyBtdWNoIG1vbmV5IGlzIGluIHRoZSBhY2NvdW50XG4gICAqIDIpIEJ1aWxkIHRyYW5zYWN0aW9uIC0gYnVpbGQgb3VyIHRyYW5zYWN0aW9uIGZvciB0aGUgYW1vdW50XG4gICAqIDMpIFNlbmQgc2lnbmVkIGJ1aWxkIC0gc2VuZCBvdXIgc2lnbmVkIGJ1aWxkIHRvIGEgcHVibGljIG5vZGVcbiAgICpcbiAgICogTm90ZSAxOiBmb3IgYmFzZSBhZGRyZXNzIHJlY292ZXJpZXMsIGZ1bmQgd2lsbCBiZSByZWNvdmVyZWQgdG8gcmVjb3ZlcnkgZGVzdGluYXRpb24gaWYgYmFzZSBhZGRyZXNzIGJhbGFuY2UgaXNcbiAgICogbW9yZSB0aGFuIDIuMSBUUlggZm9yIG5hdGl2ZSBUUlggcmVjb3ZlcnkgYW5kIDEwMCBUUlggZm9yIHRva2VuIHJlY292ZXIuIEZvciByZWNlaXZlIGFkZHJlc3NlcywgZnVuZCB3aWxsIGJlXG4gICAqIHJlY292ZXJlZCB0byBiYXNlIGFkZHJlc3MgZmlyc3QgdGhlbiBzd2VwdCB0byBiYXNlIGFkZHJlc3MoZGVjaWRlZCBhcyB0aGUgdW5pdmVyc2FsIHBhdHRlcm4gaW4gdGVhbSBtZWV0aW5nKS5cbiAgICpcbiAgICogTm90ZSAyOiB0aGUgZnVuY3Rpb24gc3VwcG9ydHMgdG9rZW4gc3dlZXAgZnJvbSBiYXNlIGFkZHJlc3MuXG4gICAqIFRPRE86IHN1cHBvcnQgdG9rZW4gc3dlZXAgZnJvbSByZWNlaXZlIGFkZHJlc3MuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIHJlY292ZXIocGFyYW1zOiBSZWNvdmVyeU9wdGlvbnMpOiBQcm9taXNlPFJlY292ZXJ5VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpc0tyc1JlY292ZXJ5ID0gZ2V0SXNLcnNSZWNvdmVyeShwYXJhbXMpO1xuICAgIGNvbnN0IGlzVW5zaWduZWRTd2VlcCA9IGdldElzVW5zaWduZWRTd2VlcChwYXJhbXMpO1xuXG4gICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzKHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRlc3RpbmF0aW9uIGFkZHJlc3MhJyk7XG4gICAgfVxuXG4gICAgbGV0IHN0YXJ0SWR4ID0gcGFyYW1zLnN0YXJ0aW5nU2NhbkluZGV4O1xuICAgIGlmIChpc1VuZGVmaW5lZChzdGFydElkeCkpIHtcbiAgICAgIHN0YXJ0SWR4ID0gMTtcbiAgICB9IGVsc2UgaWYgKCFpc0ludGVnZXIoc3RhcnRJZHgpIHx8IHN0YXJ0SWR4IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0YXJ0aW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3NlcycpO1xuICAgIH1cblxuICAgIGxldCBudW1JdGVyYXRpb24gPSBwYXJhbXMuc2NhbjtcbiAgICBpZiAoaXNVbmRlZmluZWQobnVtSXRlcmF0aW9uKSkge1xuICAgICAgbnVtSXRlcmF0aW9uID0gMjA7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbnVtSXRlcmF0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgbnVtSXRlcmF0aW9uID0gcGFyc2VJbnQobnVtSXRlcmF0aW9uLCAxMCk7XG4gICAgfVxuXG4gICAgaWYgKCFpc0ludGVnZXIobnVtSXRlcmF0aW9uKSB8fCBudW1JdGVyYXRpb24gPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNjYW5uaW5nIGZhY3RvcicpO1xuICAgIH1cblxuICAgIC8vIGdldCBvdXIgdXNlciwgYmFja3VwIGtleXNcbiAgICBjb25zdCBrZXlzID0gYXdhaXQgZ2V0QmlwMzJLZXlzQXN5bmModGhpcy5iaXRnbywgcGFyYW1zLCB7IHJlcXVpcmVCaXRHb1hwdWI6IGZhbHNlIH0pO1xuXG4gICAgLy8gd2UgbmVlZCB0byBkZWNvZGUgb3VyIGJpdGdvS2V5IHRvIGEgYmFzZTU4IGFkZHJlc3NcbiAgICBjb25zdCBiaXRnb0hleEFkZHIgPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1YihwYXJhbXMuYml0Z29LZXkpKTtcbiAgICBsZXQgcmVjb3ZlcnlGcm9tQWRkckhleCA9IGJpdGdvSGV4QWRkcjtcbiAgICBsZXQgcmVjb3ZlcnlUb0FkZHJlc3NIZXggPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuXG4gICAgLy8gY2FsbCB0aGUgbm9kZSB0byBnZXQgb3VyIGFjY291bnQgYmFsYW5jZSBmb3IgYmFzZSBhZGRyZXNzXG4gICAgbGV0IGFjY291bnQgPSBhd2FpdCB0aGlzLmdldEFjY291bnRCYWxhbmNlc0Zyb21Ob2RlKFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHJlY292ZXJ5RnJvbUFkZHJIZXgpKTtcbiAgICBsZXQgcmVjb3ZlcnlBbW91bnQgPSBhY2NvdW50LmRhdGFbMF0uYmFsYW5jZTtcblxuICAgIGxldCB1c2VyWFBydiA9IGtleXNbMF0udG9CYXNlNTgoKTtcbiAgICBsZXQgaXNSZWNlaXZlQWRkcmVzcyA9IGZhbHNlO1xuICAgIGxldCBhZGRyZXNzSW5mbzogQWRkcmVzc0luZm8gfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHIgPSBwYXJhbXMudG9rZW5Db250cmFjdEFkZHJlc3M7XG4gICAgLy8gY2hlY2sgZm9yIHBvc3NpYmxlIHRva2VuIHJlY292ZXJ5LCByZWNvdmVyIHRoZSB0b2tlbiBwcm92aWRlIGJ5IHVzZXJcbiAgICBpZiAodG9rZW5Db250cmFjdEFkZHIpIHtcbiAgICAgIGxldCByYXdUb2tlblR4bjogYW55IHwgdW5kZWZpbmVkO1xuICAgICAgZm9yIChjb25zdCB0b2tlbiBvZiBhY2NvdW50LmRhdGFbMF0udHJjMjApIHtcbiAgICAgICAgaWYgKHRva2VuW3Rva2VuQ29udHJhY3RBZGRyXSkge1xuICAgICAgICAgIGNvbnN0IGFtb3VudCA9IHRva2VuW3Rva2VuQ29udHJhY3RBZGRyXTtcbiAgICAgICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkckhleCA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcyh0b2tlbkNvbnRyYWN0QWRkcik7XG4gICAgICAgICAgcmF3VG9rZW5UeG4gPSAoXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmdldFRyaWdnZXJTbWFydENvbnRyYWN0VHJhbnNhY3Rpb24oXG4gICAgICAgICAgICAgIHJlY292ZXJ5VG9BZGRyZXNzSGV4LFxuICAgICAgICAgICAgICByZWNvdmVyeUZyb21BZGRySGV4LFxuICAgICAgICAgICAgICBhbW91bnQsXG4gICAgICAgICAgICAgIHRva2VuQ29udHJhY3RBZGRySGV4XG4gICAgICAgICAgICApXG4gICAgICAgICAgKS50cmFuc2FjdGlvbjtcbiAgICAgICAgICByZWNvdmVyeUFtb3VudCA9IHBhcnNlSW50KGFtb3VudCwgMTApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGJ1aWxkIGFuZCBzaWduIHRva2VuIHR4bnNcbiAgICAgIGlmIChyYXdUb2tlblR4bikge1xuICAgICAgICAvLyBDaGVjayB0aGVyZSBpcyBzdWZmaWNpZW50IG9mIHRoZSBuYXRpdmUgYXNzZXQgdG8gY292ZXIgZmVlc1xuICAgICAgICBjb25zdCB0cnhCYWxhbmNlID0gYWNjb3VudC5kYXRhWzBdLmJhbGFuY2U7XG4gICAgICAgIGlmICh0cnhCYWxhbmNlIDwgU0FGRV9UUk9OX1RPS0VOX1RSQU5TQUNUSU9OX0ZFRSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBBbW91bnQgb2YgZnVuZHMgdG8gcmVjb3ZlciAke3RyeEJhbGFuY2V9IGlzIGxlc3MgdGhhbiAke1NBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUV9IGFuZCB3b3VsZG4ndCBiZSBhYmxlIHRvIGZ1bmQgYSB0cmMyMCBzZW5kYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbShyYXdUb2tlblR4bik7XG4gICAgICAgIC8vIERlZmF1bHQgZXhwaXJ5IGlzIDEgbWludXRlIHdoaWNoIGlzIHRvbyBzaG9ydCBmb3IgcmVjb3ZlcnkgcHVycG9zZXNcbiAgICAgICAgLy8gZXh0ZW5kIHRoZSBleHBpcnkgdG8gMSBkYXlcbiAgICAgICAgdHhCdWlsZGVyLmV4dGVuZFZhbGlkVG8oUkVDT1ZFUl9UUkFOU0FDVElPTl9FWFBJUlkpO1xuICAgICAgICAvLyB0aGlzIHR4IHNob3VsZCBiZSBlbm91Z2ggdG8gZHJvcCBpbnRvIGEgbm9kZVxuICAgICAgICBpZiAoaXNVbnNpZ25lZFN3ZWVwKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0Rm9yT2ZmbGluZVZhdWx0KGF3YWl0IHR4QnVpbGRlci5idWlsZCgpLCBTQUZFX1RST05fVE9LRU5fVFJBTlNBQ1RJT05fRkVFLCByZWNvdmVyeUFtb3VudCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJYUHJ2KTtcblxuICAgICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcblxuICAgICAgICAvLyBrcnMgcmVjb3ZlcmllcyBkb24ndCBnZXQgc2lnbmVkXG4gICAgICAgIGlmICghaXNLcnNSZWNvdmVyeSAmJiAhaXNSZWNlaXZlQWRkcmVzcykge1xuICAgICAgICAgIGNvbnN0IGJhY2t1cFhQcnYgPSBrZXlzWzFdLnRvQmFzZTU4KCk7XG4gICAgICAgICAgY29uc3QgYmFja3VwUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KGJhY2t1cFhQcnYpO1xuXG4gICAgICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IGJhY2t1cFBydiB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRGb3JPZmZsaW5lVmF1bHQoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCksIFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUsIHJlY292ZXJ5QW1vdW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IEVycm9yKCdOb3QgZm91bmQgdG9rZW4gdG8gcmVjb3ZlciwgcGxlYXNlIGNoZWNrIHRva2VuIGJhbGFuY2UnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gbGV0IHVzIHJlY292ZXIgdGhlIG5hdGl2ZSBUcm9uXG4gICAgaWYgKHJlY292ZXJ5QW1vdW50ID4gU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSkge1xuICAgICAgY29uc3QgdXNlclhQdWIgPSBrZXlzWzBdLm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcbiAgICAgIGNvbnN0IGJhY2t1cFhQdWIgPSBrZXlzWzFdLm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcblxuICAgICAgLy8gY2hlY2sgbXVsdGlzaWcgcGVybWlzc2lvbnNcbiAgICAgIGNvbnN0IGtleUhleEFkZHJlc3NlcyA9IFtcbiAgICAgICAgdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIodXNlclhQdWIpKSxcbiAgICAgICAgdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIoYmFja3VwWFB1YikpLFxuICAgICAgICBiaXRnb0hleEFkZHIsXG4gICAgICBdO1xuICAgICAgLy8gcnVuIGNoZWNrcyB0byBlbnN1cmUgdGhpcyBpcyBhIHZhbGlkIHR4IC0gcGVybWlzc2lvbnMgbWF0Y2ggb3VyIHNpZ25lciBrZXlzXG4gICAgICBjb25zdCBvd25lcktleXM6IHsgYWRkcmVzczogc3RyaW5nOyB3ZWlnaHQ6IG51bWJlciB9W10gPSBbXTtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFjY291bnQuZGF0YVswXS5vd25lcl9wZXJtaXNzaW9uLmtleXMpIHtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcyhrZXkuYWRkcmVzcyk7XG4gICAgICAgIGNvbnN0IHdlaWdodCA9IGtleS53ZWlnaHQ7XG4gICAgICAgIG93bmVyS2V5cy5wdXNoKHsgYWRkcmVzcywgd2VpZ2h0IH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgYWN0aXZlUGVybWlzc2lvbktleXM6IHsgYWRkcmVzczogc3RyaW5nOyB3ZWlnaHQ6IG51bWJlciB9W10gPSBbXTtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFjY291bnQuZGF0YVswXS5hY3RpdmVfcGVybWlzc2lvblswXS5rZXlzKSB7XG4gICAgICAgIGNvbnN0IGFkZHJlc3MgPSBVdGlscy5nZXRIZXhBZGRyZXNzRnJvbUJhc2U1OEFkZHJlc3Moa2V5LmFkZHJlc3MpO1xuICAgICAgICBjb25zdCB3ZWlnaHQgPSBrZXkud2VpZ2h0O1xuICAgICAgICBhY3RpdmVQZXJtaXNzaW9uS2V5cy5wdXNoKHsgYWRkcmVzcywgd2VpZ2h0IH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5jaGVja1Blcm1pc3Npb25zKG93bmVyS2V5cywga2V5SGV4QWRkcmVzc2VzKTtcbiAgICAgIHRoaXMuY2hlY2tQZXJtaXNzaW9ucyhhY3RpdmVQZXJtaXNzaW9uS2V5cywga2V5SGV4QWRkcmVzc2VzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ2hlY2sgcmVjZWl2ZSBhZGRyZXNzZXMgZm9yIGZ1bmRzXG4gICAgICAvLyBDaGVjayBmb3IgZmlyc3QgZGVyaXZlZCB3YWxsZXQgd2l0aCBmdW5kc1xuICAgICAgLy8gUmVjZWl2ZSBhZGRyZXNzZXMgYXJlIGRlcml2ZWQgZnJvbSB0aGUgdXNlciBrZXlcbiAgICAgIGZvciAobGV0IGkgPSBzdGFydElkeDsgaSA8IG51bUl0ZXJhdGlvbiArIHN0YXJ0SWR4OyBpKyspIHtcbiAgICAgICAgY29uc3QgZGVyaXZhdGlvblBhdGggPSBgMC8wLzAvJHtpfWA7XG4gICAgICAgIGNvbnN0IHVzZXJLZXkgPSBrZXlzWzBdLmRlcml2ZVBhdGgoZGVyaXZhdGlvblBhdGgpO1xuICAgICAgICBjb25zdCB4cHViID0gdXNlcktleS5uZXV0ZXJlZCgpO1xuICAgICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9IHRoaXMucHViVG9IZXhBZGRyZXNzKHRoaXMueHB1YlRvVW5jb21wcmVzc2VkUHViKHhwdWIudG9CYXNlNTgoKSkpO1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gVXRpbHMuZ2V0QmFzZTU4QWRkcmVzc0Zyb21IZXgocmVjZWl2ZUFkZHJlc3MpO1xuICAgICAgICAvLyBjYWxsIHRoZSBub2RlIHRvIGdldCBvdXIgYWNjb3VudCBiYWxhbmNlXG4gICAgICAgIGNvbnN0IGFjY291bnRJbmZvID0gYXdhaXQgdGhpcy5nZXRBY2NvdW50QmFsYW5jZXNGcm9tTm9kZShhZGRyZXNzKTtcblxuICAgICAgICBpZiAoYWNjb3VudEluZm8uZGF0YVswXSAmJiBhY2NvdW50SW5mby5kYXRhWzBdLmJhbGFuY2UgPiBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFKSB7XG4gICAgICAgICAgYWNjb3VudCA9IGFjY291bnRJbmZvO1xuICAgICAgICAgIHJlY292ZXJ5QW1vdW50ID0gYWNjb3VudEluZm8uZGF0YVswXS5iYWxhbmNlO1xuICAgICAgICAgIHVzZXJYUHJ2ID0gdXNlcktleS50b0Jhc2U1OCgpOyAvLyBhc3NpZ24gZGVyaXZlZCB1c2VyWFByeFxuICAgICAgICAgIGlzUmVjZWl2ZUFkZHJlc3MgPSB0cnVlO1xuICAgICAgICAgIHJlY292ZXJ5RnJvbUFkZHJIZXggPSByZWNlaXZlQWRkcmVzcztcbiAgICAgICAgICByZWNvdmVyeVRvQWRkcmVzc0hleCA9IGJpdGdvSGV4QWRkcjtcbiAgICAgICAgICBhZGRyZXNzSW5mbyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3MsXG4gICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgIH07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhIHN3ZWVwIHBvdGVudGlhbGx5IG5lZWRzIHRvIHBheSBmb3IgbXVsdGktc2lnIHRyYW5zZmVyLCBkZXN0aW5hdGlvbiBhY2NvdW50IGFjdGl2YXRpb24gYW5kIGJhbmR3aWR0aFxuICAgIC8vIFRST04gZm91bmRhdGlvbiByZWNvbW1lbmRzIDIuMSBUUlggZm9yIGd1YXJhbnRlZWQgY29uZmlybWF0aW9uXG4gICAgaWYgKCFyZWNvdmVyeUFtb3VudCB8fCBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFID49IHJlY292ZXJ5QW1vdW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBBbW91bnQgb2YgZnVuZHMgdG8gcmVjb3ZlciAke3JlY292ZXJ5QW1vdW50fSBpcyBsZXNzIHRoYW4gJHtTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFfSBhbmQgd291bGRuJ3QgYmUgYWJsZSB0byBmdW5kIGEgc2VuZGBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVjb3ZlcnlBbW91bnRNaW51c0ZlZXMgPSByZWNvdmVyeUFtb3VudCAtIFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUU7XG4gICAgY29uc3QgYnVpbGRUeCA9IGF3YWl0IHRoaXMuZ2V0QnVpbGRUcmFuc2FjdGlvbihyZWNvdmVyeVRvQWRkcmVzc0hleCwgcmVjb3ZlcnlGcm9tQWRkckhleCwgcmVjb3ZlcnlBbW91bnRNaW51c0ZlZXMpO1xuXG4gICAgLy8gY29uc3RydWN0IG91ciB0eFxuICAgIGNvbnN0IHR4QnVpbGRlciA9IChnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkgYXMgV3JhcHBlZEJ1aWxkZXIpLmZyb20oYnVpbGRUeCk7XG4gICAgLy8gRGVmYXVsdCBleHBpcnkgaXMgMSBtaW51dGUgd2hpY2ggaXMgdG9vIHNob3J0IGZvciByZWNvdmVyeSBwdXJwb3Nlc1xuICAgIC8vIGV4dGVuZCB0aGUgZXhwaXJ5IHRvIDEgZGF5XG4gICAgdHhCdWlsZGVyLmV4dGVuZFZhbGlkVG8oUkVDT1ZFUl9UUkFOU0FDVElPTl9FWFBJUlkpO1xuICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAvLyB0aGlzIHR4IHNob3VsZCBiZSBlbm91Z2ggdG8gZHJvcCBpbnRvIGEgbm9kZVxuICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdEZvck9mZmxpbmVWYXVsdCh0eCwgU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSwgcmVjb3ZlcnlBbW91bnRNaW51c0ZlZXMsIGFkZHJlc3NJbmZvKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJYUHJ2KTtcblxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuXG4gICAgLy8ga3JzIHJlY292ZXJpZXMgZG9uJ3QgZ2V0IHNpZ25lZFxuICAgIGlmICghaXNLcnNSZWNvdmVyeSAmJiAhaXNSZWNlaXZlQWRkcmVzcykge1xuICAgICAgY29uc3QgYmFja3VwWFBydiA9IGtleXNbMV0udG9CYXNlNTgoKTtcbiAgICAgIGNvbnN0IGJhY2t1cFBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydihiYWNrdXBYUHJ2KTtcblxuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IGJhY2t1cFBydiB9KTtcbiAgICB9XG4gICAgY29uc3QgdHhTaWduZWQgPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICByZXR1cm4gdGhpcy5mb3JtYXRGb3JPZmZsaW5lVmF1bHQodHhTaWduZWQsIFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUUsIHJlY292ZXJ5QW1vdW50TWludXNGZWVzLCBhZGRyZXNzSW5mbyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIG5hdGl2ZSBUUlggcmVjb3ZlcmllcyBvZiByZWNlaXZlIGFkZHJlc3NlcyBpbiBiYXRjaCB3aXRob3V0IEJpdEdvLlxuICAgKiBGdW5kcyB3aWxsIGJlIHJlY292ZXJlZCB0byBiYXNlIGFkZHJlc3MgZmlyc3QuIFlvdSBuZWVkIHRvIGluaXRpYXRlIGFub3RoZXIgc3dlZXAgdHhuIGFmdGVyIHRoYXQuXG4gICAqIE5vdGU6IHRoZXJlIHdpbGwgYmUgYW5vdGhlciByZWNvdmVyVG9rZW5Db25zb2xpZGF0aW9ucyBmdW5jdGlvbiB0byBzdXBwb3J0IHRva2VuIHJlY292ZXIgZnJvbSByZWNlaXZlIGFkZHJlc3Nlcy5cbiAgICpcbiAgICogQHBhcmFtIHtDb25zb2xpZGF0aW9uUmVjb3ZlcnlPcHRpb25zfSBwYXJhbXMgLSBvcHRpb25zIGZvciBjb25zb2xpZGF0aW9uIHJlY292ZXJ5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5zdGFydGluZ1NjYW5JbmRleF0gLSByZWNlaXZlIGFkZHJlc3MgaW5kZXggdG8gc3RhcnQgc2Nhbm5pbmcgZnJvbS4gZGVmYXVsdCB0byAxIChpbmNsdXNpdmUpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5lbmRpbmdTY2FuSW5kZXhdIC0gcmVjZWl2ZSBhZGRyZXNzIGluZGV4IHRvIGVuZCBzY2FubmluZyBhdC4gZGVmYXVsdCB0byBzdGFydGluZ1NjYW5JbmRleCArIDIwIChleGNsdXNpdmUpLlxuICAgKi9cbiAgYXN5bmMgcmVjb3ZlckNvbnNvbGlkYXRpb25zKHBhcmFtczogQ29uc29saWRhdGlvblJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8Q29uc29saWRhdGlvblJlY292ZXJ5QmF0Y2g+IHtcbiAgICBjb25zdCBpc1Vuc2lnbmVkQ29uc29saWRhdGlvbnMgPSBnZXRJc1Vuc2lnbmVkU3dlZXAocGFyYW1zKTtcbiAgICBjb25zdCBzdGFydElkeCA9IHBhcmFtcy5zdGFydGluZ1NjYW5JbmRleCB8fCAxO1xuICAgIGNvbnN0IGVuZElkeCA9IHBhcmFtcy5lbmRpbmdTY2FuSW5kZXggfHwgc3RhcnRJZHggKyBERUZBVUxUX1NDQU5fRkFDVE9SO1xuXG4gICAgaWYgKHN0YXJ0SWR4IDwgMSB8fCBlbmRJZHggPD0gc3RhcnRJZHggfHwgZW5kSWR4IC0gc3RhcnRJZHggPiAxMCAqIERFRkFVTFRfU0NBTl9GQUNUT1IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEludmFsaWQgc3RhcnRpbmcgb3IgZW5kaW5nIGluZGV4IHRvIHNjYW4gZm9yIGFkZHJlc3Nlcy4gc3RhcnRpbmdTY2FuSW5kZXg6ICR7c3RhcnRJZHh9LCBlbmRpbmdTY2FuSW5kZXg6ICR7ZW5kSWR4fS5gXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBhd2FpdCBnZXRCaXAzMktleXNBc3luYyh0aGlzLmJpdGdvLCBwYXJhbXMsIHsgcmVxdWlyZUJpdEdvWHB1YjogZmFsc2UgfSk7XG4gICAgY29uc3QgYmFzZUFkZHJIZXggPSB0aGlzLnB1YlRvSGV4QWRkcmVzcyh0aGlzLnhwdWJUb1VuY29tcHJlc3NlZFB1YihwYXJhbXMuYml0Z29LZXkpKTtcblxuICAgIGNvbnN0IHR4bnNCYXRjaDogUmVjb3ZlcnlUcmFuc2FjdGlvbltdID0gW107XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0SWR4OyBpIDwgZW5kSWR4OyBpKyspIHtcbiAgICAgIGNvbnN0IGRlcml2YXRpb25QYXRoID0gYDAvMC8wLyR7aX1gO1xuICAgICAgY29uc3QgdXNlcktleSA9IGtleXNbMF0uZGVyaXZlUGF0aChkZXJpdmF0aW9uUGF0aCk7XG4gICAgICBjb25zdCB1c2VyS2V5WFB1YiA9IHVzZXJLZXkubmV1dGVyZWQoKTtcbiAgICAgIGNvbnN0IHJlY2VpdmVBZGRyZXNzSGV4ID0gdGhpcy5wdWJUb0hleEFkZHJlc3ModGhpcy54cHViVG9VbmNvbXByZXNzZWRQdWIodXNlcktleVhQdWIudG9CYXNlNTgoKSkpO1xuICAgICAgY29uc3QgcmVjZWl2ZUFkZHJlc3MgPSBVdGlscy5nZXRCYXNlNThBZGRyZXNzRnJvbUhleChyZWNlaXZlQWRkcmVzc0hleCk7XG4gICAgICAvLyBjYWxsIHRoZSBub2RlIHRvIGdldCBvdXIgYWNjb3VudCBiYWxhbmNlXG4gICAgICBjb25zdCBhY2NvdW50SW5mbyA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudEJhbGFuY2VzRnJvbU5vZGUocmVjZWl2ZUFkZHJlc3MpO1xuXG4gICAgICBpZiAoYWNjb3VudEluZm8uZGF0YVswXSAmJiBhY2NvdW50SW5mby5kYXRhWzBdLmJhbGFuY2UgPiBTQUZFX1RST05fVFJBTlNBQ1RJT05fRkVFKSB7XG4gICAgICAgIGxldCByZWNvdmVyeUFtb3VudCA9IDA7XG4gICAgICAgIC8vIFRva2VucyBtdXN0IGJlIGNvbnNvbGlkYXRlIGJlZm9yZSB0aGUgbmF0aXZlIGFzc2V0LiBGaXJzdCBjb25zdHJ1Y3QgdG9rZW4gdHhuc1xuICAgICAgICBsZXQgcmF3VG9rZW5UeG46IGFueSB8IHVuZGVmaW5lZDtcblxuICAgICAgICAvLyBjaGVjayBmb3IgcG9zc2libGUgdG9rZW4gcmVjb3ZlcnksIHJlY292ZXIgdGhlIHRva2VuIHByb3ZpZGUgYnkgdXNlclxuICAgICAgICBpZiAocGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzKSB7XG4gICAgICAgICAgaWYgKGFjY291bnRJbmZvLmRhdGFbMF0uYmFsYW5jZSA+IFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUgJiYgYWNjb3VudEluZm8uZGF0YVswXS50cmMyMFswXSkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW5EYXRhQXJyYXkgPSBhY2NvdW50SW5mby5kYXRhWzBdLnRyYzIwO1xuICAgICAgICAgICAgZm9yIChjb25zdCB0b2tlbkRhdGEgb2YgdG9rZW5EYXRhQXJyYXkpIHtcbiAgICAgICAgICAgICAgY29uc3QgY29udHJhY3RBZGRyZXNzID0gT2JqZWN0LmtleXModG9rZW5EYXRhKSBhcyBBcnJheTxzdHJpbmc+O1xuICAgICAgICAgICAgICBpZiAocGFyYW1zLnRva2VuQ29udHJhY3RBZGRyZXNzID09PSBjb250cmFjdEFkZHJlc3NbMF0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbW91bnQgPSB0b2tlbkRhdGFbY29udHJhY3RBZGRyZXNzWzBdXTtcbiAgICAgICAgICAgICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkckhleCA9IFV0aWxzLmdldEhleEFkZHJlc3NGcm9tQmFzZTU4QWRkcmVzcyhjb250cmFjdEFkZHJlc3NbMF0pO1xuICAgICAgICAgICAgICAgIHJhd1Rva2VuVHhuID0gKFxuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRUcmlnZ2VyU21hcnRDb250cmFjdFRyYW5zYWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICBiYXNlQWRkckhleCxcbiAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZUFkZHJlc3NIZXgsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudCxcbiAgICAgICAgICAgICAgICAgICAgdG9rZW5Db250cmFjdEFkZHJIZXhcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApLnRyYW5zYWN0aW9uO1xuICAgICAgICAgICAgICAgIHJlY292ZXJ5QW1vdW50ID0gcGFyc2VJbnQoYW1vdW50LCAxMCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gYnVpbGQgYW5kIHNpZ24gdG9rZW4gdHhuc1xuICAgICAgICAgIGlmIChyYXdUb2tlblR4bikge1xuICAgICAgICAgICAgY29uc3QgYWRkcmVzc0luZm8gPSB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6IHJlY2VpdmVBZGRyZXNzLFxuICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgaW5kZXg6IGksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcih0aGlzLmdldENoYWluKCkpLmZyb20ocmF3VG9rZW5UeG4pO1xuICAgICAgICAgICAgLy8gRGVmYXVsdCBleHBpcnkgaXMgMSBtaW51dGUgd2hpY2ggaXMgdG9vIHNob3J0IGZvciByZWNvdmVyeSBwdXJwb3Nlc1xuICAgICAgICAgICAgLy8gZXh0ZW5kIHRoZSBleHBpcnkgdG8gMSBkYXlcbiAgICAgICAgICAgIHR4QnVpbGRlci5leHRlbmRWYWxpZFRvKFJFQ09WRVJfVFJBTlNBQ1RJT05fRVhQSVJZKTtcbiAgICAgICAgICAgIC8vIHRoaXMgdHggc2hvdWxkIGJlIGVub3VnaCB0byBkcm9wIGludG8gYSBub2RlXG4gICAgICAgICAgICBpZiAoIWlzVW5zaWduZWRDb25zb2xpZGF0aW9ucykge1xuICAgICAgICAgICAgICBjb25zdCB1c2VyUHJ2ID0gdGhpcy54cHJ2VG9Db21wcmVzc2VkUHJ2KHVzZXJLZXkudG9CYXNlNTgoKSk7XG4gICAgICAgICAgICAgIC8vIHJlY2VpdmUgYWRkcmVzcyBvbmx5IG5lZWRzIHRvIGJlIHNpZ25lZCBieSB1c2VyIGtleVxuICAgICAgICAgICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgICAgICB0eG5zQmF0Y2gucHVzaChcbiAgICAgICAgICAgICAgdGhpcy5mb3JtYXRGb3JPZmZsaW5lVmF1bHQodHgsIFNBRkVfVFJPTl9UT0tFTl9UUkFOU0FDVElPTl9GRUUsIHJlY292ZXJ5QW1vdW50LCBhZGRyZXNzSW5mbylcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGFkZHJlc3NCYWxhbmNlID0gYWNjb3VudEluZm8uZGF0YVswXS5iYWxhbmNlO1xuICAgICAgICAgIGNvbnN0IGFkZHJlc3NJbmZvID0ge1xuICAgICAgICAgICAgYWRkcmVzczogcmVjZWl2ZUFkZHJlc3MsXG4gICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSBhZGRyZXNzQmFsYW5jZSAtIFNBRkVfVFJPTl9UUkFOU0FDVElPTl9GRUU7XG4gICAgICAgICAgY29uc3QgYnVpbGRUeCA9IGF3YWl0IHRoaXMuZ2V0QnVpbGRUcmFuc2FjdGlvbihiYXNlQWRkckhleCwgcmVjZWl2ZUFkZHJlc3NIZXgsIHJlY292ZXJ5QW1vdW50KTtcbiAgICAgICAgICAvLyBjb25zdHJ1Y3Qgb3VyIHR4XG4gICAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gKGdldEJ1aWxkZXIodGhpcy5nZXRDaGFpbigpKSBhcyBXcmFwcGVkQnVpbGRlcikuZnJvbShidWlsZFR4KTtcbiAgICAgICAgICAvLyBEZWZhdWx0IGV4cGlyeSBpcyAxIG1pbnV0ZSB3aGljaCBpcyB0b28gc2hvcnQgZm9yIHJlY292ZXJ5IHB1cnBvc2VzXG4gICAgICAgICAgLy8gZXh0ZW5kIHRoZSBleHBpcnkgdG8gMSBkYXlcbiAgICAgICAgICB0eEJ1aWxkZXIuZXh0ZW5kVmFsaWRUbyhSRUNPVkVSX1RSQU5TQUNUSU9OX0VYUElSWSk7XG5cbiAgICAgICAgICBpZiAoIWlzVW5zaWduZWRDb25zb2xpZGF0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgdXNlclBydiA9IHRoaXMueHBydlRvQ29tcHJlc3NlZFBydih1c2VyS2V5LnRvQmFzZTU4KCkpO1xuICAgICAgICAgICAgLy8gcmVjZWl2ZSBhZGRyZXNzIG9ubHkgbmVlZHMgdG8gYmUgc2lnbmVkIGJ5IHVzZXIga2V5XG4gICAgICAgICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdXNlclBydiB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgICB0eG5zQmF0Y2gucHVzaCh0aGlzLmZvcm1hdEZvck9mZmxpbmVWYXVsdCh0eCwgU0FGRV9UUk9OX1RSQU5TQUNUSU9OX0ZFRSwgcmVjb3ZlcnlBbW91bnQsIGFkZHJlc3NJbmZvKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNhY3Rpb25zOiB0eG5zQmF0Y2gsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsYWluIGEgVHJvbiB0cmFuc2FjdGlvbiBmcm9tIHR4SGV4XG4gICAqIEBwYXJhbSBwYXJhbXNcbiAgICovXG4gIGFzeW5jIGV4cGxhaW5UcmFuc2FjdGlvbihwYXJhbXM6IEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFRyb25UcmFuc2FjdGlvbkV4cGxhbmF0aW9uPiB7XG4gICAgY29uc3QgdHhIZXggPSBwYXJhbXMudHhIZXggfHwgKHBhcmFtcy5oYWxmU2lnbmVkICYmIHBhcmFtcy5oYWxmU2lnbmVkLnR4SGV4KTtcbiAgICBpZiAoIXR4SGV4IHx8ICFwYXJhbXMuZmVlSW5mbykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH1cbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKHRoaXMuZ2V0Q2hhaW4oKSkuZnJvbSh0eEhleCk7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCBvdXRwdXRzID0gW1xuICAgICAge1xuICAgICAgICBhbW91bnQ6IHR4Lm91dHB1dHNbMF0udmFsdWUudG9TdHJpbmcoKSxcbiAgICAgICAgYWRkcmVzczogdHgub3V0cHV0c1swXS5hZGRyZXNzLCAvLyBTaG91bGQgdHVybiBpdCBpbnRvIGEgcmVhZGFibGUgZm9ybWF0LCBha2EgYmFzZTU4XG4gICAgICB9LFxuICAgIF07XG5cbiAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAnaWQnLFxuICAgICAgJ291dHB1dEFtb3VudCcsXG4gICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICdvdXRwdXRzJyxcbiAgICAgICdjaGFuZ2VPdXRwdXRzJyxcbiAgICAgICdmZWUnLFxuICAgICAgJ3RpbWVzdGFtcCcsXG4gICAgICAnZXhwaXJhdGlvbicsXG4gICAgXTtcblxuICAgIHJldHVybiB7XG4gICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICBpZDogdHguaWQsXG4gICAgICBvdXRwdXRzLFxuICAgICAgb3V0cHV0QW1vdW50OiBvdXRwdXRzWzBdLmFtb3VudCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IFtdLCAvLyBhY2NvdW50IGJhc2VkIGRvZXMgbm90IHVzZSBjaGFuZ2Ugb3V0cHV0c1xuICAgICAgY2hhbmdlQW1vdW50OiAnMCcsIC8vIGFjY291bnQgYmFzZSBkb2VzIG5vdCBtYWtlIGNoYW5nZVxuICAgICAgZmVlOiBwYXJhbXMuZmVlSW5mbyxcbiAgICAgIHRpbWVzdGFtcDogdHgudmFsaWRGcm9tLFxuICAgICAgZXhwaXJhdGlvbjogdHgudmFsaWRUbyxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGF1ZGl0RGVjcnlwdGVkS2V5KHsgbXVsdGlTaWdUeXBlLCBwdWJsaWNLZXksIHBydiB9OiBBdWRpdERlY3J5cHRlZEtleVBhcmFtcykge1xuICAgIGlmIChtdWx0aVNpZ1R5cGUgPT09ICd0c3MnKSB7XG4gICAgICBhdWRpdEVjZHNhUHJpdmF0ZUtleShwcnYgYXMgc3RyaW5nLCBwdWJsaWNLZXkgYXMgc3RyaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IE1ldGhvZE5vdEltcGxlbWVudGVkRXJyb3IoKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|