1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | const client_common_1 = require("@neo-one/client-common");
|
5 | const node_core_1 = require("@neo-one/node-core");
|
6 | const utils_1 = require("@neo-one/utils");
|
7 | const bn_js_1 = require("bn.js");
|
8 | const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
9 | const errors_1 = require("./errors");
|
10 | const getValidators_1 = require("./getValidators");
|
11 | const StorageCache_1 = require("./StorageCache");
|
12 | const wrapExecuteScripts_1 = require("./wrapExecuteScripts");
|
13 | class WriteBatchBlockchain {
|
14 | constructor(options) {
|
15 | this.settings = options.settings;
|
16 | this.currentBlockInternal = options.currentBlock;
|
17 | this.currentHeaderInternal = options.currentHeader;
|
18 | this.storage = options.storage;
|
19 | this.vm = options.vm;
|
20 | this.getValidators = options.getValidators;
|
21 | const output = new StorageCache_1.OutputStorageCache(() => this.storage.output);
|
22 | this.caches = {
|
23 | account: new StorageCache_1.ReadAllAddUpdateDeleteStorageCache({
|
24 | name: 'account',
|
25 | readAllStorage: () => this.storage.account,
|
26 | update: (value, update) => value.update(update),
|
27 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
28 | getKeyString: (key) => client_common_1.common.uInt160ToString(key.hash),
|
29 | createAddChange: (value) => ({ type: 'account', value }),
|
30 | createDeleteChange: (key) => ({ type: 'account', key }),
|
31 | }),
|
32 | accountUnspent: new StorageCache_1.ReadGetAllAddDeleteStorageCache({
|
33 | name: 'accountUnspent',
|
34 | readGetAllStorage: () => this.storage.accountUnspent,
|
35 | getKeyFromValue: (value) => ({ hash: value.hash, input: value.input }),
|
36 | getKeyString: (key) => `${client_common_1.common.uInt160ToString(key.hash)}:${client_common_1.common.uInt256ToString(key.input.hash)}:${key.input.index}`,
|
37 | matchesPartialKey: (value, key) => client_common_1.common.uInt160Equal(value.hash, key.hash),
|
38 | createAddChange: (value) => ({ type: 'accountUnspent', value }),
|
39 | createDeleteChange: (key) => ({ type: 'accountUnspent', key }),
|
40 | }),
|
41 | accountUnclaimed: new StorageCache_1.ReadGetAllAddDeleteStorageCache({
|
42 | name: 'accountUnclaimed',
|
43 | readGetAllStorage: () => this.storage.accountUnclaimed,
|
44 | getKeyFromValue: (value) => ({ hash: value.hash, input: value.input }),
|
45 | getKeyString: (key) => `${client_common_1.common.uInt160ToString(key.hash)}:${client_common_1.common.uInt256ToString(key.input.hash)}:${key.input.index}`,
|
46 | matchesPartialKey: (value, key) => client_common_1.common.uInt160Equal(value.hash, key.hash),
|
47 | createAddChange: (value) => ({ type: 'accountUnclaimed', value }),
|
48 | createDeleteChange: (key) => ({ type: 'accountUnclaimed', key }),
|
49 | }),
|
50 | action: new StorageCache_1.ReadGetAllAddStorageCache({
|
51 | name: 'action',
|
52 | readGetAllStorage: () => this.storage.action,
|
53 | getKeyFromValue: (value) => ({
|
54 | index: value.index,
|
55 | }),
|
56 | getKeyString: (key) => key.index.toString(10),
|
57 | matchesPartialKey: (value, key) => (key.indexStart === undefined || value.index.gte(key.indexStart)) &&
|
58 | (key.indexStop === undefined || value.index.lte(key.indexStop)),
|
59 | createAddChange: (value) => ({ type: 'action', value }),
|
60 | }),
|
61 | asset: new StorageCache_1.ReadAddUpdateStorageCache({
|
62 | name: 'asset',
|
63 | readStorage: () => this.storage.asset,
|
64 | update: (value, update) => value.update(update),
|
65 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
66 | getKeyString: (key) => client_common_1.common.uInt256ToString(key.hash),
|
67 | createAddChange: (value) => ({ type: 'asset', value }),
|
68 | }),
|
69 | block: new StorageCache_1.BlockLikeStorageCache({
|
70 | name: 'block',
|
71 | readStorage: () => ({
|
72 | get: this.storage.block.get,
|
73 | tryGet: this.storage.block.tryGet,
|
74 | }),
|
75 | createAddChange: (value) => ({ type: 'block', value }),
|
76 | }),
|
77 | blockData: new StorageCache_1.ReadAddStorageCache({
|
78 | name: 'blockData',
|
79 | readStorage: () => this.storage.blockData,
|
80 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
81 | getKeyString: (key) => client_common_1.common.uInt256ToString(key.hash),
|
82 | createAddChange: (value) => ({ type: 'blockData', value }),
|
83 | }),
|
84 | header: new StorageCache_1.BlockLikeStorageCache({
|
85 | name: 'header',
|
86 | readStorage: () => ({
|
87 | get: this.storage.header.get,
|
88 | tryGet: this.storage.header.tryGet,
|
89 | }),
|
90 | createAddChange: (value) => ({ type: 'header', value }),
|
91 | }),
|
92 | transaction: new StorageCache_1.ReadAddStorageCache({
|
93 | name: 'transaction',
|
94 | readStorage: () => this.storage.transaction,
|
95 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
96 | getKeyString: (key) => client_common_1.common.uInt256ToString(key.hash),
|
97 | createAddChange: (value) => ({ type: 'transaction', value }),
|
98 | onAdd: async (value) => {
|
99 | await Promise.all(value.outputs.map(async (out, index) => output.add({ hash: value.hash, index, output: out })));
|
100 | },
|
101 | allowDupes: true,
|
102 | }),
|
103 | transactionData: new StorageCache_1.ReadAddUpdateStorageCache({
|
104 | name: 'transactionData',
|
105 | readStorage: () => this.storage.transactionData,
|
106 | update: (value, update) => value.update(update),
|
107 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
108 | getKeyString: (key) => client_common_1.common.uInt256ToString(key.hash),
|
109 | createAddChange: (value) => ({ type: 'transactionData', value }),
|
110 | allowDupes: true,
|
111 | }),
|
112 | output,
|
113 | contract: new StorageCache_1.ReadAddDeleteStorageCache({
|
114 | name: 'contract',
|
115 | readStorage: () => this.storage.contract,
|
116 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
117 | getKeyString: (key) => client_common_1.common.uInt160ToString(key.hash),
|
118 | createAddChange: (value) => ({ type: 'contract', value }),
|
119 | createDeleteChange: (key) => ({ type: 'contract', key }),
|
120 | }),
|
121 | storageItem: new StorageCache_1.ReadGetAllAddUpdateDeleteStorageCache({
|
122 | name: 'storageItem',
|
123 | readGetAllStorage: () => this.storage.storageItem,
|
124 | update: (value, update) => value.update(update),
|
125 | getKeyFromValue: (value) => ({
|
126 | hash: value.hash,
|
127 | key: value.key,
|
128 | }),
|
129 | getKeyString: (key) => `${client_common_1.common.uInt160ToString(key.hash)}:${key.key.toString('hex')}`,
|
130 | matchesPartialKey: (value, key) => (key.hash === undefined || client_common_1.common.uInt160Equal(value.hash, key.hash)) &&
|
131 | (key.prefix === undefined || key.prefix.every((byte, idx) => value.key[idx] === byte)),
|
132 | createAddChange: (value) => ({ type: 'storageItem', value }),
|
133 | createDeleteChange: (key) => ({ type: 'storageItem', key }),
|
134 | }),
|
135 | validator: new StorageCache_1.ReadAllAddUpdateDeleteStorageCache({
|
136 | name: 'validator',
|
137 | readAllStorage: () => this.storage.validator,
|
138 | getKeyFromValue: (value) => ({ publicKey: value.publicKey }),
|
139 | getKeyString: (key) => client_common_1.common.ecPointToString(key.publicKey),
|
140 | createAddChange: (value) => ({ type: 'validator', value }),
|
141 | update: (value, update) => value.update(update),
|
142 | createDeleteChange: (key) => ({ type: 'validator', key }),
|
143 | }),
|
144 | invocationData: new StorageCache_1.ReadAddStorageCache({
|
145 | name: 'invocationData',
|
146 | readStorage: () => this.storage.invocationData,
|
147 | getKeyFromValue: (value) => ({ hash: value.hash }),
|
148 | getKeyString: (key) => client_common_1.common.uInt256ToString(key.hash),
|
149 | createAddChange: (value) => ({ type: 'invocationData', value }),
|
150 | }),
|
151 | validatorsCount: new StorageCache_1.ReadAddUpdateMetadataStorageCache({
|
152 | name: 'validatorsCount',
|
153 | readStorage: () => this.storage.validatorsCount,
|
154 | createAddChange: (value) => ({ type: 'validatorsCount', value }),
|
155 | update: (value, update) => value.update(update),
|
156 | }),
|
157 | };
|
158 | this.account = this.caches.account;
|
159 | this.accountUnspent = this.caches.accountUnspent;
|
160 | this.accountUnclaimed = this.caches.accountUnclaimed;
|
161 | this.action = this.caches.action;
|
162 | this.asset = this.caches.asset;
|
163 | this.block = this.caches.block;
|
164 | this.blockData = this.caches.blockData;
|
165 | this.header = this.caches.header;
|
166 | this.transaction = this.caches.transaction;
|
167 | this.transactionData = this.caches.transactionData;
|
168 | this.output = this.caches.output;
|
169 | this.contract = this.caches.contract;
|
170 | this.storageItem = this.caches.storageItem;
|
171 | this.validator = this.caches.validator;
|
172 | this.invocationData = this.caches.invocationData;
|
173 | this.validatorsCount = this.caches.validatorsCount;
|
174 | }
|
175 | get currentBlock() {
|
176 | if (this.currentBlockInternal === undefined) {
|
177 | throw new errors_1.GenesisBlockNotRegisteredError();
|
178 | }
|
179 | return this.currentBlockInternal;
|
180 | }
|
181 | get currentBlockIndex() {
|
182 | return this.currentBlockInternal === undefined ? 0 : this.currentBlockInternal.index;
|
183 | }
|
184 | get currentHeader() {
|
185 | if (this.currentHeaderInternal === undefined) {
|
186 | throw new errors_1.GenesisBlockNotRegisteredError();
|
187 | }
|
188 | return this.currentHeaderInternal;
|
189 | }
|
190 | getChangeSet() {
|
191 | return Object.values(this.caches).reduce((acc, cache) => acc.concat(cache.getChangeSet()), []);
|
192 | }
|
193 | getTrackedChangeSet() {
|
194 | return Object.values(this.caches).reduce((acc, cache) => acc.concat(cache.getTrackedChangeSet()), []);
|
195 | }
|
196 | async persistBlock(block) {
|
197 | const [maybePrevBlockData, outputContractsList] = await Promise.all([
|
198 | block.index === 0 ? Promise.resolve(undefined) : this.blockData.get({ hash: block.previousHash }),
|
199 | Promise.all([
|
200 | ...new Set(block.transactions.reduce((acc, transaction) => acc.concat(transaction.outputs.map((output) => client_common_1.common.uInt160ToString(output.address))), [])),
|
201 | ].map(async (hash) => this.contract.tryGet({ hash: client_common_1.common.stringToUInt160(hash) }))),
|
202 | this.block.add(block),
|
203 | this.header.add(block.header),
|
204 | ]);
|
205 | const prevBlockData = maybePrevBlockData === undefined
|
206 | ? {
|
207 | lastGlobalTransactionIndex: client_common_1.utils.NEGATIVE_ONE,
|
208 | lastGlobalActionIndex: client_common_1.utils.NEGATIVE_ONE,
|
209 | systemFee: client_common_1.utils.ZERO,
|
210 | }
|
211 | : {
|
212 | lastGlobalTransactionIndex: maybePrevBlockData.lastGlobalTransactionIndex,
|
213 | lastGlobalActionIndex: maybePrevBlockData.lastGlobalActionIndex,
|
214 | systemFee: maybePrevBlockData.systemFee,
|
215 | };
|
216 | const outputContracts = {};
|
217 | outputContractsList.filter(utils_1.utils.notNull).forEach((outputContract) => {
|
218 | outputContracts[outputContract.hashHex] = outputContract;
|
219 | });
|
220 | const [utxo, rest] = lodash_1.default.partition(block.transactions.map((transaction, idx) => [idx, transaction]), ([idx, transaction]) => ((transaction.type === node_core_1.TransactionType.Claim && transaction instanceof node_core_1.ClaimTransaction) ||
|
221 | (transaction.type === node_core_1.TransactionType.Contract && transaction instanceof node_core_1.ContractTransaction) ||
|
222 | (transaction.type === node_core_1.TransactionType.Miner && transaction instanceof node_core_1.MinerTransaction)) &&
|
223 | !transaction.outputs.some((output) => outputContracts[client_common_1.common.uInt160ToString(output.address)] !== undefined));
|
224 | const [globalActionIndex] = await Promise.all([
|
225 | rest.length > 0
|
226 | ? this.persistTransactions(block, rest, prevBlockData.lastGlobalTransactionIndex, prevBlockData.lastGlobalActionIndex)
|
227 | : Promise.resolve(prevBlockData.lastGlobalActionIndex),
|
228 | utxo.length > 0
|
229 | ?
|
230 | this.persistUTXOTransactions(block, utxo, prevBlockData.lastGlobalTransactionIndex)
|
231 | : Promise.resolve(),
|
232 | ]);
|
233 | await this.blockData.add(new node_core_1.BlockData({
|
234 | hash: block.hash,
|
235 | lastGlobalTransactionIndex: prevBlockData.lastGlobalTransactionIndex.add(new bn_js_1.BN(block.transactions.length)),
|
236 | lastGlobalActionIndex: globalActionIndex,
|
237 | systemFee: prevBlockData.systemFee.add(block.getSystemFee({
|
238 | getOutput: this.output.get,
|
239 | governingToken: this.settings.governingToken,
|
240 | utilityToken: this.settings.utilityToken,
|
241 | fees: this.settings.fees,
|
242 | registerValidatorFee: this.settings.registerValidatorFee,
|
243 | })),
|
244 | }));
|
245 | }
|
246 | async persistUTXOTransactions(block, transactions, lastGlobalTransactionIndex) {
|
247 | const inputs = [];
|
248 | const claims = [];
|
249 | const outputWithInputs = [];
|
250 | for (const idxAndTransaction of transactions) {
|
251 | const transaction = idxAndTransaction[1];
|
252 | inputs.push(...transaction.inputs);
|
253 | if (transaction.type === node_core_1.TransactionType.Claim && transaction instanceof node_core_1.ClaimTransaction) {
|
254 | claims.push(...transaction.claims);
|
255 | }
|
256 | outputWithInputs.push(...this.getOutputWithInput(transaction));
|
257 | }
|
258 | await Promise.all([
|
259 | Promise.all(transactions.map(async ([idx, transaction]) => this.transaction.add(transaction))),
|
260 | Promise.all(transactions.map(async ([idx, transaction]) => this.transactionData.add(new node_core_1.TransactionData({
|
261 | hash: transaction.hash,
|
262 | startHeight: block.index,
|
263 | blockHash: block.hash,
|
264 | index: idx,
|
265 | globalIndex: lastGlobalTransactionIndex.add(new bn_js_1.BN(idx + 1)),
|
266 | })))),
|
267 | this.updateAccounts(inputs, claims, outputWithInputs),
|
268 | this.updateCoins(inputs, claims, block),
|
269 | ]);
|
270 | }
|
271 | async persistTransactions(block, transactions, lastGlobalTransactionIndex, lastGlobalActionIndex) {
|
272 | let globalActionIndex = lastGlobalActionIndex.add(client_common_1.utils.ONE);
|
273 | for (const [idx, transaction] of transactions) {
|
274 | globalActionIndex = await this.persistTransaction(block, transaction, idx, lastGlobalTransactionIndex, globalActionIndex);
|
275 | }
|
276 | return globalActionIndex.sub(client_common_1.utils.ONE);
|
277 | }
|
278 | async persistTransaction(block, transactionIn, transactionIndex, lastGlobalTransactionIndex, globalActionIndexIn) {
|
279 | let globalActionIndex = globalActionIndexIn;
|
280 | const transaction = transactionIn;
|
281 | const claims = transaction.type === node_core_1.TransactionType.Claim && transaction instanceof node_core_1.ClaimTransaction ? transaction.claims : [];
|
282 | let accountChanges = {};
|
283 | let validatorChanges = {};
|
284 | let validatorsCountChanges = [];
|
285 | if (transaction.type === node_core_1.TransactionType.State && transaction instanceof node_core_1.StateTransaction) {
|
286 | ({ accountChanges, validatorChanges, validatorsCountChanges } = await getValidators_1.getDescriptorChanges({
|
287 | transactions: [transaction],
|
288 | getAccount: async (hash) => this.account.tryGet({ hash }).then((account) => (account === undefined ? new node_core_1.Account({ hash }) : account)),
|
289 | governingTokenHash: this.settings.governingToken.hashHex,
|
290 | }));
|
291 | }
|
292 | await Promise.all([
|
293 | this.transaction.add(transaction),
|
294 | this.transactionData.add(new node_core_1.TransactionData({
|
295 | hash: transaction.hash,
|
296 | blockHash: block.hash,
|
297 | startHeight: block.index,
|
298 | index: transactionIndex,
|
299 | globalIndex: lastGlobalTransactionIndex.add(new bn_js_1.BN(transactionIndex + 1)),
|
300 | })),
|
301 | this.updateAccounts(transaction.inputs, claims, this.getOutputWithInput(transaction), accountChanges),
|
302 | this.updateCoins(transaction.inputs, claims, block),
|
303 | this.processStateTransaction(validatorChanges, validatorsCountChanges),
|
304 | ]);
|
305 | if (transaction.type === node_core_1.TransactionType.Register && transaction instanceof node_core_1.RegisterTransaction) {
|
306 | await this.asset.add(new node_core_1.Asset({
|
307 | hash: transaction.hash,
|
308 | type: transaction.asset.type,
|
309 | name: transaction.asset.name,
|
310 | amount: transaction.asset.amount,
|
311 | precision: transaction.asset.precision,
|
312 | owner: transaction.asset.owner,
|
313 | admin: transaction.asset.admin,
|
314 | issuer: transaction.asset.admin,
|
315 | expiration: this.currentBlockIndex + 2 * 2000000,
|
316 | isFrozen: false,
|
317 | }));
|
318 | }
|
319 | else if (transaction.type === node_core_1.TransactionType.Issue && transaction instanceof node_core_1.IssueTransaction) {
|
320 | const results = await Promise.all(Object.entries(transaction.getTransactionResults({
|
321 | getOutput: this.output.get,
|
322 | })));
|
323 | await Promise.all(results.map(async ([assetHex, value]) => {
|
324 | const hash = client_common_1.common.stringToUInt256(assetHex);
|
325 | const asset = await this.asset.get({ hash });
|
326 | await this.asset.update(asset, {
|
327 | available: asset.available.add(value.neg()),
|
328 | });
|
329 | }));
|
330 | }
|
331 | else if (transaction.type === node_core_1.TransactionType.Enrollment && transaction instanceof node_core_1.EnrollmentTransaction) {
|
332 | await this.validator.add(new node_core_1.Validator({
|
333 | publicKey: transaction.publicKey,
|
334 | }));
|
335 | }
|
336 | else if (transaction.type === node_core_1.TransactionType.Publish && transaction instanceof node_core_1.PublishTransaction) {
|
337 | const contract = await this.contract.tryGet({
|
338 | hash: transaction.contract.hash,
|
339 | });
|
340 | if (contract === undefined) {
|
341 | await this.contract.add(transaction.contract);
|
342 | }
|
343 | }
|
344 | else if (transaction.type === node_core_1.TransactionType.Invocation && transaction instanceof node_core_1.InvocationTransaction) {
|
345 | const temporaryBlockchain = new WriteBatchBlockchain({
|
346 | settings: this.settings,
|
347 | currentBlock: this.currentBlockInternal,
|
348 | currentHeader: this.currentHeader,
|
349 | storage: this,
|
350 | vm: this.vm,
|
351 | getValidators: this.getValidators,
|
352 | });
|
353 | const migratedContractHashes = [];
|
354 | const voteUpdates = [];
|
355 | const actions = [];
|
356 | const result = await wrapExecuteScripts_1.wrapExecuteScripts(async () => this.vm.executeScripts({
|
357 | scripts: [{ code: transaction.script }],
|
358 | blockchain: temporaryBlockchain,
|
359 | scriptContainer: {
|
360 | type: node_core_1.ScriptContainerType.Transaction,
|
361 | value: transaction,
|
362 | },
|
363 | triggerType: node_core_1.TriggerType.Application,
|
364 | action: {
|
365 | blockIndex: block.index,
|
366 | blockHash: block.hash,
|
367 | transactionIndex,
|
368 | transactionHash: transaction.hash,
|
369 | },
|
370 | gas: transaction.gas,
|
371 | listeners: {
|
372 | onLog: ({ message, scriptHash }) => {
|
373 | actions.push(new node_core_1.LogAction({
|
374 | index: globalActionIndex,
|
375 | scriptHash,
|
376 | message,
|
377 | }));
|
378 | globalActionIndex = globalActionIndex.add(client_common_1.utils.ONE);
|
379 | },
|
380 | onNotify: ({ args, scriptHash }) => {
|
381 | actions.push(new node_core_1.NotificationAction({
|
382 | index: globalActionIndex,
|
383 | scriptHash,
|
384 | args,
|
385 | }));
|
386 | globalActionIndex = globalActionIndex.add(client_common_1.utils.ONE);
|
387 | },
|
388 | onMigrateContract: ({ from, to }) => {
|
389 | migratedContractHashes.push([from, to]);
|
390 | },
|
391 | onSetVotes: ({ address, votes }) => {
|
392 | voteUpdates.push([address, votes]);
|
393 | },
|
394 | },
|
395 | persistingBlock: block,
|
396 | }));
|
397 | const addActionsPromise = Promise.all(actions.map(async (action) => this.action.add(action)));
|
398 | if (result instanceof node_core_1.InvocationResultSuccess) {
|
399 | const assetChangeSet = temporaryBlockchain.asset.getChangeSet();
|
400 | const assetHash = assetChangeSet
|
401 | .map((change) => change.type === 'add' && change.change.type === 'asset' ? change.change.value.hash : undefined)
|
402 | .find((value) => value !== undefined);
|
403 | const contractsChangeSet = temporaryBlockchain.contract.getChangeSet();
|
404 | const contractHashes = contractsChangeSet
|
405 | .map((change) => change.type === 'add' && change.change.type === 'contract' ? change.change.value.hash : undefined)
|
406 | .filter(utils_1.utils.notNull);
|
407 | const deletedContractHashes = contractsChangeSet
|
408 | .map((change) => change.type === 'delete' && change.change.type === 'contract' ? change.change.key.hash : undefined)
|
409 | .filter(utils_1.utils.notNull);
|
410 | const storageChanges = temporaryBlockchain.storageItem
|
411 | .getChangeSet()
|
412 | .map((change) => {
|
413 | const addChange = change.type === 'add' && change.change.type === 'storageItem'
|
414 | ? { value: change.change.value, subType: change.subType }
|
415 | : undefined;
|
416 | if (addChange !== undefined) {
|
417 | const options = {
|
418 | hash: addChange.value.hash,
|
419 | key: addChange.value.key,
|
420 | value: addChange.value.value,
|
421 | };
|
422 | return addChange.subType === 'add' ? new node_core_1.StorageChangeAdd(options) : new node_core_1.StorageChangeModify(options);
|
423 | }
|
424 | const deleteChange = change.type === 'delete' && change.change.type === 'storageItem' ? change.change.key : undefined;
|
425 | if (deleteChange !== undefined) {
|
426 | return new node_core_1.StorageChangeDelete(deleteChange);
|
427 | }
|
428 | return undefined;
|
429 | })
|
430 | .filter(utils_1.utils.notNull);
|
431 | temporaryBlockchain.getTrackedChangeSet().forEach((change) => {
|
432 | this.caches[change.type].addTrackedChange(change.key, change.value);
|
433 | });
|
434 | await Promise.all([
|
435 | this.invocationData.add(new node_core_1.InvocationData({
|
436 | hash: transaction.hash,
|
437 | assetHash,
|
438 | contractHashes,
|
439 | deletedContractHashes,
|
440 | migratedContractHashes,
|
441 | voteUpdates,
|
442 | blockIndex: block.index,
|
443 | transactionIndex,
|
444 | actionIndexStart: globalActionIndexIn,
|
445 | actionIndexStop: globalActionIndex,
|
446 | result,
|
447 | storageChanges,
|
448 | })),
|
449 | addActionsPromise,
|
450 | ]);
|
451 | }
|
452 | else {
|
453 | await Promise.all([
|
454 | this.invocationData.add(new node_core_1.InvocationData({
|
455 | hash: transaction.hash,
|
456 | assetHash: undefined,
|
457 | contractHashes: [],
|
458 | deletedContractHashes: [],
|
459 | migratedContractHashes: [],
|
460 | voteUpdates: [],
|
461 | blockIndex: block.index,
|
462 | transactionIndex,
|
463 | actionIndexStart: globalActionIndexIn,
|
464 | actionIndexStop: globalActionIndex,
|
465 | result,
|
466 | storageChanges: [],
|
467 | })),
|
468 | addActionsPromise,
|
469 | ]);
|
470 | }
|
471 | }
|
472 | return globalActionIndex;
|
473 | }
|
474 | async processStateTransaction(validatorChanges, validatorsCountChanges) {
|
475 | const validatorsCount = await this.validatorsCount.tryGet();
|
476 | const validatorsCountVotes = validatorsCount === undefined ? [] : [...validatorsCount.votes];
|
477 | for (const [index, value] of validatorsCountChanges.entries()) {
|
478 | validatorsCountVotes[index] = value;
|
479 | }
|
480 | await Promise.all([
|
481 | Promise.all(Object.entries(validatorChanges).map(async ([publicKeyHex, { registered, votes }]) => {
|
482 | const publicKey = client_common_1.common.hexToECPoint(publicKeyHex);
|
483 | const validator = await this.validator.tryGet({ publicKey });
|
484 | if (validator === undefined) {
|
485 | await this.validator.add(new node_core_1.Validator({
|
486 | publicKey,
|
487 | registered,
|
488 | votes,
|
489 | }));
|
490 | }
|
491 | else if (((registered !== undefined && !registered) || (registered === undefined && !validator.registered)) &&
|
492 | ((votes !== undefined && votes.eq(client_common_1.utils.ZERO)) || (votes === undefined && validator.votes.eq(client_common_1.utils.ZERO)))) {
|
493 | await this.validator.delete({ publicKey: validator.publicKey });
|
494 | }
|
495 | else {
|
496 | await this.validator.update(validator, { votes, registered });
|
497 | }
|
498 | })),
|
499 | validatorsCount === undefined
|
500 | ? this.validatorsCount.add(new node_core_1.ValidatorsCount({
|
501 | votes: validatorsCountVotes,
|
502 | }))
|
503 | : (async () => {
|
504 | await this.validatorsCount.update(validatorsCount, {
|
505 | votes: validatorsCountVotes,
|
506 | });
|
507 | })(),
|
508 | ]);
|
509 | }
|
510 | async updateAccounts(inputs, claims, outputs, accountChanges = {}) {
|
511 | const [inputOutputs, claimOutputs] = await Promise.all([
|
512 | this.getInputOutputs(inputs),
|
513 | this.getInputOutputs(claims),
|
514 | ]);
|
515 | const addressValues = Object.entries(lodash_1.default.groupBy(inputOutputs
|
516 | .map(({ output }) => [output.address, output.asset, output.value.neg()])
|
517 | .concat(outputs.map(({ output }) => [output.address, output.asset, output.value])), ([address]) => client_common_1.common.uInt160ToHex(address)));
|
518 | const addressSpent = this.groupByAddress(inputOutputs);
|
519 | const addressClaimed = lodash_1.default.mapValues(this.groupByAddress(claimOutputs), (values) => values.map(({ input }) => input));
|
520 | const addressOutputs = lodash_1.default.groupBy(outputs, (output) => client_common_1.common.uInt160ToHex(output.output.address));
|
521 | await Promise.all(addressValues.map(async ([address, values]) => {
|
522 | const spent = addressSpent[address];
|
523 | const claimed = addressClaimed[address];
|
524 | const outs = addressOutputs[address];
|
525 | const changes = accountChanges[address];
|
526 | await this.updateAccount(client_common_1.common.hexToUInt160(address), values.map(([_address, asset, value]) => [asset, value]), spent === undefined ? [] : spent, claimed === undefined ? [] : claimed, outs === undefined ? [] : outs, changes === undefined ? [] : changes);
|
527 | }));
|
528 | }
|
529 | getOutputWithInput(transaction) {
|
530 | return transaction.outputs.map((output, index) => ({
|
531 | output,
|
532 | input: new node_core_1.Input({ hash: transaction.hash, index }),
|
533 | }));
|
534 | }
|
535 | async getInputOutputs(inputs) {
|
536 | return Promise.all(inputs.map(async (input) => {
|
537 | const output = await this.output.get(input);
|
538 | return { input, output };
|
539 | }));
|
540 | }
|
541 | groupByAddress(inputOutputs) {
|
542 | return lodash_1.default.groupBy(inputOutputs, ({ output }) => client_common_1.common.uInt160ToHex(output.address));
|
543 | }
|
544 | async updateAccount(address, values, spent, claimed, outputs, votes) {
|
545 | const account = await this.account.tryGet({ hash: address });
|
546 | const balances = values.reduce((acc, [asset, value]) => {
|
547 | const key = client_common_1.common.uInt256ToHex(asset);
|
548 | if (acc[key] === undefined) {
|
549 | acc[key] = client_common_1.utils.ZERO;
|
550 | }
|
551 | acc[key] = acc[key].add(value);
|
552 | return acc;
|
553 | }, account === undefined
|
554 | ? {}
|
555 | : Object.entries(account.balances).reduce((acc, [key, value]) => {
|
556 | if (value === undefined) {
|
557 | return Object.assign({}, acc, { [key]: client_common_1.utils.ZERO });
|
558 | }
|
559 | return Object.assign({}, acc, { [key]: value });
|
560 | }, {}));
|
561 | const promises = [];
|
562 | promises.push(...spent.map(async ({ input }) => this.accountUnspent.delete({
|
563 | hash: address,
|
564 | input,
|
565 | })));
|
566 | promises.push(...outputs.map(async ({ input }) => this.accountUnspent.add(new node_core_1.AccountUnspent({ hash: address, input }))));
|
567 | promises.push(...claimed.map(async (input) => this.accountUnclaimed.delete({
|
568 | hash: address,
|
569 | input,
|
570 | })));
|
571 | promises.push(...spent
|
572 | .filter(({ output }) => client_common_1.common.uInt256Equal(output.asset, this.settings.governingToken.hash))
|
573 | .map(async ({ input }) => this.accountUnclaimed.add(new node_core_1.AccountUnclaimed({ hash: address, input }))));
|
574 | if (account === undefined) {
|
575 | promises.push(this.account.add(new node_core_1.Account({
|
576 | hash: address,
|
577 | balances,
|
578 | votes,
|
579 | })));
|
580 | }
|
581 | else {
|
582 | promises.push(this.account.update(account, { balances, votes }).then(async (newAccount) => {
|
583 | if (newAccount.isDeletable()) {
|
584 | await this.account.delete({ hash: address });
|
585 | }
|
586 | }));
|
587 | }
|
588 | await Promise.all(promises);
|
589 | }
|
590 | async updateCoins(inputs, claims, block) {
|
591 | const inputClaims = inputs
|
592 | .map((input) => ({ type: 'input', input, hash: input.hash }))
|
593 | .concat(claims.map((input) => ({ type: 'claim', input, hash: input.hash })));
|
594 | const hashInputClaims = Object.entries(lodash_1.default.groupBy(inputClaims, ({ hash }) => client_common_1.common.uInt256ToHex(hash)));
|
595 | await Promise.all(hashInputClaims.map(async ([hash, values]) => this.updateCoin(client_common_1.common.hexToUInt256(hash), values, block)));
|
596 | }
|
597 | async updateCoin(hash, inputClaims, block) {
|
598 | const spentCoins = await this.transactionData.get({ hash });
|
599 | const endHeights = Object.assign({}, spentCoins.endHeights);
|
600 | const claimed = Object.assign({}, spentCoins.claimed);
|
601 | for (const inputClaim of inputClaims) {
|
602 | if (inputClaim.type === 'input') {
|
603 | endHeights[inputClaim.input.index] = block.index;
|
604 | }
|
605 | else {
|
606 | claimed[inputClaim.input.index] = true;
|
607 | }
|
608 | }
|
609 | await this.transactionData.update(spentCoins, {
|
610 | endHeights,
|
611 | claimed,
|
612 | });
|
613 | }
|
614 | }
|
615 | exports.WriteBatchBlockchain = WriteBatchBlockchain;
|
616 |
|
617 | //# sourceMappingURL=data:application/json;charset=utf8;base64,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VSxDQUFDLE9BQU8sQ0FBRSxDQUFDO1FBRTFDLEtBQUssTUFBTSxVQUFVLElBQUksV0FBVyxFQUFFO1lBQ3BDLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7Z0JBQy9CLFVBQVUsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDbEQ7aUJBQU07Z0JBQ0wsT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDO2FBQ3hDO1NBQ0Y7UUFFRCxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtZQUM1QyxVQUFVO1lBQ1YsT0FBTztTQUNSLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQXAzQkQsb0RBbzNCQyIsImZpbGUiOiJuZW8tb25lLW5vZGUtYmxvY2tjaGFpbi9zcmMvV3JpdGVCYXRjaEJsb2NrY2hhaW4uanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0c2xpbnQ6ZGlzYWJsZSBuby1hcnJheS1tdXRhdGlvbiBuby1vYmplY3QtbXV0YXRpb25cbmltcG9ydCB7IGNvbW1vbiwgRUNQb2ludCwgVUludDE2MCwgVUludDI1NiwgdXRpbHMgfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29tbW9uJztcbmltcG9ydCB7XG4gIEFjY291bnQsXG4gIEFjY291bnRLZXksXG4gIEFjY291bnRVbmNsYWltZWQsXG4gIEFjY291bnRVbmNsYWltZWRLZXksXG4gIEFjY291bnRVbmNsYWltZWRzS2V5LFxuICBBY2NvdW50VW5zcGVudCxcbiAgQWNjb3VudFVuc3BlbnRLZXksXG4gIEFjY291bnRVbnNwZW50c0tleSxcbiAgQWNjb3VudFVwZGF0ZSxcbiAgQWN0aW9uLFxuICBBY3Rpb25LZXksXG4gIEFjdGlvbnNLZXksXG4gIEFzc2V0LFxuICBBc3NldEtleSxcbiAgQXNzZXRVcGRhdGUsXG4gIEJsb2NrLFxuICBCbG9ja2NoYWluU3RvcmFnZSxcbiAgQmxvY2tEYXRhLFxuICBCbG9ja0RhdGFLZXksXG4gIENoYW5nZVNldCxcbiAgQ2xhaW1UcmFuc2FjdGlvbixcbiAgQ29udHJhY3QsXG4gIENvbnRyYWN0S2V5LFxuICBDb250cmFjdFRyYW5zYWN0aW9uLFxuICBFbnJvbGxtZW50VHJhbnNhY3Rpb24sXG4gIEhlYWRlcixcbiAgSW5wdXQsXG4gIEludm9jYXRpb25EYXRhLFxuICBJbnZvY2F0aW9uRGF0YUtleSxcbiAgSW52b2NhdGlvblJlc3VsdFN1Y2Nlc3MsXG4gIEludm9jYXRpb25UcmFuc2FjdGlvbixcbiAgSXNzdWVUcmFuc2FjdGlvbixcbiAgTG9nQWN0aW9uLFxuICBNaW5lclRyYW5zYWN0aW9uLFxuICBOb3RpZmljYXRpb25BY3Rpb24sXG4gIE91dHB1dCxcbiAgUHVibGlzaFRyYW5zYWN0aW9uLFxuICBSZWdpc3RlclRyYW5zYWN0aW9uLFxuICBTY3JpcHRDb250YWluZXJUeXBlLFxuICBTdGF0ZVRyYW5zYWN0aW9uLFxuICBTdG9yYWdlQ2hhbmdlQWRkLFxuICBTdG9yYWdlQ2hhbmdlRGVsZXRlLFxuICBTdG9yYWdlQ2hhbmdlTW9kaWZ5LFxuICBTdG9yYWdlSXRlbSxcbiAgU3RvcmFnZUl0ZW1LZXksXG4gIFN0b3JhZ2VJdGVtc0tleSxcbiAgU3RvcmFnZUl0ZW1VcGRhdGUsXG4gIFRyYW5zYWN0aW9uLFxuICBUcmFuc2FjdGlvbkRhdGEsXG4gIFRyYW5zYWN0aW9uRGF0YUtleSxcbiAgVHJhbnNhY3Rpb25EYXRhVXBkYXRlLFxuICBUcmFuc2FjdGlvbktleSxcbiAgVHJhbnNhY3Rpb25UeXBlLFxuICBUcmlnZ2VyVHlwZSxcbiAgVmFsaWRhdG9yLFxuICBWYWxpZGF0b3JLZXksXG4gIFZhbGlkYXRvcnNDb3VudCxcbiAgVmFsaWRhdG9yc0NvdW50VXBkYXRlLFxuICBWYWxpZGF0b3JVcGRhdGUsXG4gIFZNLFxuICBXcml0ZUJsb2NrY2hhaW4sXG59IGZyb20gJ0BuZW8tb25lL25vZGUtY29yZSc7XG5pbXBvcnQgeyB1dGlscyBhcyBjb21tb25VdGlscyB9IGZyb20gJ0BuZW8tb25lL3V0aWxzJztcbmltcG9ydCB7IEJOIH0gZnJvbSAnYm4uanMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IEdlbmVzaXNCbG9ja05vdFJlZ2lzdGVyZWRFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IEFjY291bnRDaGFuZ2VzLCBnZXREZXNjcmlwdG9yQ2hhbmdlcywgVmFsaWRhdG9yQ2hhbmdlcywgVmFsaWRhdG9yc0NvdW50Q2hhbmdlcyB9IGZyb20gJy4vZ2V0VmFsaWRhdG9ycyc7XG5pbXBvcnQge1xuICBCbG9ja0xpa2VTdG9yYWdlQ2FjaGUsXG4gIE91dHB1dFN0b3JhZ2VDYWNoZSxcbiAgUmVhZEFkZERlbGV0ZVN0b3JhZ2VDYWNoZSxcbiAgUmVhZEFkZFN0b3JhZ2VDYWNoZSxcbiAgUmVhZEFkZFVwZGF0ZU1ldGFkYXRhU3RvcmFnZUNhY2hlLFxuICBSZWFkQWRkVXBkYXRlU3RvcmFnZUNhY2hlLFxuICBSZWFkQWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlLFxuICBSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlLFxuICBSZWFkR2V0QWxsQWRkU3RvcmFnZUNhY2hlLFxuICBSZWFkR2V0QWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlLFxuICBUcmFja2VkQ2hhbmdlU2V0LFxufSBmcm9tICcuL1N0b3JhZ2VDYWNoZSc7XG5pbXBvcnQgeyB3cmFwRXhlY3V0ZVNjcmlwdHMgfSBmcm9tICcuL3dyYXBFeGVjdXRlU2NyaXB0cyc7XG5cbmludGVyZmFjZSBXcml0ZUJhdGNoQmxvY2tjaGFpbk9wdGlvbnMge1xuICByZWFkb25seSBzZXR0aW5nczogV3JpdGVCbG9ja2NoYWluWydzZXR0aW5ncyddO1xuICByZWFkb25seSBjdXJyZW50QmxvY2s6IFdyaXRlQmxvY2tjaGFpblsnY3VycmVudEJsb2NrJ10gfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IGN1cnJlbnRIZWFkZXI6IFdyaXRlQmxvY2tjaGFpblsnY3VycmVudEhlYWRlciddIHwgdW5kZWZpbmVkO1xuICByZWFkb25seSBzdG9yYWdlOiBCbG9ja2NoYWluU3RvcmFnZTtcbiAgcmVhZG9ubHkgdm06IFZNO1xuICByZWFkb25seSBnZXRWYWxpZGF0b3JzOiBXcml0ZUJsb2NrY2hhaW5bJ2dldFZhbGlkYXRvcnMnXTtcbn1cblxuaW50ZXJmYWNlIENhY2hlcyB7XG4gIHJlYWRvbmx5IGFjY291bnQ6IFJlYWRBbGxBZGRVcGRhdGVEZWxldGVTdG9yYWdlQ2FjaGU8QWNjb3VudEtleSwgQWNjb3VudCwgQWNjb3VudFVwZGF0ZT47XG4gIHJlYWRvbmx5IGFjY291bnRVbnNwZW50OiBSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlPEFjY291bnRVbnNwZW50S2V5LCBBY2NvdW50VW5zcGVudHNLZXksIEFjY291bnRVbnNwZW50PjtcbiAgcmVhZG9ubHkgYWNjb3VudFVuY2xhaW1lZDogUmVhZEdldEFsbEFkZERlbGV0ZVN0b3JhZ2VDYWNoZTxcbiAgICBBY2NvdW50VW5jbGFpbWVkS2V5LFxuICAgIEFjY291bnRVbmNsYWltZWRzS2V5LFxuICAgIEFjY291bnRVbmNsYWltZWRcbiAgPjtcbiAgcmVhZG9ubHkgYWN0aW9uOiBSZWFkR2V0QWxsQWRkU3RvcmFnZUNhY2hlPEFjdGlvbktleSwgQWN0aW9uc0tleSwgQWN0aW9uPjtcbiAgcmVhZG9ubHkgYXNzZXQ6IFJlYWRBZGRVcGRhdGVTdG9yYWdlQ2FjaGU8QXNzZXRLZXksIEFzc2V0LCBBc3NldFVwZGF0ZT47XG4gIHJlYWRvbmx5IGJsb2NrOiBCbG9ja0xpa2VTdG9yYWdlQ2FjaGU8QmxvY2s+O1xuICByZWFkb25seSBibG9ja0RhdGE6IFJlYWRBZGRTdG9yYWdlQ2FjaGU8QmxvY2tEYXRhS2V5LCBCbG9ja0RhdGE+O1xuICByZWFkb25seSBoZWFkZXI6IEJsb2NrTGlrZVN0b3JhZ2VDYWNoZTxIZWFkZXI+O1xuICByZWFkb25seSB0cmFuc2FjdGlvbjogUmVhZEFkZFN0b3JhZ2VDYWNoZTxUcmFuc2FjdGlvbktleSwgVHJhbnNhY3Rpb24+O1xuICByZWFkb25seSB0cmFuc2FjdGlvbkRhdGE6IFJlYWRBZGRVcGRhdGVTdG9yYWdlQ2FjaGU8VHJhbnNhY3Rpb25EYXRhS2V5LCBUcmFuc2FjdGlvbkRhdGEsIFRyYW5zYWN0aW9uRGF0YVVwZGF0ZT47XG4gIHJlYWRvbmx5IG91dHB1dDogT3V0cHV0U3RvcmFnZUNhY2hlO1xuICByZWFkb25seSBjb250cmFjdDogUmVhZEFkZERlbGV0ZVN0b3JhZ2VDYWNoZTxDb250cmFjdEtleSwgQ29udHJhY3Q+O1xuICByZWFkb25seSBzdG9yYWdlSXRlbTogUmVhZEdldEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZTxcbiAgICBTdG9yYWdlSXRlbUtleSxcbiAgICBTdG9yYWdlSXRlbXNLZXksXG4gICAgU3RvcmFnZUl0ZW0sXG4gICAgU3RvcmFnZUl0ZW1VcGRhdGVcbiAgPjtcbiAgcmVhZG9ubHkgdmFsaWRhdG9yOiBSZWFkQWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlPFZhbGlkYXRvcktleSwgVmFsaWRhdG9yLCBWYWxpZGF0b3JVcGRhdGU+O1xuICByZWFkb25seSBpbnZvY2F0aW9uRGF0YTogUmVhZEFkZFN0b3JhZ2VDYWNoZTxJbnZvY2F0aW9uRGF0YUtleSwgSW52b2NhdGlvbkRhdGE+O1xuICByZWFkb25seSB2YWxpZGF0b3JzQ291bnQ6IFJlYWRBZGRVcGRhdGVNZXRhZGF0YVN0b3JhZ2VDYWNoZTxWYWxpZGF0b3JzQ291bnQsIFZhbGlkYXRvcnNDb3VudFVwZGF0ZT47XG59XG5cbmludGVyZmFjZSBJbnB1dENsYWltIHtcbiAgcmVhZG9ubHkgdHlwZTogJ2NsYWltJyB8ICdpbnB1dCc7XG4gIHJlYWRvbmx5IGhhc2g6IFVJbnQyNTY7XG4gIHJlYWRvbmx5IGlucHV0OiBJbnB1dDtcbn1cblxuaW50ZXJmYWNlIE91dHB1dFdpdGhJbnB1dCB7XG4gIHJlYWRvbmx5IG91dHB1dDogT3V0cHV0O1xuICByZWFkb25seSBpbnB1dDogSW5wdXQ7XG59XG5cbmV4cG9ydCBjbGFzcyBXcml0ZUJhdGNoQmxvY2tjaGFpbiB7XG4gIHB1YmxpYyByZWFkb25seSBzZXR0aW5nczogV3JpdGVCbG9ja2NoYWluWydzZXR0aW5ncyddO1xuICBwdWJsaWMgcmVhZG9ubHkgYWNjb3VudDogUmVhZEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZTxBY2NvdW50S2V5LCBBY2NvdW50LCBBY2NvdW50VXBkYXRlPjtcbiAgcHVibGljIHJlYWRvbmx5IGFjY291bnRVbnNwZW50OiBSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlPFxuICAgIEFjY291bnRVbnNwZW50S2V5LFxuICAgIEFjY291bnRVbnNwZW50c0tleSxcbiAgICBBY2NvdW50VW5zcGVudFxuICA+O1xuICBwdWJsaWMgcmVhZG9ubHkgYWNjb3VudFVuY2xhaW1lZDogUmVhZEdldEFsbEFkZERlbGV0ZVN0b3JhZ2VDYWNoZTxcbiAgICBBY2NvdW50VW5jbGFpbWVkS2V5LFxuICAgIEFjY291bnRVbmNsYWltZWRzS2V5LFxuICAgIEFjY291bnRVbmNsYWltZWRcbiAgPjtcbiAgcHVibGljIHJlYWRvbmx5IGFjdGlvbjogUmVhZEdldEFsbEFkZFN0b3JhZ2VDYWNoZTxBY3Rpb25LZXksIEFjdGlvbnNLZXksIEFjdGlvbj47XG4gIHB1YmxpYyByZWFkb25seSBhc3NldDogUmVhZEFkZFVwZGF0ZVN0b3JhZ2VDYWNoZTxBc3NldEtleSwgQXNzZXQsIEFzc2V0VXBkYXRlPjtcbiAgcHVibGljIHJlYWRvbmx5IGJsb2NrOiBCbG9ja0xpa2VTdG9yYWdlQ2FjaGU8QmxvY2s+O1xuICBwdWJsaWMgcmVhZG9ubHkgYmxvY2tEYXRhOiBSZWFkQWRkU3RvcmFnZUNhY2hlPEJsb2NrRGF0YUtleSwgQmxvY2tEYXRhPjtcbiAgcHVibGljIHJlYWRvbmx5IGhlYWRlcjogQmxvY2tMaWtlU3RvcmFnZUNhY2hlPEhlYWRlcj47XG4gIHB1YmxpYyByZWFkb25seSB0cmFuc2FjdGlvbjogUmVhZEFkZFN0b3JhZ2VDYWNoZTxUcmFuc2FjdGlvbktleSwgVHJhbnNhY3Rpb24+O1xuICBwdWJsaWMgcmVhZG9ubHkgdHJhbnNhY3Rpb25EYXRhOiBSZWFkQWRkVXBkYXRlU3RvcmFnZUNhY2hlPFxuICAgIFRyYW5zYWN0aW9uRGF0YUtleSxcbiAgICBUcmFuc2FjdGlvbkRhdGEsXG4gICAgVHJhbnNhY3Rpb25EYXRhVXBkYXRlXG4gID47XG4gIHB1YmxpYyByZWFkb25seSBvdXRwdXQ6IE91dHB1dFN0b3JhZ2VDYWNoZTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbnRyYWN0OiBSZWFkQWRkRGVsZXRlU3RvcmFnZUNhY2hlPENvbnRyYWN0S2V5LCBDb250cmFjdD47XG4gIHB1YmxpYyByZWFkb25seSBzdG9yYWdlSXRlbTogUmVhZEdldEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZTxcbiAgICBTdG9yYWdlSXRlbUtleSxcbiAgICBTdG9yYWdlSXRlbXNLZXksXG4gICAgU3RvcmFnZUl0ZW0sXG4gICAgU3RvcmFnZUl0ZW1VcGRhdGVcbiAgPjtcbiAgcHVibGljIHJlYWRvbmx5IHZhbGlkYXRvcjogUmVhZEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZTxWYWxpZGF0b3JLZXksIFZhbGlkYXRvciwgVmFsaWRhdG9yVXBkYXRlPjtcbiAgcHVibGljIHJlYWRvbmx5IGludm9jYXRpb25EYXRhOiBSZWFkQWRkU3RvcmFnZUNhY2hlPEludm9jYXRpb25EYXRhS2V5LCBJbnZvY2F0aW9uRGF0YT47XG4gIHB1YmxpYyByZWFkb25seSB2YWxpZGF0b3JzQ291bnQ6IFJlYWRBZGRVcGRhdGVNZXRhZGF0YVN0b3JhZ2VDYWNoZTxWYWxpZGF0b3JzQ291bnQsIFZhbGlkYXRvcnNDb3VudFVwZGF0ZT47XG4gIHB1YmxpYyByZWFkb25seSBnZXRWYWxpZGF0b3JzOiBXcml0ZUJsb2NrY2hhaW5bJ2dldFZhbGlkYXRvcnMnXTtcbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW50QmxvY2tJbnRlcm5hbDogV3JpdGVCbG9ja2NoYWluWydjdXJyZW50QmxvY2snXSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW50SGVhZGVySW50ZXJuYWw6IFdyaXRlQmxvY2tjaGFpblsnY3VycmVudEhlYWRlciddIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2U6IEJsb2NrY2hhaW5TdG9yYWdlO1xuICBwcml2YXRlIHJlYWRvbmx5IHZtOiBWTTtcbiAgcHJpdmF0ZSByZWFkb25seSBjYWNoZXM6IENhY2hlcztcblxuICBwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogV3JpdGVCYXRjaEJsb2NrY2hhaW5PcHRpb25zKSB7XG4gICAgdGhpcy5zZXR0aW5ncyA9IG9wdGlvbnMuc2V0dGluZ3M7XG4gICAgdGhpcy5jdXJyZW50QmxvY2tJbnRlcm5hbCA9IG9wdGlvbnMuY3VycmVudEJsb2NrO1xuICAgIHRoaXMuY3VycmVudEhlYWRlckludGVybmFsID0gb3B0aW9ucy5jdXJyZW50SGVhZGVyO1xuICAgIHRoaXMuc3RvcmFnZSA9IG9wdGlvbnMuc3RvcmFnZTtcbiAgICB0aGlzLnZtID0gb3B0aW9ucy52bTtcbiAgICB0aGlzLmdldFZhbGlkYXRvcnMgPSBvcHRpb25zLmdldFZhbGlkYXRvcnM7XG5cbiAgICBjb25zdCBvdXRwdXQgPSBuZXcgT3V0cHV0U3RvcmFnZUNhY2hlKCgpID0+IHRoaXMuc3RvcmFnZS5vdXRwdXQpO1xuICAgIHRoaXMuY2FjaGVzID0ge1xuICAgICAgYWNjb3VudDogbmV3IFJlYWRBbGxBZGRVcGRhdGVEZWxldGVTdG9yYWdlQ2FjaGUoe1xuICAgICAgICBuYW1lOiAnYWNjb3VudCcsXG4gICAgICAgIHJlYWRBbGxTdG9yYWdlOiAoKSA9PiB0aGlzLnN0b3JhZ2UuYWNjb3VudCxcbiAgICAgICAgdXBkYXRlOiAodmFsdWUsIHVwZGF0ZSkgPT4gdmFsdWUudXBkYXRlKHVwZGF0ZSksXG4gICAgICAgIGdldEtleUZyb21WYWx1ZTogKHZhbHVlKSA9PiAoeyBoYXNoOiB2YWx1ZS5oYXNoIH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGNvbW1vbi51SW50MTYwVG9TdHJpbmcoa2V5Lmhhc2gpLFxuICAgICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZSkgPT4gKHsgdHlwZTogJ2FjY291bnQnLCB2YWx1ZSB9KSxcbiAgICAgICAgY3JlYXRlRGVsZXRlQ2hhbmdlOiAoa2V5KSA9PiAoeyB0eXBlOiAnYWNjb3VudCcsIGtleSB9KSxcbiAgICAgIH0pLFxuICAgICAgYWNjb3VudFVuc3BlbnQ6IG5ldyBSZWFkR2V0QWxsQWRkRGVsZXRlU3RvcmFnZUNhY2hlKHtcbiAgICAgICAgbmFtZTogJ2FjY291bnRVbnNwZW50JyxcbiAgICAgICAgcmVhZEdldEFsbFN0b3JhZ2U6ICgpID0+IHRoaXMuc3RvcmFnZS5hY2NvdW50VW5zcGVudCxcbiAgICAgICAgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWUpID0+ICh7IGhhc2g6IHZhbHVlLmhhc2gsIGlucHV0OiB2YWx1ZS5pbnB1dCB9KSxcbiAgICAgICAgZ2V0S2V5U3RyaW5nOiAoa2V5KSA9PlxuICAgICAgICAgIGAke2NvbW1vbi51SW50MTYwVG9TdHJpbmcoa2V5Lmhhc2gpfToke2NvbW1vbi51SW50MjU2VG9TdHJpbmcoa2V5LmlucHV0Lmhhc2gpfToke2tleS5pbnB1dC5pbmRleH1gLFxuICAgICAgICBtYXRjaGVzUGFydGlhbEtleTogKHZhbHVlLCBrZXkpID0+IGNvbW1vbi51SW50MTYwRXF1YWwodmFsdWUuaGFzaCwga2V5Lmhhc2gpLFxuICAgICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZSkgPT4gKHsgdHlwZTogJ2FjY291bnRVbnNwZW50JywgdmFsdWUgfSksXG4gICAgICAgIGNyZWF0ZURlbGV0ZUNoYW5nZTogKGtleSkgPT4gKHsgdHlwZTogJ2FjY291bnRVbnNwZW50Jywga2V5IH0pLFxuICAgICAgfSksXG4gICAgICBhY2NvdW50VW5jbGFpbWVkOiBuZXcgUmVhZEdldEFsbEFkZERlbGV0ZVN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICdhY2NvdW50VW5jbGFpbWVkJyxcbiAgICAgICAgcmVhZEdldEFsbFN0b3JhZ2U6ICgpID0+IHRoaXMuc3RvcmFnZS5hY2NvdW50VW5jbGFpbWVkLFxuICAgICAgICBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZSkgPT4gKHsgaGFzaDogdmFsdWUuaGFzaCwgaW5wdXQ6IHZhbHVlLmlucHV0IH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+XG4gICAgICAgICAgYCR7Y29tbW9uLnVJbnQxNjBUb1N0cmluZyhrZXkuaGFzaCl9OiR7Y29tbW9uLnVJbnQyNTZUb1N0cmluZyhrZXkuaW5wdXQuaGFzaCl9OiR7a2V5LmlucHV0LmluZGV4fWAsXG4gICAgICAgIG1hdGNoZXNQYXJ0aWFsS2V5OiAodmFsdWUsIGtleSkgPT4gY29tbW9uLnVJbnQxNjBFcXVhbCh2YWx1ZS5oYXNoLCBrZXkuaGFzaCksXG4gICAgICAgIGNyZWF0ZUFkZENoYW5nZTogKHZhbHVlKSA9PiAoeyB0eXBlOiAnYWNjb3VudFVuY2xhaW1lZCcsIHZhbHVlIH0pLFxuICAgICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IChrZXkpID0+ICh7IHR5cGU6ICdhY2NvdW50VW5jbGFpbWVkJywga2V5IH0pLFxuICAgICAgfSksXG4gICAgICBhY3Rpb246IG5ldyBSZWFkR2V0QWxsQWRkU3RvcmFnZUNhY2hlKHtcbiAgICAgICAgbmFtZTogJ2FjdGlvbicsXG4gICAgICAgIHJlYWRHZXRBbGxTdG9yYWdlOiAoKSA9PiB0aGlzLnN0b3JhZ2UuYWN0aW9uLFxuICAgICAgICBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZSkgPT4gKHtcbiAgICAgICAgICBpbmRleDogdmFsdWUuaW5kZXgsXG4gICAgICAgIH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGtleS5pbmRleC50b1N0cmluZygxMCksXG4gICAgICAgIG1hdGNoZXNQYXJ0aWFsS2V5OiAodmFsdWUsIGtleSkgPT5cbiAgICAgICAgICAoa2V5LmluZGV4U3RhcnQgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZS5pbmRleC5ndGUoa2V5LmluZGV4U3RhcnQpKSAmJlxuICAgICAgICAgIChrZXkuaW5kZXhTdG9wID09PSB1bmRlZmluZWQgfHwgdmFsdWUuaW5kZXgubHRlKGtleS5pbmRleFN0b3ApKSxcbiAgICAgICAgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWUpID0+ICh7IHR5cGU6ICdhY3Rpb24nLCB2YWx1ZSB9KSxcbiAgICAgIH0pLFxuICAgICAgYXNzZXQ6IG5ldyBSZWFkQWRkVXBkYXRlU3RvcmFnZUNhY2hlKHtcbiAgICAgICAgbmFtZTogJ2Fzc2V0JyxcbiAgICAgICAgcmVhZFN0b3JhZ2U6ICgpID0+IHRoaXMuc3RvcmFnZS5hc3NldCxcbiAgICAgICAgdXBkYXRlOiAodmFsdWUsIHVwZGF0ZSkgPT4gdmFsdWUudXBkYXRlKHVwZGF0ZSksXG4gICAgICAgIGdldEtleUZyb21WYWx1ZTogKHZhbHVlKSA9PiAoeyBoYXNoOiB2YWx1ZS5oYXNoIH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGNvbW1vbi51SW50MjU2VG9TdHJpbmcoa2V5Lmhhc2gpLFxuICAgICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZSkgPT4gKHsgdHlwZTogJ2Fzc2V0JywgdmFsdWUgfSksXG4gICAgICB9KSxcbiAgICAgIGJsb2NrOiBuZXcgQmxvY2tMaWtlU3RvcmFnZUNhY2hlKHtcbiAgICAgICAgbmFtZTogJ2Jsb2NrJyxcbiAgICAgICAgcmVhZFN0b3JhZ2U6ICgpID0+ICh7XG4gICAgICAgICAgZ2V0OiB0aGlzLnN0b3JhZ2UuYmxvY2suZ2V0LFxuICAgICAgICAgIHRyeUdldDogdGhpcy5zdG9yYWdlLmJsb2NrLnRyeUdldCxcbiAgICAgICAgfSksXG4gICAgICAgIGNyZWF0ZUFkZENoYW5nZTogKHZhbHVlKSA9PiAoeyB0eXBlOiAnYmxvY2snLCB2YWx1ZSB9KSxcbiAgICAgIH0pLFxuICAgICAgYmxvY2tEYXRhOiBuZXcgUmVhZEFkZFN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICdibG9ja0RhdGEnLFxuICAgICAgICByZWFkU3RvcmFnZTogKCkgPT4gdGhpcy5zdG9yYWdlLmJsb2NrRGF0YSxcbiAgICAgICAgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWUpID0+ICh7IGhhc2g6IHZhbHVlLmhhc2ggfSksXG4gICAgICAgIGdldEtleVN0cmluZzogKGtleSkgPT4gY29tbW9uLnVJbnQyNTZUb1N0cmluZyhrZXkuaGFzaCksXG4gICAgICAgIGNyZWF0ZUFkZENoYW5nZTogKHZhbHVlKSA9PiAoeyB0eXBlOiAnYmxvY2tEYXRhJywgdmFsdWUgfSksXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjogbmV3IEJsb2NrTGlrZVN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICdoZWFkZXInLFxuICAgICAgICByZWFkU3RvcmFnZTogKCkgPT4gKHtcbiAgICAgICAgICBnZXQ6IHRoaXMuc3RvcmFnZS5oZWFkZXIuZ2V0LFxuICAgICAgICAgIHRyeUdldDogdGhpcy5zdG9yYWdlLmhlYWRlci50cnlHZXQsXG4gICAgICAgIH0pLFxuICAgICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZSkgPT4gKHsgdHlwZTogJ2hlYWRlcicsIHZhbHVlIH0pLFxuICAgICAgfSksXG4gICAgICB0cmFuc2FjdGlvbjogbmV3IFJlYWRBZGRTdG9yYWdlQ2FjaGUoe1xuICAgICAgICBuYW1lOiAndHJhbnNhY3Rpb24nLFxuICAgICAgICByZWFkU3RvcmFnZTogKCkgPT4gdGhpcy5zdG9yYWdlLnRyYW5zYWN0aW9uLFxuICAgICAgICBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZSkgPT4gKHsgaGFzaDogdmFsdWUuaGFzaCB9KSxcbiAgICAgICAgZ2V0S2V5U3RyaW5nOiAoa2V5KSA9PiBjb21tb24udUludDI1NlRvU3RyaW5nKGtleS5oYXNoKSxcbiAgICAgICAgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWUpID0+ICh7IHR5cGU6ICd0cmFuc2FjdGlvbicsIHZhbHVlIH0pLFxuICAgICAgICBvbkFkZDogYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICB2YWx1ZS5vdXRwdXRzLm1hcChhc3luYyAob3V0LCBpbmRleCkgPT4gb3V0cHV0LmFkZCh7IGhhc2g6IHZhbHVlLmhhc2gsIGluZGV4LCBvdXRwdXQ6IG91dCB9KSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgYWxsb3dEdXBlczogdHJ1ZSxcbiAgICAgIH0pLFxuICAgICAgdHJhbnNhY3Rpb25EYXRhOiBuZXcgUmVhZEFkZFVwZGF0ZVN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICd0cmFuc2FjdGlvbkRhdGEnLFxuICAgICAgICByZWFkU3RvcmFnZTogKCkgPT4gdGhpcy5zdG9yYWdlLnRyYW5zYWN0aW9uRGF0YSxcbiAgICAgICAgdXBkYXRlOiAodmFsdWUsIHVwZGF0ZSkgPT4gdmFsdWUudXBkYXRlKHVwZGF0ZSksXG4gICAgICAgIGdldEtleUZyb21WYWx1ZTogKHZhbHVlKSA9PiAoeyBoYXNoOiB2YWx1ZS5oYXNoIH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGNvbW1vbi51SW50MjU2VG9TdHJpbmcoa2V5Lmhhc2gpLFxuICAgICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZSkgPT4gKHsgdHlwZTogJ3RyYW5zYWN0aW9uRGF0YScsIHZhbHVlIH0pLFxuICAgICAgICBhbGxvd0R1cGVzOiB0cnVlLFxuICAgICAgfSksXG4gICAgICBvdXRwdXQsXG4gICAgICBjb250cmFjdDogbmV3IFJlYWRBZGREZWxldGVTdG9yYWdlQ2FjaGUoe1xuICAgICAgICBuYW1lOiAnY29udHJhY3QnLFxuICAgICAgICByZWFkU3RvcmFnZTogKCkgPT4gdGhpcy5zdG9yYWdlLmNvbnRyYWN0LFxuICAgICAgICBnZXRLZXlGcm9tVmFsdWU6ICh2YWx1ZSkgPT4gKHsgaGFzaDogdmFsdWUuaGFzaCB9KSxcbiAgICAgICAgZ2V0S2V5U3RyaW5nOiAoa2V5KSA9PiBjb21tb24udUludDE2MFRvU3RyaW5nKGtleS5oYXNoKSxcbiAgICAgICAgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWUpID0+ICh7IHR5cGU6ICdjb250cmFjdCcsIHZhbHVlIH0pLFxuICAgICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IChrZXkpID0+ICh7IHR5cGU6ICdjb250cmFjdCcsIGtleSB9KSxcbiAgICAgIH0pLFxuICAgICAgc3RvcmFnZUl0ZW06IG5ldyBSZWFkR2V0QWxsQWRkVXBkYXRlRGVsZXRlU3RvcmFnZUNhY2hlKHtcbiAgICAgICAgbmFtZTogJ3N0b3JhZ2VJdGVtJyxcbiAgICAgICAgcmVhZEdldEFsbFN0b3JhZ2U6ICgpID0+IHRoaXMuc3RvcmFnZS5zdG9yYWdlSXRlbSxcbiAgICAgICAgdXBkYXRlOiAodmFsdWUsIHVwZGF0ZSkgPT4gdmFsdWUudXBkYXRlKHVwZGF0ZSksXG4gICAgICAgIGdldEtleUZyb21WYWx1ZTogKHZhbHVlKSA9PiAoe1xuICAgICAgICAgIGhhc2g6IHZhbHVlLmhhc2gsXG4gICAgICAgICAga2V5OiB2YWx1ZS5rZXksXG4gICAgICAgIH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGAke2NvbW1vbi51SW50MTYwVG9TdHJpbmcoa2V5Lmhhc2gpfToke2tleS5rZXkudG9TdHJpbmcoJ2hleCcpfWAsXG4gICAgICAgIG1hdGNoZXNQYXJ0aWFsS2V5OiAodmFsdWUsIGtleSkgPT5cbiAgICAgICAgICAoa2V5Lmhhc2ggPT09IHVuZGVmaW5lZCB8fCBjb21tb24udUludDE2MEVxdWFsKHZhbHVlLmhhc2gsIGtleS5oYXNoKSkgJiZcbiAgICAgICAgICAoa2V5LnByZWZpeCA9PT0gdW5kZWZpbmVkIHx8IGtleS5wcmVmaXguZXZlcnkoKGJ5dGUsIGlkeCkgPT4gdmFsdWUua2V5W2lkeF0gPT09IGJ5dGUpKSxcbiAgICAgICAgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWUpID0+ICh7IHR5cGU6ICdzdG9yYWdlSXRlbScsIHZhbHVlIH0pLFxuICAgICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IChrZXkpID0+ICh7IHR5cGU6ICdzdG9yYWdlSXRlbScsIGtleSB9KSxcbiAgICAgIH0pLFxuICAgICAgdmFsaWRhdG9yOiBuZXcgUmVhZEFsbEFkZFVwZGF0ZURlbGV0ZVN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICd2YWxpZGF0b3InLFxuICAgICAgICByZWFkQWxsU3RvcmFnZTogKCkgPT4gdGhpcy5zdG9yYWdlLnZhbGlkYXRvcixcbiAgICAgICAgZ2V0S2V5RnJvbVZhbHVlOiAodmFsdWUpID0+ICh7IHB1YmxpY0tleTogdmFsdWUucHVibGljS2V5IH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGNvbW1vbi5lY1BvaW50VG9TdHJpbmcoa2V5LnB1YmxpY0tleSksXG4gICAgICAgIGNyZWF0ZUFkZENoYW5nZTogKHZhbHVlKSA9PiAoeyB0eXBlOiAndmFsaWRhdG9yJywgdmFsdWUgfSksXG4gICAgICAgIHVwZGF0ZTogKHZhbHVlLCB1cGRhdGUpID0+IHZhbHVlLnVwZGF0ZSh1cGRhdGUpLFxuICAgICAgICBjcmVhdGVEZWxldGVDaGFuZ2U6IChrZXkpID0+ICh7IHR5cGU6ICd2YWxpZGF0b3InLCBrZXkgfSksXG4gICAgICB9KSxcbiAgICAgIGludm9jYXRpb25EYXRhOiBuZXcgUmVhZEFkZFN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICdpbnZvY2F0aW9uRGF0YScsXG4gICAgICAgIHJlYWRTdG9yYWdlOiAoKSA9PiB0aGlzLnN0b3JhZ2UuaW52b2NhdGlvbkRhdGEsXG4gICAgICAgIGdldEtleUZyb21WYWx1ZTogKHZhbHVlKSA9PiAoeyBoYXNoOiB2YWx1ZS5oYXNoIH0pLFxuICAgICAgICBnZXRLZXlTdHJpbmc6IChrZXkpID0+IGNvbW1vbi51SW50MjU2VG9TdHJpbmcoa2V5Lmhhc2gpLFxuICAgICAgICBjcmVhdGVBZGRDaGFuZ2U6ICh2YWx1ZSkgPT4gKHsgdHlwZTogJ2ludm9jYXRpb25EYXRhJywgdmFsdWUgfSksXG4gICAgICB9KSxcbiAgICAgIHZhbGlkYXRvcnNDb3VudDogbmV3IFJlYWRBZGRVcGRhdGVNZXRhZGF0YVN0b3JhZ2VDYWNoZSh7XG4gICAgICAgIG5hbWU6ICd2YWxpZGF0b3JzQ291bnQnLFxuICAgICAgICByZWFkU3RvcmFnZTogKCkgPT4gdGhpcy5zdG9yYWdlLnZhbGlkYXRvcnNDb3VudCxcbiAgICAgICAgY3JlYXRlQWRkQ2hhbmdlOiAodmFsdWUpID0+ICh7IHR5cGU6ICd2YWxpZGF0b3JzQ291bnQnLCB2YWx1ZSB9KSxcbiAgICAgICAgdXBkYXRlOiAodmFsdWUsIHVwZGF0ZSkgPT4gdmFsdWUudXBkYXRlKHVwZGF0ZSksXG4gICAgICB9KSxcbiAgICB9O1xuXG4gICAgdGhpcy5hY2NvdW50ID0gdGhpcy5jYWNoZXMuYWNjb3VudDtcbiAgICB0aGlzLmFjY291bnRVbnNwZW50ID0gdGhpcy5jYWNoZXMuYWNjb3VudFVuc3BlbnQ7XG4gICAgdGhpcy5hY2NvdW50VW5jbGFpbWVkID0gdGhpcy5jYWNoZXMuYWNjb3VudFVuY2xhaW1lZDtcbiAgICB0aGlzLmFjdGlvbiA9IHRoaXMuY2FjaGVzLmFjdGlvbjtcbiAgICB0aGlzLmFzc2V0ID0gdGhpcy5jYWNoZXMuYXNzZXQ7XG4gICAgdGhpcy5ibG9jayA9IHRoaXMuY2FjaGVzLmJsb2NrO1xuICAgIHRoaXMuYmxvY2tEYXRhID0gdGhpcy5jYWNoZXMuYmxvY2tEYXRhO1xuICAgIHRoaXMuaGVhZGVyID0gdGhpcy5jYWNoZXMuaGVhZGVyO1xuICAgIHRoaXMudHJhbnNhY3Rpb24gPSB0aGlzLmNhY2hlcy50cmFuc2FjdGlvbjtcbiAgICB0aGlzLnRyYW5zYWN0aW9uRGF0YSA9IHRoaXMuY2FjaGVzLnRyYW5zYWN0aW9uRGF0YTtcbiAgICB0aGlzLm91dHB1dCA9IHRoaXMuY2FjaGVzLm91dHB1dDtcbiAgICB0aGlzLmNvbnRyYWN0ID0gdGhpcy5jYWNoZXMuY29udHJhY3Q7XG4gICAgdGhpcy5zdG9yYWdlSXRlbSA9IHRoaXMuY2FjaGVzLnN0b3JhZ2VJdGVtO1xuICAgIHRoaXMudmFsaWRhdG9yID0gdGhpcy5jYWNoZXMudmFsaWRhdG9yO1xuICAgIHRoaXMuaW52b2NhdGlvbkRhdGEgPSB0aGlzLmNhY2hlcy5pbnZvY2F0aW9uRGF0YTtcbiAgICB0aGlzLnZhbGlkYXRvcnNDb3VudCA9IHRoaXMuY2FjaGVzLnZhbGlkYXRvcnNDb3VudDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgY3VycmVudEJsb2NrKCk6IEJsb2NrIHtcbiAgICBpZiAodGhpcy5jdXJyZW50QmxvY2tJbnRlcm5hbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgR2VuZXNpc0Jsb2NrTm90UmVnaXN0ZXJlZEVycm9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY3VycmVudEJsb2NrSW50ZXJuYWw7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGN1cnJlbnRCbG9ja0luZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudEJsb2NrSW50ZXJuYWwgPT09IHVuZGVmaW5lZCA/IDAgOiB0aGlzLmN1cnJlbnRCbG9ja0ludGVybmFsLmluZGV4O1xuICB9XG5cbiAgcHVibGljIGdldCBjdXJyZW50SGVhZGVyKCk6IEhlYWRlciB7XG4gICAgaWYgKHRoaXMuY3VycmVudEhlYWRlckludGVybmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBHZW5lc2lzQmxvY2tOb3RSZWdpc3RlcmVkRXJyb3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jdXJyZW50SGVhZGVySW50ZXJuYWw7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2hhbmdlU2V0KCk6IENoYW5nZVNldCB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5jYWNoZXMpLnJlZHVjZTxDaGFuZ2VTZXQ+KChhY2MsIGNhY2hlKSA9PiBhY2MuY29uY2F0KGNhY2hlLmdldENoYW5nZVNldCgpKSwgW10pO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICBwdWJsaWMgZ2V0VHJhY2tlZENoYW5nZVNldCgpOiBUcmFja2VkQ2hhbmdlU2V0PGFueSwgYW55LCBhbnk+IHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5jYWNoZXMpLnJlZHVjZTxUcmFja2VkQ2hhbmdlU2V0PGFueSwgYW55LCBhbnk+PihcbiAgICAgIChhY2MsIGNhY2hlKSA9PiBhY2MuY29uY2F0KGNhY2hlLmdldFRyYWNrZWRDaGFuZ2VTZXQoKSksXG4gICAgICBbXSxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHBlcnNpc3RCbG9jayhibG9jazogQmxvY2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBbbWF5YmVQcmV2QmxvY2tEYXRhLCBvdXRwdXRDb250cmFjdHNMaXN0XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIGJsb2NrLmluZGV4ID09PSAwID8gUHJvbWlzZS5yZXNvbHZlKHVuZGVmaW5lZCkgOiB0aGlzLmJsb2NrRGF0YS5nZXQoeyBoYXNoOiBibG9jay5wcmV2aW91c0hhc2ggfSksXG4gICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgW1xuICAgICAgICAgIC4uLm5ldyBTZXQoXG4gICAgICAgICAgICBibG9jay50cmFuc2FjdGlvbnMucmVkdWNlPHN0cmluZ1tdPihcbiAgICAgICAgICAgICAgKGFjYywgdHJhbnNhY3Rpb24pID0+XG4gICAgICAgICAgICAgICAgYWNjLmNvbmNhdCh0cmFuc2FjdGlvbi5vdXRwdXRzLm1hcCgob3V0cHV0KSA9PiBjb21tb24udUludDE2MFRvU3RyaW5nKG91dHB1dC5hZGRyZXNzKSkpLFxuXG4gICAgICAgICAgICAgIFtdLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICBdLm1hcChhc3luYyAoaGFzaCkgPT4gdGhpcy5jb250cmFjdC50cnlHZXQoeyBoYXNoOiBjb21tb24uc3RyaW5nVG9VSW50MTYwKGhhc2gpIH0pKSxcbiAgICAgICksXG5cbiAgICAgIHRoaXMuYmxvY2suYWRkKGJsb2NrKSxcbiAgICAgIHRoaXMuaGVhZGVyLmFkZChibG9jay5oZWFkZXIpLFxuICAgIF0pO1xuXG4gICAgY29uc3QgcHJldkJsb2NrRGF0YSA9XG4gICAgICBtYXliZVByZXZCbG9ja0RhdGEgPT09IHVuZGVmaW5lZFxuICAgICAgICA/IHtcbiAgICAgICAgICAgIGxhc3RHbG9iYWxUcmFuc2FjdGlvbkluZGV4OiB1dGlscy5ORUdBVElWRV9PTkUsXG4gICAgICAgICAgICBsYXN0R2xvYmFsQWN0aW9uSW5kZXg6IHV0aWxzLk5FR0FUSVZFX09ORSxcbiAgICAgICAgICAgIHN5c3RlbUZlZTogdXRpbHMuWkVSTyxcbiAgICAgICAgICB9XG4gICAgICAgIDoge1xuICAgICAgICAgICAgbGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXg6IG1heWJlUHJldkJsb2NrRGF0YS5sYXN0R2xvYmFsVHJhbnNhY3Rpb25JbmRleCxcbiAgICAgICAgICAgIGxhc3RHbG9iYWxBY3Rpb25JbmRleDogbWF5YmVQcmV2QmxvY2tEYXRhLmxhc3RHbG9iYWxBY3Rpb25JbmRleCxcbiAgICAgICAgICAgIHN5c3RlbUZlZTogbWF5YmVQcmV2QmxvY2tEYXRhLnN5c3RlbUZlZSxcbiAgICAgICAgICB9O1xuXG4gICAgY29uc3Qgb3V0cHV0Q29udHJhY3RzOiB7IFtrZXk6IHN0cmluZ106IENvbnRyYWN0IHwgdW5kZWZpbmVkIH0gPSB7fTtcbiAgICBvdXRwdXRDb250cmFjdHNMaXN0LmZpbHRlcihjb21tb25VdGlscy5ub3ROdWxsKS5mb3JFYWNoKChvdXRwdXRDb250cmFjdCkgPT4ge1xuICAgICAgb3V0cHV0Q29udHJhY3RzW291dHB1dENvbnRyYWN0Lmhhc2hIZXhdID0gb3V0cHV0Q29udHJhY3Q7XG4gICAgfSk7XG5cbiAgICBjb25zdCBbdXR4bywgcmVzdF0gPSBfLnBhcnRpdGlvbihcbiAgICAgIGJsb2NrLnRyYW5zYWN0aW9ucy5tYXA8W251bWJlciwgVHJhbnNhY3Rpb25dPigodHJhbnNhY3Rpb24sIGlkeCkgPT4gW2lkeCwgdHJhbnNhY3Rpb25dKSxcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWRcbiAgICAgIChbaWR4LCB0cmFuc2FjdGlvbl0pID0+XG4gICAgICAgICgodHJhbnNhY3Rpb24udHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLkNsYWltICYmIHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgQ2xhaW1UcmFuc2FjdGlvbikgfHxcbiAgICAgICAgICAodHJhbnNhY3Rpb24udHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0ICYmIHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgQ29udHJhY3RUcmFuc2FjdGlvbikgfHxcbiAgICAgICAgICAodHJhbnNhY3Rpb24udHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLk1pbmVyICYmIHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgTWluZXJUcmFuc2FjdGlvbikpICYmXG4gICAgICAgICF0cmFuc2FjdGlvbi5vdXRwdXRzLnNvbWUoKG91dHB1dCkgPT4gb3V0cHV0Q29udHJhY3RzW2NvbW1vbi51SW50MTYwVG9TdHJpbmcob3V0cHV0LmFkZHJlc3MpXSAhPT0gdW5kZWZpbmVkKSxcbiAgICApO1xuXG4gICAgY29uc3QgW2dsb2JhbEFjdGlvbkluZGV4XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIHJlc3QubGVuZ3RoID4gMFxuICAgICAgICA/IHRoaXMucGVyc2lzdFRyYW5zYWN0aW9ucyhcbiAgICAgICAgICAgIGJsb2NrLFxuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICAgICAgICAgICAgcmVzdCBhcyBhbnksXG4gICAgICAgICAgICBwcmV2QmxvY2tEYXRhLmxhc3RHbG9iYWxUcmFuc2FjdGlvbkluZGV4LFxuICAgICAgICAgICAgcHJldkJsb2NrRGF0YS5sYXN0R2xvYmFsQWN0aW9uSW5kZXgsXG4gICAgICAgICAgKVxuICAgICAgICA6IFByb21pc2UucmVzb2x2ZShwcmV2QmxvY2tEYXRhLmxhc3RHbG9iYWxBY3Rpb25JbmRleCksXG4gICAgICB1dHhvLmxlbmd0aCA+IDBcbiAgICAgICAgPyAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gICAgICAgICAgdGhpcy5wZXJzaXN0VVRYT1RyYW5zYWN0aW9ucyhibG9jaywgdXR4byBhcyBhbnksIHByZXZCbG9ja0RhdGEubGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXgpXG4gICAgICAgIDogUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgXSk7XG5cbiAgICBhd2FpdCB0aGlzLmJsb2NrRGF0YS5hZGQoXG4gICAgICBuZXcgQmxvY2tEYXRhKHtcbiAgICAgICAgaGFzaDogYmxvY2suaGFzaCxcbiAgICAgICAgbGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXg6IHByZXZCbG9ja0RhdGEubGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXguYWRkKG5ldyBCTihibG9jay50cmFuc2FjdGlvbnMubGVuZ3RoKSksXG5cbiAgICAgICAgbGFzdEdsb2JhbEFjdGlvbkluZGV4OiBnbG9iYWxBY3Rpb25JbmRleCxcbiAgICAgICAgc3lzdGVtRmVlOiBwcmV2QmxvY2tEYXRhLnN5c3RlbUZlZS5hZGQoXG4gICAgICAgICAgYmxvY2suZ2V0U3lzdGVtRmVlKHtcbiAgICAgICAgICAgIGdldE91dHB1dDogdGhpcy5vdXRwdXQuZ2V0LFxuICAgICAgICAgICAgZ292ZXJuaW5nVG9rZW46IHRoaXMuc2V0dGluZ3MuZ292ZXJuaW5nVG9rZW4sXG4gICAgICAgICAgICB1dGlsaXR5VG9rZW46IHRoaXMuc2V0dGluZ3MudXRpbGl0eVRva2VuLFxuICAgICAgICAgICAgZmVlczogdGhpcy5zZXR0aW5ncy5mZWVzLFxuICAgICAgICAgICAgcmVnaXN0ZXJWYWxpZGF0b3JGZWU6IHRoaXMuc2V0dGluZ3MucmVnaXN0ZXJWYWxpZGF0b3JGZWUsXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwZXJzaXN0VVRYT1RyYW5zYWN0aW9ucyhcbiAgICBibG9jazogQmxvY2ssXG4gICAgdHJhbnNhY3Rpb25zOiBSZWFkb25seUFycmF5PHJlYWRvbmx5IFtudW1iZXIsIChDb250cmFjdFRyYW5zYWN0aW9uIHwgQ2xhaW1UcmFuc2FjdGlvbiB8IE1pbmVyVHJhbnNhY3Rpb24pXT4sXG4gICAgbGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXg6IEJOLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpbnB1dHMgPSBbXTtcbiAgICBjb25zdCBjbGFpbXMgPSBbXTtcbiAgICBjb25zdCBvdXRwdXRXaXRoSW5wdXRzID0gW107XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZCBuby1sb29wLXN0YXRlbWVudCBuby1kZWFkLXN0b3JlXG4gICAgZm9yIChjb25zdCBpZHhBbmRUcmFuc2FjdGlvbiBvZiB0cmFuc2FjdGlvbnMpIHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gaWR4QW5kVHJhbnNhY3Rpb25bMV07XG4gICAgICBpbnB1dHMucHVzaCguLi50cmFuc2FjdGlvbi5pbnB1dHMpO1xuICAgICAgaWYgKHRyYW5zYWN0aW9uLnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5DbGFpbSAmJiB0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIENsYWltVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgY2xhaW1zLnB1c2goLi4udHJhbnNhY3Rpb24uY2xhaW1zKTtcbiAgICAgIH1cbiAgICAgIG91dHB1dFdpdGhJbnB1dHMucHVzaCguLi50aGlzLmdldE91dHB1dFdpdGhJbnB1dCh0cmFuc2FjdGlvbikpO1xuICAgIH1cbiAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZFxuICAgICAgICB0cmFuc2FjdGlvbnMubWFwKGFzeW5jIChbaWR4LCB0cmFuc2FjdGlvbl0pID0+IHRoaXMudHJhbnNhY3Rpb24uYWRkKHRyYW5zYWN0aW9uKSksXG4gICAgICApLFxuICAgICAgUHJvbWlzZS5hbGwoXG4gICAgICAgIHRyYW5zYWN0aW9ucy5tYXAoYXN5bmMgKFtpZHgsIHRyYW5zYWN0aW9uXSkgPT5cbiAgICAgICAgICB0aGlzLnRyYW5zYWN0aW9uRGF0YS5hZGQoXG4gICAgICAgICAgICBuZXcgVHJhbnNhY3Rpb25EYXRhKHtcbiAgICAgICAgICAgICAgaGFzaDogdHJhbnNhY3Rpb24uaGFzaCxcbiAgICAgICAgICAgICAgc3RhcnRIZWlnaHQ6IGJsb2NrLmluZGV4LFxuICAgICAgICAgICAgICBibG9ja0hhc2g6IGJsb2NrLmhhc2gsXG4gICAgICAgICAgICAgIGluZGV4OiBpZHgsXG4gICAgICAgICAgICAgIGdsb2JhbEluZGV4OiBsYXN0R2xvYmFsVHJhbnNhY3Rpb25JbmRleC5hZGQobmV3IEJOKGlkeCArIDEpKSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICApLFxuXG4gICAgICB0aGlzLnVwZGF0ZUFjY291bnRzKGlucHV0cywgY2xhaW1zLCBvdXRwdXRXaXRoSW5wdXRzKSxcbiAgICAgIHRoaXMudXBkYXRlQ29pbnMoaW5wdXRzLCBjbGFpbXMsIGJsb2NrKSxcbiAgICBdKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGVyc2lzdFRyYW5zYWN0aW9ucyhcbiAgICBibG9jazogQmxvY2ssXG4gICAgdHJhbnNhY3Rpb25zOiBSZWFkb25seUFycmF5PHJlYWRvbmx5IFtudW1iZXIsIFRyYW5zYWN0aW9uXT4sXG4gICAgbGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXg6IEJOLFxuICAgIGxhc3RHbG9iYWxBY3Rpb25JbmRleDogQk4sXG4gICk6IFByb21pc2U8Qk4+IHtcbiAgICBsZXQgZ2xvYmFsQWN0aW9uSW5kZXggPSBsYXN0R2xvYmFsQWN0aW9uSW5kZXguYWRkKHV0aWxzLk9ORSk7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3Atc3RhdGVtZW50XG4gICAgZm9yIChjb25zdCBbaWR4LCB0cmFuc2FjdGlvbl0gb2YgdHJhbnNhY3Rpb25zKSB7XG4gICAgICBnbG9iYWxBY3Rpb25JbmRleCA9IGF3YWl0IHRoaXMucGVyc2lzdFRyYW5zYWN0aW9uKFxuICAgICAgICBibG9jayxcbiAgICAgICAgdHJhbnNhY3Rpb24sXG4gICAgICAgIGlkeCxcbiAgICAgICAgbGFzdEdsb2JhbFRyYW5zYWN0aW9uSW5kZXgsXG4gICAgICAgIGdsb2JhbEFjdGlvbkluZGV4LFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2xvYmFsQWN0aW9uSW5kZXguc3ViKHV0aWxzLk9ORSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBlcnNpc3RUcmFuc2FjdGlvbihcbiAgICBibG9jazogQmxvY2ssXG4gICAgdHJhbnNhY3Rpb25JbjogVHJhbnNhY3Rpb24sXG4gICAgdHJhbnNhY3Rpb25JbmRleDogbnVtYmVyLFxuICAgIGxhc3RHbG9iYWxUcmFuc2FjdGlvbkluZGV4OiBCTixcbiAgICBnbG9iYWxBY3Rpb25JbmRleEluOiBCTixcbiAgKTogUHJvbWlzZTxCTj4ge1xuICAgIGxldCBnbG9iYWxBY3Rpb25JbmRleCA9IGdsb2JhbEFjdGlvbkluZGV4SW47XG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvbkluO1xuICAgIGNvbnN0IGNsYWltcyA9XG4gICAgICB0cmFuc2FjdGlvbi50eXBlID09PSBUcmFuc2FjdGlvblR5cGUuQ2xhaW0gJiYgdHJhbnNhY3Rpb24gaW5zdGFuY2VvZiBDbGFpbVRyYW5zYWN0aW9uID8gdHJhbnNhY3Rpb24uY2xhaW1zIDogW107XG4gICAgbGV0IGFjY291bnRDaGFuZ2VzID0ge307XG4gICAgbGV0IHZhbGlkYXRvckNoYW5nZXMgPSB7fTtcbiAgICBsZXQgdmFsaWRhdG9yc0NvdW50Q2hhbmdlczogVmFsaWRhdG9yc0NvdW50Q2hhbmdlcyA9IFtdO1xuICAgIGlmICh0cmFuc2FjdGlvbi50eXBlID09PSBUcmFuc2FjdGlvblR5cGUuU3RhdGUgJiYgdHJhbnNhY3Rpb24gaW5zdGFuY2VvZiBTdGF0ZVRyYW5zYWN0aW9uKSB7XG4gICAgICAoeyBhY2NvdW50Q2hhbmdlcywgdmFsaWRhdG9yQ2hhbmdlcywgdmFsaWRhdG9yc0NvdW50Q2hhbmdlcyB9ID0gYXdhaXQgZ2V0RGVzY3JpcHRvckNoYW5nZXMoe1xuICAgICAgICB0cmFuc2FjdGlvbnM6IFt0cmFuc2FjdGlvbl0sXG4gICAgICAgIGdldEFjY291bnQ6IGFzeW5jIChoYXNoKSA9PlxuICAgICAgICAgIHRoaXMuYWNjb3VudC50cnlHZXQoeyBoYXNoIH0pLnRoZW4oKGFjY291bnQpID0+IChhY2NvdW50ID09PSB1bmRlZmluZWQgPyBuZXcgQWNjb3VudCh7IGhhc2ggfSkgOiBhY2NvdW50KSksXG5cbiAgICAgICAgZ292ZXJuaW5nVG9rZW5IYXNoOiB0aGlzLnNldHRpbmdzLmdvdmVybmluZ1Rva2VuLmhhc2hIZXgsXG4gICAgICB9KSk7XG4gICAgfVxuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIHRoaXMudHJhbnNhY3Rpb24uYWRkKHRyYW5zYWN0aW9uKSxcbiAgICAgIHRoaXMudHJhbnNhY3Rpb25EYXRhLmFkZChcbiAgICAgICAgbmV3IFRyYW5zYWN0aW9uRGF0YSh7XG4gICAgICAgICAgaGFzaDogdHJhbnNhY3Rpb24uaGFzaCxcbiAgICAgICAgICBibG9ja0hhc2g6IGJsb2NrLmhhc2gsXG4gICAgICAgICAgc3RhcnRIZWlnaHQ6IGJsb2NrLmluZGV4LFxuICAgICAgICAgIGluZGV4OiB0cmFuc2FjdGlvbkluZGV4LFxuICAgICAgICAgIGdsb2JhbEluZGV4OiBsYXN0R2xvYmFsVHJhbnNhY3Rpb25JbmRleC5hZGQobmV3IEJOKHRyYW5zYWN0aW9uSW5kZXggKyAxKSksXG4gICAgICAgIH0pLFxuICAgICAgKSxcblxuICAgICAgdGhpcy51cGRhdGVBY2NvdW50cyh0cmFuc2FjdGlvbi5pbnB1dHMsIGNsYWltcywgdGhpcy5nZXRPdXRwdXRXaXRoSW5wdXQodHJhbnNhY3Rpb24pLCBhY2NvdW50Q2hhbmdlcyksXG5cbiAgICAgIHRoaXMudXBkYXRlQ29pbnModHJhbnNhY3Rpb24uaW5wdXRzLCBjbGFpbXMsIGJsb2NrKSxcbiAgICAgIHRoaXMucHJvY2Vzc1N0YXRlVHJhbnNhY3Rpb24odmFsaWRhdG9yQ2hhbmdlcywgdmFsaWRhdG9yc0NvdW50Q2hhbmdlcyksXG4gICAgXSk7XG5cbiAgICBpZiAodHJhbnNhY3Rpb24udHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLlJlZ2lzdGVyICYmIHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgUmVnaXN0ZXJUcmFuc2FjdGlvbikge1xuICAgICAgYXdhaXQgdGhpcy5hc3NldC5hZGQoXG4gICAgICAgIG5ldyBBc3NldCh7XG4gICAgICAgICAgaGFzaDogdHJhbnNhY3Rpb24uaGFzaCxcbiAgICAgICAgICB0eXBlOiB0cmFuc2FjdGlvbi5hc3NldC50eXBlLFxuICAgICAgICAgIG5hbWU6IHRyYW5zYWN0aW9uLmFzc2V0Lm5hbWUsXG4gICAgICAgICAgYW1vdW50OiB0cmFuc2FjdGlvbi5hc3NldC5hbW91bnQsXG4gICAgICAgICAgcHJlY2lzaW9uOiB0cmFuc2FjdGlvbi5hc3NldC5wcmVjaXNpb24sXG4gICAgICAgICAgb3duZXI6IHRyYW5zYWN0aW9uLmFzc2V0Lm93bmVyLFxuICAgICAgICAgIGFkbWluOiB0cmFuc2FjdGlvbi5hc3NldC5hZG1pbixcbiAgICAgICAgICBpc3N1ZXI6IHRyYW5zYWN0aW9uLmFzc2V0LmFkbWluLFxuICAgICAgICAgIGV4cGlyYXRpb246IHRoaXMuY3VycmVudEJsb2NrSW5kZXggKyAyICogMjAwMDAwMCxcbiAgICAgICAgICBpc0Zyb3plbjogZmFsc2UsXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRyYW5zYWN0aW9uLnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5Jc3N1ZSAmJiB0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIElzc3VlVHJhbnNhY3Rpb24pIHtcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgT2JqZWN0LmVudHJpZXMoXG4gICAgICAgICAgdHJhbnNhY3Rpb24uZ2V0VHJhbnNhY3Rpb25SZXN1bHRzKHtcbiAgICAgICAgICAgIGdldE91dHB1dDogdGhpcy5vdXRwdXQuZ2V0LFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIHJlc3VsdHMubWFwKGFzeW5jIChbYXNzZXRIZXgsIHZhbHVlXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhc2ggPSBjb21tb24uc3RyaW5nVG9VSW50MjU2KGFzc2V0SGV4KTtcbiAgICAgICAgICBjb25zdCBhc3NldCA9IGF3YWl0IHRoaXMuYXNzZXQuZ2V0KHsgaGFzaCB9KTtcbiAgICAgICAgICBhd2FpdCB0aGlzLmFzc2V0LnVwZGF0ZShhc3NldCwge1xuICAgICAgICAgICAgYXZhaWxhYmxlOiBhc3NldC5hdmFpbGFibGUuYWRkKHZhbHVlLm5lZygpKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodHJhbnNhY3Rpb24udHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLkVucm9sbG1lbnQgJiYgdHJhbnNhY3Rpb24gaW5zdGFuY2VvZiBFbnJvbGxtZW50VHJhbnNhY3Rpb24pIHtcbiAgICAgIGF3YWl0IHRoaXMudmFsaWRhdG9yLmFkZChcbiAgICAgICAgbmV3IFZhbGlkYXRvcih7XG4gICAgICAgICAgcHVibGljS2V5OiB0cmFuc2FjdGlvbi5wdWJsaWNLZXksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHRyYW5zYWN0aW9uLnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5QdWJsaXNoICYmIHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgUHVibGlzaFRyYW5zYWN0aW9uKSB7XG4gICAgICBjb25zdCBjb250cmFjdCA9IGF3YWl0IHRoaXMuY29udHJhY3QudHJ5R2V0KHtcbiAgICAgICAgaGFzaDogdHJhbnNhY3Rpb24uY29udHJhY3QuaGFzaCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoY29udHJhY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhd2FpdCB0aGlzLmNvbnRyYWN0LmFkZCh0cmFuc2FjdGlvbi5jb250cmFjdCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0cmFuc2FjdGlvbi50eXBlID09PSBUcmFuc2FjdGlvblR5cGUuSW52b2NhdGlvbiAmJiB0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIEludm9jYXRpb25UcmFuc2FjdGlvbikge1xuICAgICAgY29uc3QgdGVtcG9yYXJ5QmxvY2tjaGFpbiA9IG5ldyBXcml0ZUJhdGNoQmxvY2tjaGFpbih7XG4gICAgICAgIHNldHRpbmdzOiB0aGlzLnNldHRpbmdzLFxuICAgICAgICBjdXJyZW50QmxvY2s6IHRoaXMuY3VycmVudEJsb2NrSW50ZXJuYWwsXG4gICAgICAgIGN1cnJlbnRIZWFkZXI6IHRoaXMuY3VycmVudEhlYWRlcixcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICAgICAgICBzdG9yYWdlOiB0aGlzIGFzIGFueSxcbiAgICAgICAgdm06IHRoaXMudm0sXG4gICAgICAgIGdldFZhbGlkYXRvcnM6IHRoaXMuZ2V0VmFsaWRhdG9ycyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBtaWdyYXRlZENvbnRyYWN0SGFzaGVzOiBBcnJheTxyZWFkb25seSBbVUludDE2MCwgVUludDE2MF0+ID0gW107XG4gICAgICBjb25zdCB2b3RlVXBkYXRlczogQXJyYXk8cmVhZG9ubHkgW1VJbnQxNjAsIFJlYWRvbmx5QXJyYXk8RUNQb2ludD5dPiA9IFtdO1xuICAgICAgY29uc3QgYWN0aW9uczogQXJyYXk8Tm90aWZpY2F0aW9uQWN0aW9uIHwgTG9nQWN0aW9uPiA9IFtdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd3JhcEV4ZWN1dGVTY3JpcHRzKGFzeW5jICgpID0+XG4gICAgICAgIHRoaXMudm0uZXhlY3V0ZVNjcmlwdHMoe1xuICAgICAgICAgIHNjcmlwdHM6IFt7IGNvZGU6IHRyYW5zYWN0aW9uLnNjcmlwdCB9XSxcbiAgICAgICAgICBibG9ja2NoYWluOiB0ZW1wb3JhcnlCbG9ja2NoYWluLFxuICAgICAgICAgIHNjcmlwdENvbnRhaW5lcjoge1xuICAgICAgICAgICAgdHlwZTogU2NyaXB0Q29udGFpbmVyVHlwZS5UcmFuc2FjdGlvbixcbiAgICAgICAgICAgIHZhbHVlOiB0cmFuc2FjdGlvbixcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgdHJpZ2dlclR5cGU6IFRyaWdnZXJUeXBlLkFwcGxpY2F0aW9uLFxuICAgICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgICAgYmxvY2tJbmRleDogYmxvY2suaW5kZXgsXG4gICAgICAgICAgICBibG9ja0hhc2g6IGJsb2NrLmhhc2gsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbkluZGV4LFxuICAgICAgICAgICAgdHJhbnNhY3Rpb25IYXNoOiB0cmFuc2FjdGlvbi5oYXNoLFxuICAgICAgICAgIH0sXG5cbiAgICAgICAgICBnYXM6IHRyYW5zYWN0aW9uLmdhcyxcbiAgICAgICAgICBsaXN0ZW5lcnM6IHtcbiAgICAgICAgICAgIG9uTG9nOiAoeyBtZXNzYWdlLCBzY3JpcHRIYXNoIH0pID0+IHtcbiAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFxuICAgICAgICAgICAgICAgIG5ldyBMb2dBY3Rpb24oe1xuICAgICAgICAgICAgICAgICAgaW5kZXg6IGdsb2JhbEFjdGlvbkluZGV4LFxuICAgICAgICAgICAgICAgICAgc2NyaXB0SGFzaCxcbiAgICAgICAgICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgZ2xvYmFsQWN0aW9uSW5kZXggPSBnbG9iYWxBY3Rpb25JbmRleC5hZGQodXRpbHMuT05FKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvbk5vdGlmeTogKHsgYXJncywgc2NyaXB0SGFzaCB9KSA9PiB7XG4gICAgICAgICAgICAgIGFjdGlvbnMucHVzaChcbiAgICAgICAgICAgICAgICBuZXcgTm90aWZpY2F0aW9uQWN0aW9uKHtcbiAgICAgICAgICAgICAgICAgIGluZGV4OiBnbG9iYWxBY3Rpb25JbmRleCxcbiAgICAgICAgICAgICAgICAgIHNjcmlwdEhhc2gsXG4gICAgICAgICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIGdsb2JhbEFjdGlvbkluZGV4ID0gZ2xvYmFsQWN0aW9uSW5kZXguYWRkKHV0aWxzLk9ORSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25NaWdyYXRlQ29udHJhY3Q6ICh7IGZyb20sIHRvIH0pID0+IHtcbiAgICAgICAgICAgICAgbWlncmF0ZWRDb250cmFjdEhhc2hlcy5wdXNoKFtmcm9tLCB0b10gYXMgY29uc3QpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uU2V0Vm90ZXM6ICh7IGFkZHJlc3MsIHZvdGVzIH0pID0+IHtcbiAgICAgICAgICAgICAgdm90ZVVwZGF0ZXMucHVzaChbYWRkcmVzcywgdm90ZXNdIGFzIGNvbnN0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcblxuICAgICAgICAgIHBlcnNpc3RpbmdCbG9jazogYmxvY2ssXG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgYWRkQWN0aW9uc1Byb21pc2UgPSBQcm9taXNlLmFsbChhY3Rpb25zLm1hcChhc3luYyAoYWN0aW9uKSA9PiB0aGlzLmFjdGlvbi5hZGQoYWN0aW9uKSkpO1xuXG4gICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgSW52b2NhdGlvblJlc3VsdFN1Y2Nlc3MpIHtcbiAgICAgICAgY29uc3QgYXNzZXRDaGFuZ2VTZXQgPSB0ZW1wb3JhcnlCbG9ja2NoYWluLmFzc2V0LmdldENoYW5nZVNldCgpO1xuICAgICAgICBjb25zdCBhc3NldEhhc2ggPSBhc3NldENoYW5nZVNldFxuICAgICAgICAgIC5tYXAoKGNoYW5nZSkgPT5cbiAgICAgICAgICAgIGNoYW5nZS50eXBlID09PSAnYWRkJyAmJiBjaGFuZ2UuY2hhbmdlLnR5cGUgPT09ICdhc3NldCcgPyBjaGFuZ2UuY2hhbmdlLnZhbHVlLmhhc2ggOiB1bmRlZmluZWQsXG4gICAgICAgICAgKVxuICAgICAgICAgIC5maW5kKCh2YWx1ZSkgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCk7XG5cbiAgICAgICAgY29uc3QgY29udHJhY3RzQ2hhbmdlU2V0ID0gdGVtcG9yYXJ5QmxvY2tjaGFpbi5jb250cmFjdC5nZXRDaGFuZ2VTZXQoKTtcbiAgICAgICAgY29uc3QgY29udHJhY3RIYXNoZXMgPSBjb250cmFjdHNDaGFuZ2VTZXRcbiAgICAgICAgICAubWFwKChjaGFuZ2UpID0+XG4gICAgICAgICAgICBjaGFuZ2UudHlwZSA9PT0gJ2FkZCcgJiYgY2hhbmdlLmNoYW5nZS50eXBlID09PSAnY29udHJhY3QnID8gY2hhbmdlLmNoYW5nZS52YWx1ZS5oYXNoIDogdW5kZWZpbmVkLFxuICAgICAgICAgIClcbiAgICAgICAgICAuZmlsdGVyKGNvbW1vblV0aWxzLm5vdE51bGwpO1xuXG4gICAgICAgIGNvbnN0IGRlbGV0ZWRDb250cmFjdEhhc2hlcyA9IGNvbnRyYWN0c0NoYW5nZVNldFxuICAgICAgICAgIC5tYXAoKGNoYW5nZSkgPT5cbiAgICAgICAgICAgIGNoYW5nZS50eXBlID09PSAnZGVsZXRlJyAmJiBjaGFuZ2UuY2hhbmdlLnR5cGUgPT09ICdjb250cmFjdCcgPyBjaGFuZ2UuY2hhbmdlLmtleS5oYXNoIDogdW5kZWZpbmVkLFxuICAgICAgICAgIClcbiAgICAgICAgICAuZmlsdGVyKGNvbW1vblV0aWxzLm5vdE51bGwpO1xuXG4gICAgICAgIGNvbnN0IHN0b3JhZ2VDaGFuZ2VzID0gdGVtcG9yYXJ5QmxvY2tjaGFpbi5zdG9yYWdlSXRlbVxuICAgICAgICAgIC5nZXRDaGFuZ2VTZXQoKVxuICAgICAgICAgIC5tYXAoKGNoYW5nZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWRkQ2hhbmdlID1cbiAgICAgICAgICAgICAgY2hhbmdlLnR5cGUgPT09ICdhZGQnICYmIGNoYW5nZS5jaGFuZ2UudHlwZSA9PT0gJ3N0b3JhZ2VJdGVtJ1xuICAgICAgICAgICAgICAgID8geyB2YWx1ZTogY2hhbmdlLmNoYW5nZS52YWx1ZSwgc3ViVHlwZTogY2hhbmdlLnN1YlR5cGUgfVxuICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKGFkZENoYW5nZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgaGFzaDogYWRkQ2hhbmdlLnZhbHVlLmhhc2gsXG4gICAgICAgICAgICAgICAga2V5OiBhZGRDaGFuZ2UudmFsdWUua2V5LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBhZGRDaGFuZ2UudmFsdWUudmFsdWUsXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgcmV0dXJuIGFkZENoYW5nZS5zdWJUeXBlID09PSAnYWRkJyA/IG5ldyBTdG9yYWdlQ2hhbmdlQWRkKG9wdGlvbnMpIDogbmV3IFN0b3JhZ2VDaGFuZ2VNb2RpZnkob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGRlbGV0ZUNoYW5nZSA9XG4gICAgICAgICAgICAgIGNoYW5nZS50eXBlID09PSAnZGVsZXRlJyAmJiBjaGFuZ2UuY2hhbmdlLnR5cGUgPT09ICdzdG9yYWdlSXRlbScgPyBjaGFuZ2UuY2hhbmdlLmtleSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChkZWxldGVDaGFuZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0b3JhZ2VDaGFuZ2VEZWxldGUoZGVsZXRlQ2hhbmdlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoY29tbW9uVXRpbHMubm90TnVsbCk7XG5cbiAgICAgICAgdGVtcG9yYXJ5QmxvY2tjaGFpbi5nZXRUcmFja2VkQ2hhbmdlU2V0KCkuZm9yRWFjaCgoY2hhbmdlKSA9PiB7XG4gICAgICAgICAgdGhpcy5jYWNoZXNbY2hhbmdlLnR5cGUgYXMga2V5b2YgQ2FjaGVzXS5hZGRUcmFja2VkQ2hhbmdlKGNoYW5nZS5rZXksIGNoYW5nZS52YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgdGhpcy5pbnZvY2F0aW9uRGF0YS5hZGQoXG4gICAgICAgICAgICBuZXcgSW52b2NhdGlvbkRhdGEoe1xuICAgICAgICAgICAgICBoYXNoOiB0cmFuc2FjdGlvbi5oYXNoLFxuICAgICAgICAgICAgICBhc3NldEhhc2gsXG4gICAgICAgICAgICAgIGNvbnRyYWN0SGFzaGVzLFxuICAgICAgICAgICAgICBkZWxldGVkQ29udHJhY3RIYXNoZXMsXG4gICAgICAgICAgICAgIG1pZ3JhdGVkQ29udHJhY3RIYXNoZXMsXG4gICAgICAgICAgICAgIHZvdGVVcGRhdGVzLFxuICAgICAgICAgICAgICBibG9ja0luZGV4OiBibG9jay5pbmRleCxcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb25JbmRleCxcbiAgICAgICAgICAgICAgYWN0aW9uSW5kZXhTdGFydDogZ2xvYmFsQWN0aW9uSW5kZXhJbixcbiAgICAgICAgICAgICAgYWN0aW9uSW5kZXhTdG9wOiBnbG9iYWxBY3Rpb25JbmRleCxcbiAgICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgICBzdG9yYWdlQ2hhbmdlcyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICAgYWRkQWN0aW9uc1Byb21pc2UsXG4gICAgICAgIF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgIHRoaXMuaW52b2NhdGlvbkRhdGEuYWRkKFxuICAgICAgICAgICAgbmV3IEludm9jYXRpb25EYXRhKHtcbiAgICAgICAgICAgICAgaGFzaDogdHJhbnNhY3Rpb24uaGFzaCxcbiAgICAgICAgICAgICAgYXNzZXRIYXNoOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbnRyYWN0SGFzaGVzOiBbXSxcbiAgICAgICAgICAgICAgZGVsZXRlZENvbnRyYWN0SGFzaGVzOiBbXSxcbiAgICAgICAgICAgICAgbWlncmF0ZWRDb250cmFjdEhhc2hlczogW10sXG4gICAgICAgICAgICAgIHZvdGVVcGRhdGVzOiBbXSxcbiAgICAgICAgICAgICAgYmxvY2tJbmRleDogYmxvY2suaW5kZXgsXG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uSW5kZXgsXG4gICAgICAgICAgICAgIGFjdGlvbkluZGV4U3RhcnQ6IGdsb2JhbEFjdGlvbkluZGV4SW4sXG4gICAgICAgICAgICAgIGFjdGlvbkluZGV4U3RvcDogZ2xvYmFsQWN0aW9uSW5kZXgsXG4gICAgICAgICAgICAgIHJlc3VsdCxcbiAgICAgICAgICAgICAgc3RvcmFnZUNoYW5nZXM6IFtdLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgICBhZGRBY3Rpb25zUHJvbWlzZSxcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGdsb2JhbEFjdGlvbkluZGV4O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzU3RhdGVUcmFuc2FjdGlvbihcbiAgICB2YWxpZGF0b3JDaGFuZ2VzOiBWYWxpZGF0b3JDaGFuZ2VzLFxuICAgIHZhbGlkYXRvcnNDb3VudENoYW5nZXM6IFZhbGlkYXRvcnNDb3VudENoYW5nZXMsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHZhbGlkYXRvcnNDb3VudCA9IGF3YWl0IHRoaXMudmFsaWRhdG9yc0NvdW50LnRyeUdldCgpO1xuICAgIGNvbnN0IHZhbGlkYXRvcnNDb3VudFZvdGVzID0gdmFsaWRhdG9yc0NvdW50ID09PSB1bmRlZmluZWQgPyBbXSA6IFsuLi52YWxpZGF0b3JzQ291bnQudm90ZXNdO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1sb29wLXN0YXRlbWVudFxuICAgIGZvciAoY29uc3QgW2luZGV4LCB2YWx1ZV0gb2YgdmFsaWRhdG9yc0NvdW50Q2hhbmdlcy5lbnRyaWVzKCkpIHtcbiAgICAgIHZhbGlkYXRvcnNDb3VudFZvdGVzW2luZGV4XSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIFByb21pc2UuYWxsKFxuICAgICAgICBPYmplY3QuZW50cmllcyh2YWxpZGF0b3JDaGFuZ2VzKS5tYXAoYXN5bmMgKFtwdWJsaWNLZXlIZXgsIHsgcmVnaXN0ZXJlZCwgdm90ZXMgfV0pID0+IHtcbiAgICAgICAgICBjb25zdCBwdWJsaWNLZXkgPSBjb21tb24uaGV4VG9FQ1BvaW50KHB1YmxpY0tleUhleCk7XG4gICAgICAgICAgY29uc3QgdmFsaWRhdG9yID0gYXdhaXQgdGhpcy52YWxpZGF0b3IudHJ5R2V0KHsgcHVibGljS2V5IH0pO1xuICAgICAgICAgIGlmICh2YWxpZGF0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy52YWxpZGF0b3IuYWRkKFxuICAgICAgICAgICAgICBuZXcgVmFsaWRhdG9yKHtcbiAgICAgICAgICAgICAgICBwdWJsaWNLZXksXG4gICAgICAgICAgICAgICAgcmVnaXN0ZXJlZCxcbiAgICAgICAgICAgICAgICB2b3RlcyxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAoKHJlZ2lzdGVyZWQgIT09IHVuZGVmaW5lZCAmJiAhcmVnaXN0ZXJlZCkgfHwgKHJlZ2lzdGVyZWQgPT09IHVuZGVmaW5lZCAmJiAhdmFsaWRhdG9yLnJlZ2lzdGVyZWQpKSAmJlxuICAgICAgICAgICAgKCh2b3RlcyAhPT0gdW5kZWZpbmVkICYmIHZvdGVzLmVxKHV0aWxzLlpFUk8pKSB8fCAodm90ZXMgPT09IHVuZGVmaW5lZCAmJiB2YWxpZGF0b3Iudm90ZXMuZXEodXRpbHMuWkVSTykpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy52YWxpZGF0b3IuZGVsZXRlKHsgcHVibGljS2V5OiB2YWxpZGF0b3IucHVibGljS2V5IH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnZhbGlkYXRvci51cGRhdGUodmFsaWRhdG9yLCB7IHZvdGVzLCByZWdpc3RlcmVkIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICApLFxuICAgICAgdmFsaWRhdG9yc0NvdW50ID09PSB1bmRlZmluZWRcbiAgICAgICAgPyB0aGlzLnZhbGlkYXRvcnNDb3VudC5hZGQoXG4gICAgICAgICAgICBuZXcgVmFsaWRhdG9yc0NvdW50KHtcbiAgICAgICAgICAgICAgdm90ZXM6IHZhbGlkYXRvcnNDb3VudFZvdGVzLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKVxuICAgICAgICA6IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnZhbGlkYXRvcnNDb3VudC51cGRhdGUodmFsaWRhdG9yc0NvdW50LCB7XG4gICAgICAgICAgICAgIHZvdGVzOiB2YWxpZGF0b3JzQ291bnRWb3RlcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pKCksXG4gICAgXSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUFjY291bnRzKFxuICAgIGlucHV0czogcmVhZG9ubHkgSW5wdXRbXSxcbiAgICBjbGFpbXM6IHJlYWRvbmx5IElucHV0W10sXG4gICAgb3V0cHV0czogcmVhZG9ubHkgT3V0cHV0V2l0aElucHV0W10sXG4gICAgYWNjb3VudENoYW5nZXM6IEFjY291bnRDaGFuZ2VzID0ge30sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IFtpbnB1dE91dHB1dHMsIGNsYWltT3V0cHV0c10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLmdldElucHV0T3V0cHV0cyhpbnB1dHMpLFxuICAgICAgdGhpcy5nZXRJbnB1dE91dHB1dHMoY2xhaW1zKSxcbiAgICBdKTtcblxuICAgIGNvbnN0IGFkZHJlc3NWYWx1ZXMgPSBPYmplY3QuZW50cmllcyhcbiAgICAgIF8uZ3JvdXBCeShcbiAgICAgICAgaW5wdXRPdXRwdXRzXG4gICAgICAgICAgLm1hcDxbVUludDE2MCwgVUludDI1NiwgQk5dPigoeyBvdXRwdXQgfSkgPT4gW291dHB1dC5hZGRyZXNzLCBvdXRwdXQuYXNzZXQsIG91dHB1dC52YWx1ZS5uZWcoKV0pXG4gICAgICAgICAgLmNvbmNhdChvdXRwdXRzLm1hcDxbVUludDE2MCwgVUludDI1NiwgQk5dPigoeyBvdXRwdXQgfSkgPT4gW291dHB1dC5hZGRyZXNzLCBvdXRwdXQuYXNzZXQsIG91dHB1dC52YWx1ZV0pKSxcbiAgICAgICAgKFthZGRyZXNzXSkgPT4gY29tbW9uLnVJbnQxNjBUb0hleChhZGRyZXNzKSxcbiAgICAgICksXG4gICAgKTtcblxuICAgIGNvbnN0IGFkZHJlc3NTcGVudCA9IHRoaXMuZ3JvdXBCeUFkZHJlc3MoaW5wdXRPdXRwdXRzKTtcbiAgICBjb25zdCBhZGRyZXNzQ2xhaW1lZCA9IF8ubWFwVmFsdWVzKHRoaXMuZ3JvdXBCeUFkZHJlc3MoY2xhaW1PdXRwdXRzKSwgKHZhbHVlcykgPT4gdmFsdWVzLm1hcCgoeyBpbnB1dCB9KSA9PiBpbnB1dCkpO1xuXG4gICAgY29uc3QgYWRkcmVzc091dHB1dHMgPSBfLmdyb3VwQnkob3V0cHV0cywgKG91dHB1dCkgPT4gY29tbW9uLnVJbnQxNjBUb0hleChvdXRwdXQub3V0cHV0LmFkZHJlc3MpKTtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYWRkcmVzc1ZhbHVlcy5tYXAoYXN5bmMgKFthZGRyZXNzLCB2YWx1ZXNdKSA9PiB7XG4gICAgICAgIGNvbnN0IHNwZW50ID0gYWRkcmVzc1NwZW50W2FkZHJlc3NdIGFzIHJlYWRvbmx5IE91dHB1dFdpdGhJbnB1dFtdIHwgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBjbGFpbWVkID0gYWRkcmVzc0NsYWltZWRbYWRkcmVzc10gYXMgcmVhZG9ubHkgSW5wdXRbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgb3V0cyA9IGFkZHJlc3NPdXRwdXRzW2FkZHJlc3NdIGFzIHJlYWRvbmx5IE91dHB1dFdpdGhJbnB1dFtdIHwgdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBjaGFuZ2VzID0gYWNjb3VudENoYW5nZXNbYWRkcmVzc10gYXMgcmVhZG9ubHkgRUNQb2ludFtdIHwgdW5kZWZpbmVkO1xuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZUFjY291bnQoXG4gICAgICAgICAgY29tbW9uLmhleFRvVUludDE2MChhZGRyZXNzKSxcbiAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkXG4gICAgICAgICAgdmFsdWVzLm1hcDxyZWFkb25seSBbVUludDI1NiwgQk5dPigoW19hZGRyZXNzLCBhc3NldCwgdmFsdWVdKSA9PiBbYXNzZXQsIHZhbHVlXSBhcyBjb25zdCksXG4gICAgICAgICAgc3BlbnQgPT09IHVuZGVmaW5lZCA/IFtdIDogc3BlbnQsXG4gICAgICAgICAgY2xhaW1lZCA9PT0gdW5kZWZpbmVkID8gW10gOiBjbGFpbWVkLFxuICAgICAgICAgIG91dHMgPT09IHVuZGVmaW5lZCA/IFtdIDogb3V0cyxcbiAgICAgICAgICBjaGFuZ2VzID09PSB1bmRlZmluZWQgPyBbXSA6IGNoYW5nZXMsXG4gICAgICAgICk7XG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRPdXRwdXRXaXRoSW5wdXQodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKTogcmVhZG9ubHkgT3V0cHV0V2l0aElucHV0W10ge1xuICAgIHJldHVybiB0cmFuc2FjdGlvbi5vdXRwdXRzLm1hcCgob3V0cHV0LCBpbmRleCkgPT4gKHtcbiAgICAgIG91dHB1dCxcbiAgICAgIGlucHV0OiBuZXcgSW5wdXQoeyBoYXNoOiB0cmFuc2FjdGlvbi5oYXNoLCBpbmRleCB9KSxcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldElucHV0T3V0cHV0cyhcbiAgICBpbnB1dHM6IHJlYWRvbmx5IElucHV0W10sXG4gICk6IFByb21pc2U8XG4gICAgUmVhZG9ubHlBcnJheTx7XG4gICAgICByZWFkb25seSBpbnB1dDogSW5wdXQ7XG4gICAgICByZWFkb25seSBvdXRwdXQ6IE91dHB1dDtcbiAgICB9PlxuICA+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICBpbnB1dHMubWFwKGFzeW5jIChpbnB1dCkgPT4ge1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBhd2FpdCB0aGlzLm91dHB1dC5nZXQoaW5wdXQpO1xuXG4gICAgICAgIHJldHVybiB7IGlucHV0LCBvdXRwdXQgfTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGdyb3VwQnlBZGRyZXNzKFxuICAgIGlucHV0T3V0cHV0czogcmVhZG9ubHkgT3V0cHV0V2l0aElucHV0W10sXG4gICk6IHsgcmVhZG9ubHkgW2tleTogc3RyaW5nXTogcmVhZG9ubHkgT3V0cHV0V2l0aElucHV0W10gfSB7XG4gICAgcmV0dXJuIF8uZ3JvdXBCeShpbnB1dE91dHB1dHMsICh7IG91dHB1dCB9KSA9PiBjb21tb24udUludDE2MFRvSGV4KG91dHB1dC5hZGRyZXNzKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZUFjY291bnQoXG4gICAgYWRkcmVzczogVUludDE2MCxcbiAgICB2YWx1ZXM6IFJlYWRvbmx5QXJyYXk8cmVhZG9ubHkgW1VJbnQyNTYsIEJOXT4sXG4gICAgc3BlbnQ6IHJlYWRvbmx5IE91dHB1dFdpdGhJbnB1dFtdLFxuICAgIGNsYWltZWQ6IHJlYWRvbmx5IElucHV0W10sXG4gICAgb3V0cHV0czogcmVhZG9ubHkgT3V0cHV0V2l0aElucHV0W10sXG4gICAgdm90ZXM6IHJlYWRvbmx5IEVDUG9pbnRbXSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYWNjb3VudCA9IGF3YWl0IHRoaXMuYWNjb3VudC50cnlHZXQoeyBoYXNoOiBhZGRyZXNzIH0pO1xuXG4gICAgY29uc3QgYmFsYW5jZXMgPSB2YWx1ZXMucmVkdWNlPHsgW2Fzc2V0OiBzdHJpbmddOiBCTiB9PihcbiAgICAgIChhY2MsIFthc3NldCwgdmFsdWVdKSA9PiB7XG4gICAgICAgIGNvbnN0IGtleSA9IGNvbW1vbi51SW50MjU2VG9IZXgoYXNzZXQpO1xuICAgICAgICBpZiAoKGFjY1trZXldIGFzIEJOIHwgdW5kZWZpbmVkKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgYWNjW2tleV0gPSB1dGlscy5aRVJPO1xuICAgICAgICB9XG4gICAgICAgIGFjY1trZXldID0gYWNjW2tleV0uYWRkKHZhbHVlKTtcblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIGFjY291bnQgPT09IHVuZGVmaW5lZFxuICAgICAgICA/IHt9XG4gICAgICAgIDogT2JqZWN0LmVudHJpZXMoYWNjb3VudC5iYWxhbmNlcykucmVkdWNlPHsgW2Fzc2V0OiBzdHJpbmddOiBCTiB9PigoYWNjLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uYWNjLFxuICAgICAgICAgICAgICAgIFtrZXldOiB1dGlscy5aRVJPLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5hY2MsXG4gICAgICAgICAgICAgIFtrZXldOiB2YWx1ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSwge30pLFxuICAgICk7XG5cbiAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgIHByb21pc2VzLnB1c2goXG4gICAgICAuLi5zcGVudC5tYXAoYXN5bmMgKHsgaW5wdXQgfSkgPT5cbiAgICAgICAgdGhpcy5hY2NvdW50VW5zcGVudC5kZWxldGUoe1xuICAgICAgICAgIGhhc2g6IGFkZHJlc3MsXG4gICAgICAgICAgaW5wdXQsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgcHJvbWlzZXMucHVzaChcbiAgICAgIC4uLm91dHB1dHMubWFwKGFzeW5jICh7IGlucHV0IH0pID0+IHRoaXMuYWNjb3VudFVuc3BlbnQuYWRkKG5ldyBBY2NvdW50VW5zcGVudCh7IGhhc2g6IGFkZHJlc3MsIGlucHV0IH0pKSksXG4gICAgKTtcblxuICAgIHByb21pc2VzLnB1c2goXG4gICAgICAuLi5jbGFpbWVkLm1hcChhc3luYyAoaW5wdXQpID0+XG4gICAgICAgIHRoaXMuYWNjb3VudFVuY2xhaW1lZC5kZWxldGUoe1xuICAgICAgICAgIGhhc2g6IGFkZHJlc3MsXG4gICAgICAgICAgaW5wdXQsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgcHJvbWlzZXMucHVzaChcbiAgICAgIC4uLnNwZW50XG4gICAgICAgIC5maWx0ZXIoKHsgb3V0cHV0IH0pID0+IGNvbW1vbi51SW50MjU2RXF1YWwob3V0cHV0LmFzc2V0LCB0aGlzLnNldHRpbmdzLmdvdmVybmluZ1Rva2VuLmhhc2gpKVxuICAgICAgICAubWFwKGFzeW5jICh7IGlucHV0IH0pID0+IHRoaXMuYWNjb3VudFVuY2xhaW1lZC5hZGQobmV3IEFjY291bnRVbmNsYWltZWQoeyBoYXNoOiBhZGRyZXNzLCBpbnB1dCB9KSkpLFxuICAgICk7XG5cbiAgICBpZiAoYWNjb3VudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKFxuICAgICAgICB0aGlzLmFjY291bnQuYWRkKFxuICAgICAgICAgIG5ldyBBY2NvdW50KHtcbiAgICAgICAgICAgIGhhc2g6IGFkZHJlc3MsXG4gICAgICAgICAgICBiYWxhbmNlcyxcbiAgICAgICAgICAgIHZvdGVzLFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZXMucHVzaChcbiAgICAgICAgdGhpcy5hY2NvdW50LnVwZGF0ZShhY2NvdW50LCB7IGJhbGFuY2VzLCB2b3RlcyB9KS50aGVuKGFzeW5jIChuZXdBY2NvdW50KSA9PiB7XG4gICAgICAgICAgaWYgKG5ld0FjY291bnQuaXNEZWxldGFibGUoKSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5hY2NvdW50LmRlbGV0ZSh7IGhhc2g6IGFkZHJlc3MgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVDb2lucyhpbnB1dHM6IHJlYWRvbmx5IElucHV0W10sIGNsYWltczogcmVhZG9ubHkgSW5wdXRbXSwgYmxvY2s6IEJsb2NrKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaW5wdXRDbGFpbXMgPSBpbnB1dHNcbiAgICAgIC5tYXA8SW5wdXRDbGFpbT4oKGlucHV0KSA9PiAoeyB0eXBlOiAnaW5wdXQnLCBpbnB1dCwgaGFzaDogaW5wdXQuaGFzaCB9KSlcbiAgICAgIC5jb25jYXQoY2xhaW1zLm1hcDxJbnB1dENsYWltPigoaW5wdXQpID0+ICh7IHR5cGU6ICdjbGFpbScsIGlucHV0LCBoYXNoOiBpbnB1dC5oYXNoIH0pKSk7XG5cbiAgICBjb25zdCBoYXNoSW5wdXRDbGFpbXMgPSBPYmplY3QuZW50cmllcyhfLmdyb3VwQnkoaW5wdXRDbGFpbXMsICh7IGhhc2ggfSkgPT4gY29tbW9uLnVJbnQyNTZUb0hleChoYXNoKSkpO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBoYXNoSW5wdXRDbGFpbXMubWFwKGFzeW5jIChbaGFzaCwgdmFsdWVzXSkgPT4gdGhpcy51cGRhdGVDb2luKGNvbW1vbi5oZXhUb1VJbnQyNTYoaGFzaCksIHZhbHVlcywgYmxvY2spKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVDb2luKGhhc2g6IFVJbnQyNTYsIGlucHV0Q2xhaW1zOiByZWFkb25seSBJbnB1dENsYWltW10sIGJsb2NrOiBCbG9jayk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNwZW50Q29pbnMgPSBhd2FpdCB0aGlzLnRyYW5zYWN0aW9uRGF0YS5nZXQoeyBoYXNoIH0pO1xuICAgIGNvbnN0IGVuZEhlaWdodHMgPSB7IC4uLnNwZW50Q29pbnMuZW5kSGVpZ2h0cyB9O1xuICAgIGNvbnN0IGNsYWltZWQgPSB7IC4uLnNwZW50Q29pbnMuY2xhaW1lZCB9O1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1sb29wLXN0YXRlbWVudFxuICAgIGZvciAoY29uc3QgaW5wdXRDbGFpbSBvZiBpbnB1dENsYWltcykge1xuICAgICAgaWYgKGlucHV0Q2xhaW0udHlwZSA9PT0gJ2lucHV0Jykge1xuICAgICAgICBlbmRIZWlnaHRzW2lucHV0Q2xhaW0uaW5wdXQuaW5kZXhdID0gYmxvY2suaW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbGFpbWVkW2lucHV0Q2xhaW0uaW5wdXQuaW5kZXhdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnRyYW5zYWN0aW9uRGF0YS51cGRhdGUoc3BlbnRDb2lucywge1xuICAgICAgZW5kSGVpZ2h0cyxcbiAgICAgIGNsYWltZWQsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|