@bitgo-beta/sdk-coin-algo 1.3.3-alpha.43 → 1.3.3-alpha.430

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.
Files changed (83) hide show
  1. package/dist/src/algo.d.ts +117 -16
  2. package/dist/src/algo.d.ts.map +1 -1
  3. package/dist/src/algo.js +430 -46
  4. package/dist/src/algoToken.d.ts +1 -1
  5. package/dist/src/algoToken.d.ts.map +1 -1
  6. package/dist/src/algoToken.js +3 -3
  7. package/dist/src/index.js +23 -9
  8. package/dist/src/lib/assetTransferBuilder.d.ts +1 -1
  9. package/dist/src/lib/assetTransferBuilder.js +2 -2
  10. package/dist/src/lib/ifaces.d.ts +0 -1
  11. package/dist/src/lib/ifaces.d.ts.map +1 -1
  12. package/dist/src/lib/index.js +23 -9
  13. package/dist/src/lib/keyPair.js +24 -10
  14. package/dist/src/lib/keyRegistrationBuilder.js +1 -1
  15. package/dist/src/lib/seedEncoding.js +23 -9
  16. package/dist/src/lib/transaction.js +3 -4
  17. package/dist/src/lib/transactionBuilder.d.ts +6 -0
  18. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  19. package/dist/src/lib/transactionBuilder.js +45 -29
  20. package/dist/src/lib/transactionBuilderFactory.js +1 -1
  21. package/dist/src/lib/transferBuilder.js +1 -1
  22. package/dist/src/lib/txnSchema.js +1 -1
  23. package/dist/src/lib/utils.d.ts +6 -1
  24. package/dist/src/lib/utils.d.ts.map +1 -1
  25. package/dist/src/lib/utils.js +35 -11
  26. package/dist/src/seedValidator.js +23 -9
  27. package/dist/test/fixtures/algo.d.ts +101 -0
  28. package/dist/test/fixtures/algo.d.ts.map +1 -0
  29. package/dist/test/fixtures/algo.js +239 -0
  30. package/dist/test/fixtures/resources.d.ts +121 -0
  31. package/dist/test/fixtures/resources.d.ts.map +1 -0
  32. package/dist/test/fixtures/resources.js +131 -0
  33. package/dist/test/integration/algo.integration.d.ts +2 -0
  34. package/dist/test/integration/algo.integration.d.ts.map +1 -0
  35. package/dist/test/integration/algo.integration.js +71 -0
  36. package/dist/test/unit/algo.d.ts +2 -0
  37. package/dist/test/unit/algo.d.ts.map +1 -0
  38. package/dist/test/unit/algo.js +1223 -0
  39. package/dist/test/unit/algoIsWalletAddress.d.ts +2 -0
  40. package/dist/test/unit/algoIsWalletAddress.d.ts.map +1 -0
  41. package/dist/test/unit/algoIsWalletAddress.js +118 -0
  42. package/dist/test/unit/algoToken.d.ts +2 -0
  43. package/dist/test/unit/algoToken.d.ts.map +1 -0
  44. package/dist/test/unit/algoToken.js +79 -0
  45. package/dist/test/unit/fixtures/algoBackupKey.d.ts +4 -0
  46. package/dist/test/unit/fixtures/algoBackupKey.d.ts.map +1 -0
  47. package/dist/test/unit/fixtures/algoBackupKey.js +10 -0
  48. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  49. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  50. package/dist/test/unit/lib/keyPair.js +110 -0
  51. package/dist/test/unit/lib/seedEncoding.d.ts +2 -0
  52. package/dist/test/unit/lib/seedEncoding.d.ts.map +1 -0
  53. package/dist/test/unit/lib/seedEncoding.js +59 -0
  54. package/dist/test/unit/lib/transaction.d.ts +2 -0
  55. package/dist/test/unit/lib/transaction.d.ts.map +1 -0
  56. package/dist/test/unit/lib/transaction.js +157 -0
  57. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.d.ts +2 -0
  58. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.d.ts.map +1 -0
  59. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.js +300 -0
  60. package/dist/test/unit/lib/transactionBuilder/base.d.ts +2 -0
  61. package/dist/test/unit/lib/transactionBuilder/base.d.ts.map +1 -0
  62. package/dist/test/unit/lib/transactionBuilder/base.js +310 -0
  63. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.d.ts +2 -0
  64. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.d.ts.map +1 -0
  65. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.js +473 -0
  66. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  67. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  68. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.js +138 -0
  69. package/dist/test/unit/lib/transactionBuilder/transferBuilder.d.ts +2 -0
  70. package/dist/test/unit/lib/transactionBuilder/transferBuilder.d.ts.map +1 -0
  71. package/dist/test/unit/lib/transactionBuilder/transferBuilder.js +290 -0
  72. package/dist/test/unit/lib/utils.d.ts +2 -0
  73. package/dist/test/unit/lib/utils.d.ts.map +1 -0
  74. package/dist/test/unit/lib/utils.js +307 -0
  75. package/dist/test/unit/verifyTransaction.d.ts +2 -0
  76. package/dist/test/unit/verifyTransaction.d.ts.map +1 -0
  77. package/dist/test/unit/verifyTransaction.js +703 -0
  78. package/dist/tsconfig.tsbuildinfo +1 -0
  79. package/package.json +12 -10
  80. package/.eslintignore +0 -5
  81. package/.mocharc.yml +0 -8
  82. package/CHANGELOG.md +0 -160
  83. package/types/index.d.ts +0 -60
package/dist/src/algo.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.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
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,13 +15,23 @@ 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 (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
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
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
37
  };
@@ -26,13 +40,18 @@ exports.Algo = void 0;
26
40
  /**
27
41
  * @prettier
28
42
  */
29
- const utxolib = __importStar(require("@bitgo-beta/utxo-lib"));
30
43
  const _ = __importStar(require("lodash"));
31
44
  const seedValidator_1 = require("./seedValidator");
32
45
  const statics_1 = require("@bitgo-beta/statics");
33
46
  const AlgoLib = __importStar(require("./lib"));
34
47
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
35
48
  const stellar_sdk_1 = __importDefault(require("stellar-sdk"));
49
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
50
+ const utils_1 = __importDefault(require("./lib/utils"));
51
+ const algosdk = __importStar(require("algosdk"));
52
+ const transactionBuilder_1 = require("./lib/transactionBuilder");
53
+ const buffer_1 = require("buffer");
54
+ const lodash_1 = require("lodash");
36
55
  const SUPPORTED_ADDRESS_VERSION = 1;
37
56
  const MSIG_THRESHOLD = 2; // m in m-of-n
38
57
  class Algo extends sdk_core_1.BaseCoin {
@@ -73,12 +92,11 @@ class Algo extends sdk_core_1.BaseCoin {
73
92
  allowsAccountConsolidations() {
74
93
  return true;
75
94
  }
76
- /**
77
- * Generate ed25519 key pair
78
- *
79
- * @param seed
80
- * @returns {Object} object with generated pub, prv
81
- */
95
+ /** inheritdoc */
96
+ deriveKeyWithSeed() {
97
+ throw new sdk_core_1.NotSupported('method deriveKeyWithSeed not supported for eddsa curve');
98
+ }
99
+ /** inheritdoc */
82
100
  generateKeyPair(seed) {
83
101
  const keyPair = seed ? new AlgoLib.KeyPair({ seed }) : new AlgoLib.KeyPair();
84
102
  const keys = keyPair.getKeys();
@@ -87,9 +105,18 @@ class Algo extends sdk_core_1.BaseCoin {
87
105
  }
88
106
  return {
89
107
  pub: keyPair.getAddress(),
90
- prv: AlgoLib.algoUtils.encodeSeed(Buffer.from(keyPair.getSigningKey())),
108
+ prv: AlgoLib.algoUtils.encodeSeed(buffer_1.Buffer.from(keyPair.getSigningKey())),
91
109
  };
92
110
  }
111
+ /** inheritdoc */
112
+ generateRootKeyPair(seed) {
113
+ const keyPair = seed ? new AlgoLib.KeyPair({ seed }) : new AlgoLib.KeyPair();
114
+ const keys = keyPair.getKeys();
115
+ if (!keys.prv) {
116
+ throw new Error('Missing prv in key generation.');
117
+ }
118
+ return { prv: keys.prv + keys.pub, pub: keys.pub };
119
+ }
93
120
  /**
94
121
  * Return boolean indicating whether input is valid public key for the coin.
95
122
  *
@@ -97,7 +124,7 @@ class Algo extends sdk_core_1.BaseCoin {
97
124
  * @returns {Boolean} is it valid?
98
125
  */
99
126
  isValidPub(pub) {
100
- return AlgoLib.algoUtils.isValidAddress(pub);
127
+ return AlgoLib.algoUtils.isValidAddress(pub) || AlgoLib.algoUtils.isValidPublicKey(pub);
101
128
  }
102
129
  /**
103
130
  * Return boolean indicating whether input is valid seed for the coin
@@ -108,7 +135,7 @@ class Algo extends sdk_core_1.BaseCoin {
108
135
  * @returns {Boolean} is it valid?
109
136
  */
110
137
  isValidPrv(prv) {
111
- return AlgoLib.algoUtils.isValidSeed(prv);
138
+ return AlgoLib.algoUtils.isValidSeed(prv) || AlgoLib.algoUtils.isValidPrivateKey(prv);
112
139
  }
113
140
  /**
114
141
  * Return boolean indicating whether input is valid public key for the coin
@@ -127,10 +154,10 @@ class Algo extends sdk_core_1.BaseCoin {
127
154
  */
128
155
  async signMessage(key, message) {
129
156
  const algoKeypair = new AlgoLib.KeyPair({ prv: key.prv });
130
- if (Buffer.isBuffer(message)) {
157
+ if (buffer_1.Buffer.isBuffer(message)) {
131
158
  message = message.toString('base64');
132
159
  }
133
- return Buffer.from(algoKeypair.signMessage(message));
160
+ return buffer_1.Buffer.from(algoKeypair.signMessage(message));
134
161
  }
135
162
  /**
136
163
  * Specifies what key we will need for signing` - Algorand needs the backup, bitgo pubs.
@@ -324,7 +351,7 @@ class Algo extends sdk_core_1.BaseCoin {
324
351
  if (!transaction) {
325
352
  throw new Error('Invalid transaction');
326
353
  }
327
- const signedTxHex = Buffer.from(transaction.toBroadcastFormat()).toString('base64');
354
+ const signedTxHex = buffer_1.Buffer.from(transaction.toBroadcastFormat()).toString('base64');
328
355
  if (numberSigners === 1) {
329
356
  return { txHex: signedTxHex };
330
357
  }
@@ -361,23 +388,172 @@ class Algo extends sdk_core_1.BaseCoin {
361
388
  return rootAddress === address;
362
389
  }
363
390
  async verifyTransaction(params) {
391
+ const { txParams, txPrebuild, wallet, verification } = params;
392
+ if (!txParams) {
393
+ throw new Error('missing txParams');
394
+ }
395
+ if (!txPrebuild) {
396
+ throw new Error('missing txPrebuild');
397
+ }
398
+ if (!txPrebuild.txHex) {
399
+ throw new Error('missing txHex in txPrebuild');
400
+ }
401
+ const factory = this.getBuilder();
402
+ const txBuilder = factory.from(txPrebuild.txHex);
403
+ const tx = await txBuilder.build();
404
+ const txJson = tx.toJson();
405
+ // Check if this is a token enablement transaction
406
+ const isTokenEnablementTx = txParams.type === 'enabletoken';
407
+ // Validate based on Algorand transaction type
408
+ if (isTokenEnablementTx && verification?.verifyTokenEnablement) {
409
+ // Validate token enablement transaction
410
+ this.validateTokenEnablementTransaction(txJson, txParams);
411
+ }
412
+ else {
413
+ switch (txJson.type) {
414
+ case 'pay':
415
+ this.validatePayTransaction(txJson, txParams);
416
+ break;
417
+ case 'axfer':
418
+ this.validateAssetTransferTransaction(txJson, txParams);
419
+ break;
420
+ default:
421
+ // For other transaction types, perform basic validation
422
+ this.validateBasicTransaction(txJson);
423
+ break;
424
+ }
425
+ }
426
+ // Verify consolidation transactions send to base address
427
+ if (verification?.consolidationToBaseAddress) {
428
+ if (!wallet?.coinSpecific()?.rootAddress) {
429
+ throw new Error('Unable to determine base address for consolidation');
430
+ }
431
+ const rootAddress = wallet.coinSpecific()?.rootAddress;
432
+ // Verify the transaction recipient matches the rootAddress
433
+ if (!txJson.to) {
434
+ throw new Error('Transaction is missing recipient address');
435
+ }
436
+ if (txJson.to !== rootAddress) {
437
+ throw new sdk_core_1.TxIntentMismatchError('Consolidation transaction recipient does not match wallet base address', txJson.to, [txParams], txJson);
438
+ }
439
+ }
364
440
  return true;
365
441
  }
366
- /** @inheritDoc */
367
- deriveKeyWithSeed({ key, seed }) {
368
- const derivationPathInput = utxolib.crypto.hash256(Buffer.from(seed, 'utf8')).toString('hex');
369
- const derivationPathParts = [
370
- 999999,
371
- parseInt(derivationPathInput.slice(0, 7), 16),
372
- parseInt(derivationPathInput.slice(7, 14), 16),
373
- ];
374
- const derivationPath = 'm/' + derivationPathParts.map((part) => `${part}'`).join('/');
375
- const derivedKey = sdk_core_1.Ed25519KeyDeriver.derivePath(derivationPath, key).key;
376
- const keypair = new AlgoLib.KeyPair({ seed: derivedKey });
377
- return {
378
- key: keypair.getAddress(),
379
- derivationPath,
380
- };
442
+ /**
443
+ * Validate basic transaction fields common to all transaction types
444
+ */
445
+ validateBasicTransaction(txJson) {
446
+ if (!txJson.from) {
447
+ throw new Error('Invalid transaction: missing sender address');
448
+ }
449
+ if (!txJson.fee || txJson.fee < 0) {
450
+ throw new Error('Invalid transaction: invalid fee');
451
+ }
452
+ }
453
+ /**
454
+ * Validate Payment (pay) transaction
455
+ */
456
+ validatePayTransaction(txJson, txParams) {
457
+ this.validateBasicTransaction(txJson);
458
+ if (!txJson.to) {
459
+ throw new Error('Invalid transaction: missing recipient address');
460
+ }
461
+ if (txJson.amount === undefined || txJson.amount < 0) {
462
+ throw new Error('Invalid transaction: invalid amount');
463
+ }
464
+ // Validate recipients if provided in txParams
465
+ if (txParams.recipients && txParams.recipients.length > 0) {
466
+ if (txParams.recipients.length !== 1) {
467
+ throw new Error('Algorand transactions can only have one recipient');
468
+ }
469
+ const expectedRecipient = txParams.recipients[0];
470
+ const expectedAmount = expectedRecipient.amount.toString();
471
+ const expectedAddress = expectedRecipient.address;
472
+ const actualAmount = txJson.amount.toString();
473
+ const actualAddress = txJson.to;
474
+ if (expectedAmount !== actualAmount) {
475
+ throw new Error('transaction amount in txPrebuild does not match the value given by client');
476
+ }
477
+ if (expectedAddress.toLowerCase() !== actualAddress.toLowerCase()) {
478
+ throw new Error('destination address does not match with the recipient address');
479
+ }
480
+ }
481
+ return true;
482
+ }
483
+ /**
484
+ * Validate Asset Transfer (axfer) transaction
485
+ */
486
+ validateAssetTransferTransaction(txJson, txParams) {
487
+ this.validateBasicTransaction(txJson);
488
+ // Basic amount validation if present
489
+ if (txJson.amount !== undefined && txJson.amount < 0) {
490
+ throw new Error('Invalid asset transfer transaction: invalid amount');
491
+ }
492
+ return true;
493
+ }
494
+ /**
495
+ * Extract token ID from token name
496
+ * Token names are in format like "talgo:JPT-162085446" where the number after the last hyphen is the token ID
497
+ */
498
+ extractTokenIdFromName(tokenName) {
499
+ // Handle format like "talgo:JPT-162085446" or "algo:TOKEN-123456"
500
+ const parts = tokenName.split(':');
501
+ if (parts.length < 2) {
502
+ return null;
503
+ }
504
+ // Get the part after colon (e.g., "JPT-162085446")
505
+ const tokenPart = parts[1];
506
+ // Extract the number after the last hyphen
507
+ const lastHyphenIndex = tokenPart.lastIndexOf('-');
508
+ if (lastHyphenIndex === -1) {
509
+ return null;
510
+ }
511
+ const tokenIdStr = tokenPart.substring(lastHyphenIndex + 1);
512
+ const tokenId = parseInt(tokenIdStr, 10);
513
+ return isNaN(tokenId) ? null : tokenId;
514
+ }
515
+ /**
516
+ * Validate Token Enablement (opt-in) transaction
517
+ */
518
+ validateTokenEnablementTransaction(txJson, txParams) {
519
+ this.validateBasicTransaction(txJson);
520
+ // Verify it's an asset transfer (axfer) transaction
521
+ if (txJson.type !== 'axfer') {
522
+ throw new Error('Invalid token enablement transaction: must be of type axfer');
523
+ }
524
+ // Verify amount is 0 (token opt-in requirement)
525
+ if ((0, lodash_1.toNumber)(txJson.amount) !== 0) {
526
+ throw new Error('Invalid token enablement transaction: amount must be 0 for token opt-in');
527
+ }
528
+ // Verify sender and recipient are the same (self-transaction)
529
+ if (!txJson.from || !txJson.to || txJson.from !== txJson.to) {
530
+ throw new Error('Invalid token enablement transaction: sender and recipient must be the same address');
531
+ }
532
+ // Verify token ID is present
533
+ if (!txJson.tokenId) {
534
+ throw new Error('Invalid token enablement transaction: missing token ID');
535
+ }
536
+ // If txParams specifies token information, verify the token ID matches
537
+ let expectedTokenId = null;
538
+ // Check for enableTokens array (used in TSS wallets)
539
+ if (txParams.enableTokens && Array.isArray(txParams.enableTokens) && txParams.enableTokens.length > 0) {
540
+ const tokenName = txParams.enableTokens[0].name;
541
+ if (tokenName) {
542
+ expectedTokenId = this.extractTokenIdFromName(tokenName);
543
+ }
544
+ }
545
+ // Check for recipients array with tokenName (used in non-TSS wallets)
546
+ else if (txParams.recipients && Array.isArray(txParams.recipients) && txParams.recipients.length > 0) {
547
+ const recipient = txParams.recipients[0];
548
+ if (recipient.tokenName) {
549
+ expectedTokenId = this.extractTokenIdFromName(recipient.tokenName);
550
+ }
551
+ }
552
+ // Verify the token ID matches if we have an expected value
553
+ if (expectedTokenId !== null && txJson.tokenId !== expectedTokenId) {
554
+ throw new Error(`Token enablement verification failed: expected token ID ${expectedTokenId} but transaction has token ID ${txJson.tokenId}`);
555
+ }
556
+ return true;
381
557
  }
382
558
  decodeTx(txn) {
383
559
  return AlgoLib.algoUtils.decodeAlgoTxn(txn);
@@ -385,6 +561,188 @@ class Algo extends sdk_core_1.BaseCoin {
385
561
  getAddressFromPublicKey(pubKey) {
386
562
  return AlgoLib.algoUtils.publicKeyToAlgoAddress(pubKey);
387
563
  }
564
+ supportsDeriveKeyWithSeed() {
565
+ return false;
566
+ }
567
+ /** inherited doc */
568
+ getDefaultMultisigType() {
569
+ return sdk_core_1.multisigTypes.onchain;
570
+ }
571
+ /**
572
+ * Gets config for how token enablements work for this coin
573
+ * @returns
574
+ * requiresTokenEnablement: True if tokens need to be enabled for this coin
575
+ * supportsMultipleTokenEnablements: True if multiple tokens can be enabled in one transaction
576
+ */
577
+ getTokenEnablementConfig() {
578
+ return {
579
+ requiresTokenEnablement: true,
580
+ supportsMultipleTokenEnablements: false,
581
+ };
582
+ }
583
+ /**
584
+ * Gets the balance of the root address in base units of algo
585
+ * Eg. If balance is 1 Algo, this returns 1*10^6
586
+ * @param rootAddress
587
+ * @param client
588
+ */
589
+ async getAccountBalance(rootAddress, client) {
590
+ const accountInformation = await client.accountInformation(rootAddress).do();
591
+ // Extract the balance from the account information
592
+ return accountInformation.amount;
593
+ }
594
+ /**
595
+ * Returns the Algo client for the given token, baseServer and port
596
+ * Used to interact with the Algo network
597
+ */
598
+ getClient(token, baseServer, port) {
599
+ return new algosdk.Algodv2(token, baseServer, port);
600
+ }
601
+ async recover(params) {
602
+ const isUnsignedSweep = this.isValidPub(params.userKey) && this.isValidPub(params.backupKey);
603
+ if (!params.nodeParams) {
604
+ throw new Error('Please provide the details of an ALGO node to use for recovery');
605
+ }
606
+ // Validate the root address
607
+ if (!this.isValidAddress(params.rootAddress)) {
608
+ throw new Error('invalid rootAddress, got: ' + params.rootAddress);
609
+ }
610
+ // Validate the destination address
611
+ if (!this.isValidAddress(params.recoveryDestination)) {
612
+ throw new Error('invalid recoveryDestination, got: ' + params.recoveryDestination);
613
+ }
614
+ if (params.firstRound && new bignumber_js_1.default(params.firstRound).isNegative()) {
615
+ throw new Error('first round needs to be a positive value');
616
+ }
617
+ const genesisId = this.bitgo.getEnv() === 'prod' ? transactionBuilder_1.MAINNET_GENESIS_ID : transactionBuilder_1.TESTNET_GENESIS_ID;
618
+ const genesisHash = this.bitgo.getEnv() === 'prod' ? transactionBuilder_1.MAINNET_GENESIS_HASH : transactionBuilder_1.TESTNET_GENESIS_HASH;
619
+ utils_1.default.validateBase64(genesisHash);
620
+ if (!isUnsignedSweep && !params.walletPassphrase) {
621
+ throw new Error('walletPassphrase is required for non-bitgo recovery');
622
+ }
623
+ const factory = new AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
624
+ const txBuilder = factory.getTransferBuilder();
625
+ let userPrv;
626
+ let backupPrv;
627
+ if (!isUnsignedSweep) {
628
+ if (!params.bitgoKey) {
629
+ throw new Error('bitgo public key from the keyCard is required for non-bitgo recovery');
630
+ }
631
+ try {
632
+ userPrv = this.bitgo.decrypt({ input: params.userKey, password: params.walletPassphrase });
633
+ backupPrv = this.bitgo.decrypt({ input: params.backupKey, password: params.walletPassphrase });
634
+ const userKeyAddress = utils_1.default.privateKeyToAlgoAddress(userPrv);
635
+ const backupKeyAddress = utils_1.default.privateKeyToAlgoAddress(backupPrv);
636
+ txBuilder.numberOfRequiredSigners(2).setSigners([userKeyAddress, backupKeyAddress, params.bitgoKey]);
637
+ }
638
+ catch (e) {
639
+ throw new Error('unable to decrypt userKey or backupKey with the walletPassphrase provided, got error: ' + e.message);
640
+ }
641
+ }
642
+ const client = this.getClient(params.nodeParams.token, params.nodeParams.baseServer, params.nodeParams.port);
643
+ const nativeBalance = await this.getAccountBalance(params.rootAddress, client);
644
+ // Algorand accounts require a min. balance of 1 ALGO
645
+ const MIN_MICROALGOS_BALANCE = 100000;
646
+ const spendableAmount = new bignumber_js_1.default(nativeBalance).minus(params.fee).minus(MIN_MICROALGOS_BALANCE).toNumber();
647
+ if (new bignumber_js_1.default(spendableAmount).isZero() || new bignumber_js_1.default(spendableAmount).isLessThanOrEqualTo(params.fee)) {
648
+ throw new Error('Insufficient balance to recover, got balance: ' +
649
+ nativeBalance +
650
+ ' fee: ' +
651
+ params.fee +
652
+ ' min account balance: ' +
653
+ MIN_MICROALGOS_BALANCE);
654
+ }
655
+ let latestRound;
656
+ if (!params.firstRound) {
657
+ latestRound = await client
658
+ .status()
659
+ .do()
660
+ .then((status) => status['last-round']);
661
+ }
662
+ const firstRound = !params.firstRound ? latestRound : params.firstRound;
663
+ if (!firstRound) {
664
+ throw new Error('Unable to fetch the latest round from the node. Please provide the firstRound or try again.');
665
+ }
666
+ const LAST_ROUND_BUFFER = 1000;
667
+ const lastRound = firstRound + LAST_ROUND_BUFFER;
668
+ txBuilder
669
+ .fee({ fee: params.fee.toString() })
670
+ .isFlatFee(true)
671
+ .sender({
672
+ address: params.rootAddress,
673
+ })
674
+ .to({
675
+ address: params.recoveryDestination,
676
+ })
677
+ .amount(spendableAmount)
678
+ .genesisId(genesisId)
679
+ .genesisHash(genesisHash)
680
+ .firstRound(new bignumber_js_1.default(firstRound).toNumber())
681
+ .lastRound(new bignumber_js_1.default(lastRound).toNumber());
682
+ if (params.note) {
683
+ const note = new Uint8Array(buffer_1.Buffer.from(params.note, 'utf-8'));
684
+ txBuilder.note(note);
685
+ }
686
+ // Cold wallet, offline vault
687
+ if (isUnsignedSweep) {
688
+ const tx = await txBuilder.build();
689
+ const txJson = tx.toJson();
690
+ return {
691
+ txHex: buffer_1.Buffer.from(tx.toBroadcastFormat()).toString('hex'),
692
+ type: txJson.type,
693
+ userKey: params.userKey,
694
+ backupKey: params.backupKey,
695
+ bitgoKey: params.bitgoKey,
696
+ address: params.rootAddress,
697
+ coin: this.getChain(),
698
+ feeInfo: txJson.fee,
699
+ amount: txJson.amount ?? nativeBalance.toString(),
700
+ firstRound: txJson.firstRound,
701
+ lastRound: txJson.lastRound,
702
+ genesisId: genesisId,
703
+ genesisHash: genesisHash,
704
+ note: txJson.note ? buffer_1.Buffer.from(txJson.note.buffer).toString('utf-8') : undefined,
705
+ keys: [params.userKey, params.backupKey, params.bitgoKey],
706
+ addressVersion: 1,
707
+ };
708
+ }
709
+ // Non-bitgo Recovery (Hot wallets)
710
+ txBuilder.sign({ key: userPrv });
711
+ txBuilder.sign({ key: backupPrv });
712
+ const tx = await txBuilder.build();
713
+ const txJson = tx.toJson();
714
+ return {
715
+ tx: buffer_1.Buffer.from(tx.toBroadcastFormat()).toString('base64'),
716
+ id: txJson.id,
717
+ coin: this.getChain(),
718
+ fee: txJson.fee,
719
+ firstRound: txJson.firstRound,
720
+ lastRound: txJson.lastRound,
721
+ genesisId: genesisId,
722
+ genesisHash: genesisHash,
723
+ note: txJson.note ? buffer_1.Buffer.from(txJson.note.buffer).toString('utf-8') : undefined,
724
+ };
725
+ }
726
+ /**
727
+ * Accepts a fully signed serialized base64 transaction and broadcasts it on the network.
728
+ * Uses the external node provided by the client
729
+ * @param serializedSignedTransaction
730
+ * @param nodeParams
731
+ */
732
+ async broadcastTransaction({ serializedSignedTransaction, nodeParams, }) {
733
+ if (!nodeParams) {
734
+ throw new Error('Please provide the details of the algorand node');
735
+ }
736
+ try {
737
+ const txHex = buffer_1.Buffer.from(serializedSignedTransaction, 'base64').toString('hex');
738
+ const algoTx = utils_1.default.toUint8Array(txHex);
739
+ const client = this.getClient(nodeParams.token, nodeParams.baseServer, nodeParams.port);
740
+ return await client.sendRawTransaction(algoTx).do();
741
+ }
742
+ catch (e) {
743
+ throw new Error('Failed to broadcast transaction, error: ' + e.message);
744
+ }
745
+ }
388
746
  /**
389
747
  * Stellar and Algorand both use keys on the ed25519 curve, but use different encodings.
390
748
  * As the HSM doesn't have explicit support to create Algorand addresses, we use the Stellar
@@ -396,24 +754,50 @@ class Algo extends sdk_core_1.BaseCoin {
396
754
  * @return {*}
397
755
  */
398
756
  stellarAddressToAlgoAddress(addressOrPubKey) {
757
+ // we have an Algorand address
399
758
  if (this.isValidAddress(addressOrPubKey)) {
400
- // we have an Algorand address
401
759
  return addressOrPubKey;
402
760
  }
403
- if (!stellar_sdk_1.default.StrKey.isValidEd25519PublicKey(addressOrPubKey)) {
404
- throw new sdk_core_1.UnexpectedAddressError('Neither an Algorand address nor a stellar pubkey.');
405
- }
406
761
  // we have a stellar key
407
- const stellarPub = stellar_sdk_1.default.StrKey.decodeEd25519PublicKey(addressOrPubKey);
408
- const algoAddress = AlgoLib.algoUtils.encodeAddress(stellarPub);
409
- if (!this.isValidAddress(algoAddress)) {
410
- throw new sdk_core_1.UnexpectedAddressError('Cannot convert Stellar address to an Algorand address via pubkey.');
762
+ if (stellar_sdk_1.default.StrKey.isValidEd25519PublicKey(addressOrPubKey)) {
763
+ const stellarPub = stellar_sdk_1.default.StrKey.decodeEd25519PublicKey(addressOrPubKey);
764
+ const algoAddress = AlgoLib.algoUtils.encodeAddress(stellarPub);
765
+ if (this.isValidAddress(algoAddress)) {
766
+ return algoAddress;
767
+ }
768
+ throw new sdk_core_1.UnexpectedAddressError('Cannot convert Stellar address to an Algorand address via stellar pubkey.');
769
+ // we have a root pubkey
770
+ }
771
+ else if (AlgoLib.algoUtils.isValidPublicKey(addressOrPubKey)) {
772
+ const kp = new AlgoLib.KeyPair({ pub: addressOrPubKey });
773
+ const algoAddress = kp.getAddress();
774
+ if (this.isValidAddress(algoAddress)) {
775
+ return algoAddress;
776
+ }
777
+ throw new sdk_core_1.UnexpectedAddressError('Invalid root pubkey.');
411
778
  }
412
- return algoAddress;
779
+ throw new sdk_core_1.UnexpectedAddressError('Neither an Algorand address, a stellar pubkey or a root public key.');
413
780
  }
414
781
  getBuilder() {
415
782
  return new AlgoLib.TransactionBuilderFactory(statics_1.coins.get(this.getBaseChain()));
416
783
  }
784
+ /** @inheritDoc */
785
+ auditDecryptedKey({ publicKey, prv, multiSigType }) {
786
+ if (multiSigType === 'tss') {
787
+ throw new Error('Unsupported multiSigType');
788
+ }
789
+ let algoKey;
790
+ try {
791
+ algoKey = new AlgoLib.KeyPair({ prv });
792
+ }
793
+ catch (e) {
794
+ throw new Error(`Invalid private key: ${e.message}`);
795
+ }
796
+ if (publicKey && publicKey !== algoKey.getKeys().pub) {
797
+ throw new Error('Invalid public key');
798
+ }
799
+ return;
800
+ }
417
801
  }
418
802
  exports.Algo = Algo;
419
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxnby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hbGdvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7R0FFRztBQUNILDhEQUFnRDtBQUNoRCwwQ0FBNEI7QUFDNUIsbURBQWdEO0FBQ2hELGlEQUF3RDtBQUN4RCwrQ0FBaUM7QUFDakMsbURBb0I4QjtBQUM5Qiw4REFBa0M7QUFFbEMsTUFBTSx5QkFBeUIsR0FBRyxDQUFDLENBQUM7QUFDcEMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxDQUFDLENBQUMsY0FBYztBQTJGeEMsTUFBYSxJQUFLLFNBQVEsbUJBQVE7SUFJaEMsWUFBWSxLQUFnQjtRQUMxQixLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFKTixpQkFBWSxHQUF3QixhQUFhLENBQUM7UUFDbEQsa0JBQWEsR0FBd0IsY0FBYyxDQUFDO0lBSTdELENBQUM7SUFFRCxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQWdCO1FBQ3BDLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUVELFFBQVE7UUFDTixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsWUFBWTtRQUNWLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELFdBQVc7UUFDVCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsYUFBYTtRQUNYLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVEOzs7T0FHRztJQUNILHdCQUF3QjtRQUN0QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSCwyQkFBMkI7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxlQUFlLENBQUMsSUFBYTtRQUMzQixNQUFNLE9BQU8sR0FBRyxJQUFJ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QUFPLElBQUksT0FBTyxDQUFDLHlCQUF5QixDQUFDLGVBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMvRSxDQUFDO0NBQ0Y7QUExYkQsb0JBMGJDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBTZWVkVmFsaWRhdG9yIH0gZnJvbSAnLi9zZWVkVmFsaWRhdG9yJztcbmltcG9ydCB7IGNvaW5zLCBDb2luRmFtaWx5IH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgKiBhcyBBbGdvTGliIGZyb20gJy4vbGliJztcbmltcG9ydCB7XG4gIEFkZHJlc3NDb2luU3BlY2lmaWMsXG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIEVkMjU1MTlLZXlEZXJpdmVyLFxuICBJbnZhbGlkQWRkcmVzc0Vycm9yLFxuICBJbnZhbGlkS2V5LFxuICBLZXlJbmRpY2VzLFxuICBLZXlQYWlyLFxuICBQYXJzZWRUcmFuc2FjdGlvbixcbiAgUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFNpZ25lZFRyYW5zYWN0aW9uLFxuICBTaWduVHJhbnNhY3Rpb25PcHRpb25zIGFzIEJhc2VTaWduVHJhbnNhY3Rpb25PcHRpb25zLFxuICBUb2tlbk1hbmFnZW1lbnRUeXBlLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUcmFuc2FjdGlvblJlY2lwaWVudCxcbiAgVHJhbnNhY3Rpb25UeXBlLFxuICBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yLFxuICBWZXJpZnlBZGRyZXNzT3B0aW9ucyxcbiAgVmVyaWZ5VHJhbnNhY3Rpb25PcHRpb25zLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgc3RlbGxhciBmcm9tICdzdGVsbGFyLXNkayc7XG5cbmNvbnN0IFNVUFBPUlRFRF9BRERSRVNTX1ZFUlNJT04gPSAxO1xuY29uc3QgTVNJR19USFJFU0hPTEQgPSAyOyAvLyBtIGluIG0tb2YtblxuXG5leHBvcnQgaW50ZXJmYWNlIEFsZ29BZGRyZXNzQ29pblNwZWNpZmljcyBleHRlbmRzIEFkZHJlc3NDb2luU3BlY2lmaWMge1xuICByb290QWRkcmVzczogc3RyaW5nO1xuICBiaXRnb0tleTogc3RyaW5nO1xuICBiaXRnb1B1YktleT86IHN0cmluZztcbiAgYWRkcmVzc1ZlcnNpb246IG51bWJlcjtcbiAgdGhyZXNob2xkOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVmVyaWZ5QWxnb0FkZHJlc3NPcHRpb25zIGV4dGVuZHMgVmVyaWZ5QWRkcmVzc09wdGlvbnMge1xuICBjaGFpbjogbnVtYmVyO1xuICBpbmRleDogbnVtYmVyO1xuICBjb2luOiBzdHJpbmc7XG4gIHdhbGxldDogc3RyaW5nO1xuICBjb2luU3BlY2lmaWM6IEFsZ29BZGRyZXNzQ29pblNwZWNpZmljcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBbGdvVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiBleHRlbmRzIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24ge1xuICBtZW1vPzogc3RyaW5nO1xuICB0eXBlPzogc3RyaW5nIHwgbnVtYmVyO1xuICB2b3RlS2V5Pzogc3RyaW5nO1xuICBzZWxlY3Rpb25LZXk/OiBzdHJpbmc7XG4gIHZvdGVGaXJzdD86IG51bWJlcjtcbiAgdm90ZUxhc3Q/OiBudW1iZXI7XG4gIHZvdGVLZXlEaWx1dGlvbj86IG51bWJlcjtcbiAgdG9rZW5JZD86IG51bWJlcjtcbiAgb3BlcmF0aW9ucz86IFRyYW5zYWN0aW9uT3BlcmF0aW9uW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNhY3Rpb25PcGVyYXRpb24ge1xuICB0eXBlOiBzdHJpbmc7XG4gIGNvaW46IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaWduVHJhbnNhY3Rpb25PcHRpb25zIGV4dGVuZHMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eFByZWJ1aWxkOiBUcmFuc2FjdGlvblByZWJ1aWxkO1xuICBwcnY6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvblByZWJ1aWxkIHtcbiAgdHhIZXg6IHN0cmluZztcbiAgaGFsZlNpZ25lZD86IHtcbiAgICB0eEhleDogc3RyaW5nO1xuICB9O1xuICB0eEluZm86IHtcbiAgICBmcm9tOiBzdHJpbmc7XG4gICAgdG86IHN0cmluZztcbiAgICBhbW91bnQ6IHN0cmluZztcbiAgICBmZWU6IG51bWJlcjtcbiAgICBmaXJzdFJvdW5kOiBudW1iZXI7XG4gICAgbGFzdFJvdW5kOiBudW1iZXI7XG4gICAgZ2VuZXNpc0lEOiBzdHJpbmc7XG4gICAgZ2VuZXNpc0hhc2g6IHN0cmluZztcbiAgICBub3RlPzogc3RyaW5nO1xuICB9O1xuICBrZXlzOiBzdHJpbmdbXTtcbiAgYWRkcmVzc1ZlcnNpb246IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGdWxseVNpZ25lZFRyYW5zYWN0aW9uIHtcbiAgdHhIZXg6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIYWxmU2lnbmVkVHJhbnNhY3Rpb24ge1xuICBoYWxmU2lnbmVkOiB7XG4gICAgdHhIZXg6IHN0cmluZztcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvbkZlZSB7XG4gIGZlZTogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBFeHBsYWluVHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgdHhIZXg/OiBzdHJpbmc7XG4gIGhhbGZTaWduZWQ/OiB7XG4gICAgdHhIZXg6IHN0cmluZztcbiAgfTtcbiAgcHVibGljS2V5cz86IHN0cmluZ1tdO1xuICBmZWVJbmZvOiBUcmFuc2FjdGlvbkZlZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZmllZFRyYW5zYWN0aW9uUGFyYW1ldGVycyB7XG4gIHR4SGV4OiBzdHJpbmc7XG4gIGFkZHJlc3NWZXJzaW9uOiBudW1iZXI7XG4gIHNpZ25lcnM6IHN0cmluZ1tdO1xuICBwcnY6IHN0cmluZztcbiAgaXNIYWxmU2lnbmVkOiBib29sZWFuO1xuICBudW1iZXJTaWduZXJzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjbGFzcyBBbGdvIGV4dGVuZHMgQmFzZUNvaW4ge1xuICByZWFkb25seSBFTkFCTEVfVE9LRU46IFRva2VuTWFuYWdlbWVudFR5cGUgPSAnZW5hYmxldG9rZW4nO1xuICByZWFkb25seSBESVNBQkxFX1RPS0VOOiBUb2tlbk1hbmFnZW1lbnRUeXBlID0gJ2Rpc2FibGV0b2tlbic7XG5cbiAgY29uc3RydWN0b3IoYml0Z286IEJpdEdvQmFzZSkge1xuICAgIHN1cGVyKGJpdGdvKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVJbnN0YW5jZShiaXRnbzogQml0R29CYXNlKTogQmFzZUNvaW4ge1xuICAgIHJldHVybiBuZXcgQWxnbyhiaXRnbyk7XG4gIH1cblxuICBnZXRDaGFpbigpOiBzdHJpbmcge1xuICAgIHJldHVybiAnYWxnbyc7XG4gIH1cblxuICBnZXRCYXNlQ2hhaW4oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2FsZ28nO1xuICB9XG5cbiAgZ2V0RmFtaWx5KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdhbGdvJztcbiAgfVxuXG4gIGdldEZ1bGxOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdBbGdvcmFuZCc7XG4gIH1cblxuICBnZXRCYXNlRmFjdG9yKCk6IG51bWJlciB8IHN0cmluZyB7XG4gICAgcmV0dXJuIDFlNjtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFnIGZvciBzZW5kaW5nIHZhbHVlIG9mIDBcbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb2theSB0byBzZW5kIDAgdmFsdWUsIGZhbHNlIG90aGVyd2lzZVxuICAgKi9cbiAgdmFsdWVsZXNzVHJhbnNmZXJBbGxvd2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsZ29yYW5kIHN1cHBvcnRzIGFjY291bnQgY29uc29saWRhdGlvbnMuIFRoZXNlIGFyZSB0cmFuc2ZlcnMgZnJvbSB0aGUgcmVjZWl2ZSBhZGRyZXNzZXNcbiAgICogdG8gdGhlIG1haW4gYWRkcmVzcy5cbiAgICovXG4gIGFsbG93c0FjY291bnRDb25zb2xpZGF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBlZDI1NTE5IGtleSBwYWlyXG4gICAqXG4gICAqIEBwYXJhbSBzZWVkXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IG9iamVjdCB3aXRoIGdlbmVyYXRlZCBwdWIsIHBydlxuICAgKi9cbiAgZ2VuZXJhdGVLZXlQYWlyKHNlZWQ/OiBCdWZmZXIpOiBLZXlQYWlyIHtcbiAgICBjb25zdCBrZXlQYWlyID0gc2VlZCA/IG5ldyBBbGdvTGliLktleVBhaXIoeyBzZWVkIH0pIDogbmV3IEFsZ29MaWIuS2V5UGFpcigpO1xuICAgIGNvbnN0IGtleXMgPSBrZXlQYWlyLmdldEtleXMoKTtcbiAgICBpZiAoIWtleXMucHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcHJ2IGluIGtleSBnZW5lcmF0aW9uLicpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBwdWI6IGtleVBhaXIuZ2V0QWRkcmVzcygpLFxuICAgICAgcHJ2OiBBbGdvTGliLmFsZ29VdGlscy5lbmNvZGVTZWVkKEJ1ZmZlci5mcm9tKGtleVBhaXIuZ2V0U2lnbmluZ0tleSgpKSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgcHVibGljIGtleSBmb3IgdGhlIGNvaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwdWIgdGhlIHB1YiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRQdWIocHViOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMuaXNWYWxpZEFkZHJlc3MocHViKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgc2VlZCBmb3IgdGhlIGNvaW5cbiAgICogSW4gQWxnb3JhbmQsIHdoZW4gdGhlIHByaXZhdGUga2V5IGlzIGVuY29kZWQgYXMgYmFzZTMyIHN0cmluZyBvbmx5IHRoZSBmaXJzdCAzMiBieXRlcyBhcmUgdGFrZW4sXG4gICAqIHNvIHRoZSBlbmNvZGVkIHZhbHVlIGlzIGFjdHVhbGx5IHRoZSBzZWVkXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcnYgdGhlIHBydiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRQcnYocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMuaXNWYWxpZFNlZWQocHJ2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgcHVibGljIGtleSBmb3IgdGhlIGNvaW5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3MgdGhlIHB1YiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBBbGdvTGliLmFsZ29VdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIG1lc3NhZ2Ugd2l0aCBwcml2YXRlIGtleVxuICAgKlxuICAgKiBAcGFyYW0ga2V5XG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqL1xuICBhc3luYyBzaWduTWVzc2FnZShrZXk6IEtleVBhaXIsIG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgYWxnb0tleXBhaXIgPSBuZXcgQWxnb0xpYi5LZXlQYWlyKHsgcHJ2OiBrZXkucHJ2IH0pO1xuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIobWVzc2FnZSkpIHtcbiAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICB9XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGFsZ29LZXlwYWlyLnNpZ25NZXNzYWdlKG1lc3NhZ2UpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hhdCBrZXkgd2Ugd2lsbCBuZWVkIGZvciBzaWduaW5nYCAtIEFsZ29yYW5kIG5lZWRzIHRoZSBiYWNrdXAsIGJpdGdvIHB1YnMuXG4gICAqL1xuICBrZXlJZHNGb3JTaWduaW5nKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gW0tleUluZGljZXMuVVNFUiwgS2V5SW5kaWNlcy5CQUNLVVAsIEtleUluZGljZXMuQklUR09dO1xuICB9XG5cbiAgZ2V0VG9rZW5OYW1lQnlJZCh0b2tlbklkOiBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHRva2VuTmFtZXMgPSBjb2lucy5maWx0ZXIoKGNvaW4pID0+IGNvaW4uZmFtaWx5ID09PSAnYWxnbycgJiYgY29pbi5pc1Rva2VuKS5tYXAoKHsgbmFtZSB9KSA9PiBuYW1lISk7XG4gICAgcmV0dXJuIHRva2VuTmFtZXMuZmluZCgodG9rZW5OYW1lKSA9PiB0b2tlbk5hbWUuc3BsaXQoJy0nKVsxXSA9PT0gYCR7dG9rZW5JZH1gKSB8fCAnQWxnb1Rva2VuIHVua25vd24nO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4vcGFyc2UgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8QWxnb1RyYW5zYWN0aW9uRXhwbGFuYXRpb24gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB0eEhleCA9IHBhcmFtcy50eEhleCB8fCAocGFyYW1zLmhhbGZTaWduZWQgJiYgcGFyYW1zLmhhbGZTaWduZWQudHhIZXgpO1xuICAgIGlmICghdHhIZXggfHwgIXBhcmFtcy5mZWVJbmZvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgZXhwbGFpbiB0eCBwYXJhbWV0ZXJzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuXG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuXG4gICAgaWYgKHR4LnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TZW5kKSB7XG4gICAgICBjb25zdCBvdXRwdXRzOiBUcmFuc2FjdGlvblJlY2lwaWVudFtdID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogdHhKc29uLnRvLFxuICAgICAgICAgIGFtb3VudDogdHhKc29uLmFtb3VudCxcbiAgICAgICAgICBtZW1vOiB0eEpzb24ubm90ZSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBvcGVyYXRpb25zOiBUcmFuc2FjdGlvbk9wZXJhdGlvbltdID0gW107XG5cbiAgICAgIGNvbnN0IGlzVG9rZW5UeCA9IHRoaXMuaXNUb2tlblR4KHR4SnNvbi50eXBlKTtcbiAgICAgIGlmIChpc1Rva2VuVHgpIHtcbiAgICAgICAgY29uc3QgdHlwZSA9IEFsZ29MaWIuYWxnb1V0aWxzLmdldFRva2VuVHhUeXBlKHR4SnNvbi5hbW91bnQsIHR4SnNvbi5mcm9tLCB0eEpzb24udG8sIHR4SnNvbi5jbG9zZVJlbWFpbmRlclRvKTtcbiAgICAgICAgb3BlcmF0aW9ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgIGNvaW46IHRoaXMuZ2V0VG9rZW5OYW1lQnlJZCh0eEpzb24udG9rZW5JZCksXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAgICdpZCcsXG4gICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICdmZWUnLFxuICAgICAgICAnbWVtbycsXG4gICAgICAgICd0eXBlJyxcbiAgICAgICAgJ29wZXJhdGlvbnMnLFxuICAgICAgXTtcblxuICAgICAgY29uc3QgZXhwbGFuYXRpb25SZXN1bHQ6IEFsZ29UcmFuc2FjdGlvbkV4cGxhbmF0aW9uID0ge1xuICAgICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICAgIGlkOiB0eEpzb24uaWQsXG4gICAgICAgIG91dHB1dEFtb3VudDogdHhKc29uLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0cyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGZlZTogdHhKc29uLmZlZSxcbiAgICAgICAgbWVtbzogdHhKc29uLm5vdGUsXG4gICAgICAgIHR5cGU6IHR4LnR5cGUudG9TdHJpbmcoKSxcbiAgICAgICAgb3BlcmF0aW9ucyxcbiAgICAgIH07XG5cbiAgICAgIGlmICh0eEpzb24udG9rZW5JZCkge1xuICAgICAgICBleHBsYW5hdGlvblJlc3VsdC50b2tlbklkID0gdHhKc29uLnRva2VuSWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBleHBsYW5hdGlvblJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAodHgudHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uKSB7XG4gICAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAgICdpZCcsXG4gICAgICAgICdmZWUnLFxuICAgICAgICAnbWVtbycsXG4gICAgICAgICd0eXBlJyxcbiAgICAgICAgJ3ZvdGVLZXknLFxuICAgICAgICAnc2VsZWN0aW9uS2V5JyxcbiAgICAgICAgJ3ZvdGVGaXJzdCcsXG4gICAgICAgICd2b3RlTGFzdCcsXG4gICAgICAgICd2b3RlS2V5RGlsdXRpb24nLFxuICAgICAgXTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGlzcGxheU9yZGVyLFxuICAgICAgICBpZDogdHhKc29uLmlkLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgZmVlOiB0eEpzb24uZmVlLFxuICAgICAgICBtZW1vOiB0eEpzb24ubm90ZSxcbiAgICAgICAgdHlwZTogdHgudHlwZSxcbiAgICAgICAgdm90ZUtleTogdHhKc29uLnZvdGVLZXksXG4gICAgICAgIHNlbGVjdGlvbktleTogdHhKc29uLnNlbGVjdGlvbktleSxcbiAgICAgICAgdm90ZUZpcnN0OiB0eEpzb24udm90ZUZpcnN0LFxuICAgICAgICB2b3RlTGFzdDogdHhKc29uLnZvdGVMYXN0LFxuICAgICAgICB2b3RlS2V5RGlsdXRpb246IHR4SnNvbi52b3RlS2V5RGlsdXRpb24sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm5zIGlmIGEgdHggaXMgYSB0b2tlbiB0eFxuICAgKiBAcGFyYW0gdHlwZSB7c3RyaW5nfSAtIHR4IHR5cGVcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBpdCdzIGEgdG9rZW4gdHhcbiAgICovXG4gIGlzVG9rZW5UeCh0eXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHlwZSA9PT0gJ2F4ZmVyJztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHNlZWQgaXMgYSB2YWxpZCBzdGVsbGFyIHNlZWRcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNlZWQgdGhlIHNlZWQgdG8gY2hlY2tcbiAgICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIGlucHV0IGlzIGEgU3RlbGxhciBzZWVkXG4gICAqL1xuICBpc1N0ZWxsYXJTZWVkKHNlZWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBTZWVkVmFsaWRhdG9yLmlzVmFsaWRFZDI1NTE5U2VlZEZvckNvaW4oc2VlZCwgQ29pbkZhbWlseS5YTE0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdGVsbGFyIHNlZWQgdG8gYW4gYWxnbyBzZWVkXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzZWVkIHRoZSBzZWVkIHRvIGNvbnZlcnRcbiAgICogQHJldHVybnMge0Jvb2xlYW4gfCBudWxsfSBzZWVkIGluIGFsZ28gZW5jb2RpbmdcbiAgICovXG4gIGNvbnZlcnRGcm9tU3RlbGxhclNlZWQoc2VlZDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gYXNzdW1lIHRoaXMgaXMgYSB0cnVzdCBjdXN0b2RpYWwgc2VlZCBpZiBpdHMgYSB2YWxpZCBlZDI1NTE5IHBydlxuICAgIGlmICghdGhpcy5pc1N0ZWxsYXJTZWVkKHNlZWQpIHx8IFNlZWRWYWxpZGF0b3IuaGFzQ29tcGV0aW5nU2VlZEZvcm1hdHMoc2VlZCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChTZWVkVmFsaWRhdG9yLmlzVmFsaWRFZDI1NTE5U2VlZEZvckNvaW4oc2VlZCwgQ29pbkZhbWlseS5YTE0pKSB7XG4gICAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMuY29udmVydEZyb21TdGVsbGFyU2VlZChzZWVkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZlcmlmeVNpZ25UcmFuc2FjdGlvblBhcmFtcyhwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBWZXJpZmllZFRyYW5zYWN0aW9uUGFyYW1ldGVycyB7XG4gICAgY29uc3QgcHJ2ID0gcGFyYW1zLnBydjtcbiAgICBjb25zdCBhZGRyZXNzVmVyc2lvbiA9IHBhcmFtcy50eFByZWJ1aWxkLmFkZHJlc3NWZXJzaW9uO1xuICAgIGxldCBpc0hhbGZTaWduZWQgPSBmYWxzZTtcblxuICAgIC8vIGl0J3MgcG9zc2libGUgdGhpcyB0eCB3YXMgYWxyZWFkeSBzaWduZWQgLSB0YWtlIHRoZSBoYWxmU2lnbmVkXG4gICAgLy8gdHhIZXggaWYgaXQgaXNcbiAgICBsZXQgdHhIZXggPSBwYXJhbXMudHhQcmVidWlsZC50eEhleDtcbiAgICBpZiAocGFyYW1zLnR4UHJlYnVpbGQuaGFsZlNpZ25lZCkge1xuICAgICAgaXNIYWxmU2lnbmVkID0gdHJ1ZTtcbiAgICAgIHR4SGV4ID0gcGFyYW1zLnR4UHJlYnVpbGQuaGFsZlNpZ25lZC50eEhleDtcbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZCh0eEhleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFByZWJ1aWxkIHBhcmFtZXRlcicpO1xuICAgIH1cblxuICAgIGlmICghXy5pc1N0cmluZyh0eEhleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHhQcmVidWlsZCBtdXN0IGJlIGFuIG9iamVjdCwgZ290IHR5cGUgJHt0eXBlb2YgdHhIZXh9YCk7XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQocHJ2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHBydiBwYXJhbWV0ZXIgdG8gc2lnbiB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGlmICghXy5pc1N0cmluZyhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHBydiBtdXN0IGJlIGEgc3RyaW5nLCBnb3QgdHlwZSAke3R5cGVvZiBwcnZ9YCk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmhhcyhwYXJhbXMudHhQcmVidWlsZCwgJ2tleXMnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHB1YmxpYyBrZXlzIHBhcmFtZXRlciB0byBzaWduIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzTnVtYmVyKGFkZHJlc3NWZXJzaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGFkZHJlc3NWZXJzaW9uIHBhcmFtZXRlciB0byBzaWduIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2lnbmVycyA9IHBhcmFtcy50eFByZWJ1aWxkLmtleXMubWFwKChrZXkpID0+IHtcbiAgICAgIC8vIGlmIHdlIGFyZSByZWNlaXZpbmcgYWRkcmVzc2VzIGRvIG5vdCB0cnkgdG8gY29udmVydCB0aGVtXG4gICAgICBpZiAoIUFsZ29MaWIuYWxnb1V0aWxzLmlzVmFsaWRBZGRyZXNzKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIEFsZ29MaWIuYWxnb1V0aWxzLnB1YmxpY0tleVRvQWxnb0FkZHJlc3MoQWxnb0xpYi5hbGdvVXRpbHMudG9VaW50OEFycmF5KGtleSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGtleTtcbiAgICB9KTtcbiAgICAvLyBUT0RPKGh0dHBzOi8vYml0Z29pbmMuYXRsYXNzaWFuLm5ldC9icm93c2UvU1RMWC02MDY3KTogZml4IHRoZSBudW1iZXIgb2Ygc2lnbmVycyB1c2luZ1xuICAgIC8vIHNob3VsZCBiZSBzaW1pbGFyIHRvIG90aGVyIGNvaW5zIGltcGxlbWVudGF0aW9uXG4gICAgLy8gSWYgd2UgaGF2ZSBhIG51bWJlciB3aXRoIGRpZ2l0cyB0byBlbGltaW5hdGUgdGhlbSB3aXRob3V0IHRha2luZyBhbnkgcm91bmRpbmcgY3JpdGVyaWEuXG4gICAgY29uc3QgbnVtYmVyU2lnbmVycyA9IE1hdGgudHJ1bmMoc2lnbmVycy5sZW5ndGggLyAyKSArIDE7XG4gICAgcmV0dXJuIHsgdHhIZXgsIGFkZHJlc3NWZXJzaW9uLCBzaWduZXJzLCBwcnYsIGlzSGFsZlNpZ25lZCwgbnVtYmVyU2lnbmVycyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge1RyYW5zYWN0aW9uUHJlYnVpbGR9IHByZWJ1aWxkIG9iamVjdCByZXR1cm5lZCBieSBwbGF0Zm9ybVxuICAgKiBAcGFyYW0gcGFyYW1zLnBydiB7U3RyaW5nfSB1c2VyIHBydlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj59XG4gICAqL1xuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBTaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHsgdHhIZXgsIHNpZ25lcnMsIHBydiwgaXNIYWxmU2lnbmVkLCBudW1iZXJTaWduZXJzIH0gPSB0aGlzLnZlcmlmeVNpZ25UcmFuc2FjdGlvblBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odHhIZXgpO1xuICAgIHR4QnVpbGRlci5udW1iZXJPZlJlcXVpcmVkU2lnbmVycyhudW1iZXJTaWduZXJzKTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogcHJ2IH0pO1xuICAgIHR4QnVpbGRlci5zZXRTaWduZXJzKHNpZ25lcnMpO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIGNvbnN0IHNpZ25lZFR4SGV4ID0gQnVmZmVyLmZyb20odHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGlmIChudW1iZXJTaWduZXJzID09PSAxKSB7XG4gICAgICByZXR1cm4geyB0eEhleDogc2lnbmVkVHhIZXggfTtcbiAgICB9IGVsc2UgaWYgKGlzSGFsZlNpZ25lZCkge1xuICAgICAgcmV0dXJuIHsgdHhIZXg6IHNpZ25lZFR4SGV4IH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IGhhbGZTaWduZWQ6IHsgdHhIZXg6IHNpZ25lZFR4SGV4IH0gfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBwYXJzZVRyYW5zYWN0aW9uKHBhcmFtczogUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFBhcnNlZFRyYW5zYWN0aW9uPiB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFkZHJlc3MgY2FuIGJlIHVzZWQgdG8gc2VuZCBmdW5kcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcy5hZGRyZXNzIGFkZHJlc3MgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHBhcmFtcy5rZXljaGFpbnMgcHVibGljIGtleXMgdG8gZ2VuZXJhdGUgdGhlIHdhbGxldFxuICAgKi9cbiAgYXN5bmMgaXNXYWxsZXRBZGRyZXNzKHBhcmFtczogVmVyaWZ5QWxnb0FkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qge1xuICAgICAgYWRkcmVzcyxcbiAgICAgIGtleWNoYWlucyxcbiAgICAgIGNvaW5TcGVjaWZpYzogeyBiaXRnb1B1YktleSB9LFxuICAgIH0gPSBwYXJhbXM7XG5cbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBpbnZhbGlkIGFkZHJlc3M6ICR7YWRkcmVzc31gKTtcbiAgICB9XG5cbiAgICBpZiAoIWtleWNoYWlucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucycpO1xuICAgIH1cblxuICAgIGNvbnN0IGVmZmVjdGl2ZUtleWNoYWluID0gYml0Z29QdWJLZXkgPyBrZXljaGFpbnMuc2xpY2UoMCwgLTEpLmNvbmNhdChbeyBwdWI6IGJpdGdvUHViS2V5IH1dKSA6IGtleWNoYWlucztcbiAgICBjb25zdCBwdWJLZXlzID0gZWZmZWN0aXZlS2V5Y2hhaW4ubWFwKChrZXkpID0+IHRoaXMuc3RlbGxhckFkZHJlc3NUb0FsZ29BZGRyZXNzKGtleS5wdWIpKTtcblxuICAgIGlmICghcHViS2V5cy5ldmVyeSgocHViS2V5KSA9PiB0aGlzLmlzVmFsaWRQdWIocHViS2V5KSkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5KCdpbnZhbGlkIHB1YmxpYyBrZXknKTtcbiAgICB9XG5cbiAgICBjb25zdCByb290QWRkcmVzcyA9IEFsZ29MaWIuYWxnb1V0aWxzLm11bHRpc2lnQWRkcmVzcyhTVVBQT1JURURfQUREUkVTU19WRVJTSU9OLCBNU0lHX1RIUkVTSE9MRCwgcHViS2V5cyk7XG5cbiAgICByZXR1cm4gcm9vdEFkZHJlc3MgPT09IGFkZHJlc3M7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0RG9jICovXG4gIGRlcml2ZUtleVdpdGhTZWVkKHsga2V5LCBzZWVkIH06IHsga2V5OiBzdHJpbmc7IHNlZWQ6IHN0cmluZyB9KTogeyBkZXJpdmF0aW9uUGF0aDogc3RyaW5nOyBrZXk6IHN0cmluZyB9IHtcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aElucHV0ID0gdXR4b2xpYi5jcnlwdG8uaGFzaDI1NihCdWZmZXIuZnJvbShzZWVkLCAndXRmOCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgZGVyaXZhdGlvblBhdGhQYXJ0cyA9IFtcbiAgICAgIDk5OTk5OSxcbiAgICAgIHBhcnNlSW50KGRlcml2YXRpb25QYXRoSW5wdXQuc2xpY2UoMCwgNyksIDE2KSxcbiAgICAgIHBhcnNlSW50KGRlcml2YXRpb25QYXRoSW5wdXQuc2xpY2UoNywgMTQpLCAxNiksXG4gICAgXTtcbiAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLycgKyBkZXJpdmF0aW9uUGF0aFBhcnRzLm1hcCgocGFydCkgPT4gYCR7cGFydH0nYCkuam9pbignLycpO1xuICAgIGNvbnN0IGRlcml2ZWRLZXkgPSBFZDI1NTE5S2V5RGVyaXZlci5kZXJpdmVQYXRoKGRlcml2YXRpb25QYXRoLCBrZXkpLmtleTtcbiAgICBjb25zdCBrZXlwYWlyID0gbmV3IEFsZ29MaWIuS2V5UGFpcih7IHNlZWQ6IGRlcml2ZWRLZXkgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleToga2V5cGFpci5nZXRBZGRyZXNzKCksXG4gICAgICBkZXJpdmF0aW9uUGF0aCxcbiAgICB9O1xuICB9XG5cbiAgZGVjb2RlVHgodHhuOiBCdWZmZXIpOiB1bmtub3duIHtcbiAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMuZGVjb2RlQWxnb1R4bih0eG4pO1xuICB9XG5cbiAgZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkocHViS2V5OiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMucHVibGljS2V5VG9BbGdvQWRkcmVzcyhwdWJLZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0ZWxsYXIgYW5kIEFsZ29yYW5kIGJvdGggdXNlIGtleXMgb24gdGhlIGVkMjU1MTkgY3VydmUsIGJ1dCB1c2UgZGlmZmVyZW50IGVuY29kaW5ncy5cbiAgICogQXMgdGhlIEhTTSBkb2Vzbid0IGhhdmUgZXhwbGljaXQgc3VwcG9ydCB0byBjcmVhdGUgQWxnb3JhbmQgYWRkcmVzc2VzLCB3ZSB1c2UgdGhlIFN0ZWxsYXJcbiAgICoga2V5cyBhbmQgcmUtZW5jb2RlIHRoZW0gdG8gdGhlIEFsZ29yYW5kIGVuY29kaW5nLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gY3JlYXRpbmcgQWxnb3JhbmQgY3VzdG9kaWFsIHdhbGxldHMgcmV1c2luZyBTdGVsbGFyIGtleXMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzT3JQdWJLZXkgYSBTdGVsbGFyIHB1YmtleSBvciBBbGdvcmFuZCBhZGRyZXNzXG4gICAqIEByZXR1cm4geyp9XG4gICAqL1xuICBwcml2YXRlIHN0ZWxsYXJBZGRyZXNzVG9BbGdvQWRkcmVzcyhhZGRyZXNzT3JQdWJLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzc09yUHViS2V5KSkge1xuICAgICAgLy8gd2UgaGF2ZSBhbiBBbGdvcmFuZCBhZGRyZXNzXG4gICAgICByZXR1cm4gYWRkcmVzc09yUHViS2V5O1xuICAgIH1cblxuICAgIGlmICghc3RlbGxhci5TdHJLZXkuaXNWYWxpZEVkMjU1MTlQdWJsaWNLZXkoYWRkcmVzc09yUHViS2V5KSkge1xuICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IoJ05laXRoZXIgYW4gQWxnb3JhbmQgYWRkcmVzcyBub3IgYSBzdGVsbGFyIHB1YmtleS4nKTtcbiAgICB9XG5cbiAgICAvLyB3ZSBoYXZlIGEgc3RlbGxhciBrZXlcbiAgICBjb25zdCBzdGVsbGFyUHViID0gc3RlbGxhci5TdHJLZXkuZGVjb2RlRWQyNTUxOVB1YmxpY0tleShhZGRyZXNzT3JQdWJLZXkpO1xuICAgIGNvbnN0IGFsZ29BZGRyZXNzID0gQWxnb0xpYi5hbGdvVXRpbHMuZW5jb2RlQWRkcmVzcyhzdGVsbGFyUHViKTtcblxuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhhbGdvQWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKCdDYW5ub3QgY29udmVydCBTdGVsbGFyIGFkZHJlc3MgdG8gYW4gQWxnb3JhbmQgYWRkcmVzcyB2aWEgcHVia2V5LicpO1xuICAgIH1cblxuICAgIHJldHVybiBhbGdvQWRkcmVzcztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QnVpbGRlcigpOiBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3Rvcnkge1xuICAgIHJldHVybiBuZXcgQWxnb0xpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldEJhc2VDaGFpbigpKSk7XG4gIH1cbn1cbiJdfQ==
803
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxnby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hbGdvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztHQUVHO0FBQ0gsMENBQTRCO0FBQzVCLG1EQUFnRDtBQUNoRCxpREFBd0Q7QUFDeEQsK0NBQWlDO0FBQ2pDLG1EQTBCOEI7QUFDOUIsOERBQWtDO0FBQ2xDLGdFQUFxQztBQUNyQyx3REFBZ0M7QUFFaEMsaURBQW1DO0FBQ25DLGlFQUtrQztBQUNsQyxtQ0FBZ0M7QUFDaEMsbUNBQWtDO0FBRWxDLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQyxDQUFDLGNBQWM7QUFpSnhDLE1BQWEsSUFBSyxTQUFRLG1CQUFRO0lBSWhDLFlBQVksS0FBZ0I7UUFDMUIsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBSk4saUJBQVksR0FBd0IsYUFBYSxDQUFDO1FBQ2xELGtCQUFhLEdBQXdCLGNBQWMsQ0FBQztJQUk3RCxDQUFDO0lBRUQsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFnQjtRQUNwQyxPQUFPLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxRQUFRO1FBQ04sT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELFlBQVk7UUFDVixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsU0FBUztRQUNQLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxXQUFXO1FBQ1QsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVELGFBQWE7UUFDWCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFRDs7O09BR0c7SUFDSCx3QkFBd0I7UUFDdEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsMkJBQTJCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGlCQUFpQjtJQUNqQixpQkFBaUI7UUFDZixNQUFNLElBQUksdUJBQVksQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFRCxpQkFBaUI7SUFDakIsZUFBZSxDQUFDLElBQWE7UUFDM0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM3RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBRUQsT0FBTztZQUNMLEdBQUcsRUFBRSxPQUFPLENBQUMsVUFBVSxFQUFFO1lBQ3pCLEdBQUcsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxlQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDO1NBQ3hFLENBQUM7SUFDSixDQUFDO0lBRUQsaUJBQWlCO0lBQ2pCLG1CQUFtQixDQUFDLElBQWE7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM3RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUNwRCxDQUFDO1FBQ0QsT0FBTyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxVQUFVLENBQUMsR0FBVztRQUNwQixPQUFPLE9BQU8sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxVQUFVLENBQUMsR0FBVztRQUNwQixPQUFPLE9BQU8sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEYsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsY0FBYyxDQUFDLE9BQWU7UUFDNUIsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVksRUFBRSxPQUF3QjtRQUN0RCxNQUFNLFdBQVcsR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBSSxlQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkMsQ0FBQztRQUNELE9BQU8sZUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsZ0JBQWdCO1FBQ2QsT0FBTyxDQUFDLHFCQUFVLENBQUMsSUFBSSxFQUFFLHFCQUFVLENBQUMsTUFBTSxFQUFFLHFCQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVELGdCQUFnQixDQUFDLE9BQXdCO1FBQ3ZDLE1BQU0sVUFBVSxHQUFHLGVBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFLLENBQUMsQ0FBQztRQUMzRyxPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxPQUFPLEVBQUUsQ0FBQyxJQUFJLG1CQUFtQixDQUFDO0lBQ3pHLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBaUM7UUFDeEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3RSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBRWxDLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdEMsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRTNCLElBQUksRUFBRSxDQUFDLElBQUksS0FBSywwQkFBZSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3JDLE1BQU0sT0FBTyxHQUEyQjtnQkFDdEM7b0JBQ0UsT0FBTyxFQUFFLE1BQU0sQ0FBQyxFQUFFO29CQUNsQixNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU07b0JBQ3JCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtpQkFDbEI7YUFDRixDQUFDO1lBQ0YsTUFBTSxVQUFVLEdBQTJCLEVBQUUsQ0FBQztZQUU5QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM5QyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUM5RyxVQUFVLENBQUMsSUFBSSxDQUFDO29CQUNkLElBQUksRUFBRSxJQUFJO29CQUNWLElBQUksRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztpQkFDNUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELE1BQU0sWUFBWSxHQUFHO2dCQUNuQixJQUFJO2dCQUNKLGNBQWM7Z0JBQ2QsY0FBYztnQkFDZCxTQUFTO2dCQUNULGVBQWU7Z0JBQ2YsS0FBSztnQkFDTCxNQUFNO2dCQUNOLE1BQU07Z0JBQ04sWUFBWTthQUNiLENBQUM7WUFFRixNQUFNLGlCQUFpQixHQUErQjtnQkFDcEQsWUFBWTtnQkFDWixFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7Z0JBQ2IsWUFBWSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO2dCQUN0QyxZQUFZLEVBQUUsR0FBRztnQkFDakIsT0FBTztnQkFDUCxhQUFhLEVBQUUsRUFBRTtnQkFDakIsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHO2dCQUNmLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtnQkFDakIsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUN4QixVQUFVO2FBQ1gsQ0FBQztZQUVGLElBQUksTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNuQixpQkFBaUIsQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztZQUM3QyxDQUFDO1lBRUQsT0FBTyxpQkFBaUIsQ0FBQztRQUMzQixDQUFDO1FBRUQsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLDBCQUFlLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUNyRCxNQUFNLFlBQVksR0FBRztnQkFDbkIsSUFBSTtnQkFDSixLQUFLO2dCQUNMLE1BQU07Z0JBQ04sTUFBTTtnQkFDTixTQUFTO2dCQUNULGNBQWM7Z0JBQ2QsV0FBVztnQkFDWCxVQUFVO2dCQUNWLGlCQUFpQjthQUNsQixDQUFDO1lBRUYsT0FBTztnQkFDTCxZQUFZO2dCQUNaLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRTtnQkFDYixZQUFZLEVBQUUsR0FBRztnQkFDakIsWUFBWSxFQUFFLEdBQUc7Z0JBQ2pCLE9BQU8sRUFBRSxFQUFFO2dCQUNYLGFBQWEsRUFBRSxFQUFFO2dCQUNqQixHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUc7Z0JBQ2YsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNqQixJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUk7Z0JBQ2IsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixZQUFZLEVBQUUsTUFBTSxDQUFDLFlBQVk7Z0JBQ2pDLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUztnQkFDM0IsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRO2dCQUN6QixlQUFlLEVBQUUsTUFBTSxDQUFDLGVBQWU7YUFDeEMsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFNBQVMsQ0FBQyxJQUFZO1FBQ3BCLE9BQU8sSUFBSSxLQUFLLE9BQU8sQ0FBQztJQUMxQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxhQUFhLENBQUMsSUFBWTtRQUN4QixPQUFPLDZCQUFhLENBQUMseUJBQXlCLENBQUMsSUFBSSxFQUFFLG9CQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsc0JBQXNCLENBQUMsSUFBWTtRQUNqQyxtRUFBbUU7UUFDbkUsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksNkJBQWEsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzdFLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELElBQUksNkJBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLEVBQUUsb0JBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2xFLE9BQU8sT0FBTyxDQUFDLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsMkJBQTJCLENBQUMsTUFBOEI7UUFDeEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQztRQUN2QixNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQztRQUN4RCxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7UUFFekIsaUVBQWlFO1FBQ2pFLGlCQUFpQjtRQUNqQixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUNwQyxJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDakMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUNwQixLQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBQzdDLENBQUM7UUFFRCxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUVELElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsT0FBTyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzVFLENBQUM7UUFFRCxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUVELElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQ0FBa0MsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7UUFFRCxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDdEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFFRCxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDakQsMkRBQTJEO1lBQzNELElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMzQyxPQUFPLE9BQU8sQ0FBQyxTQUFTLENBQUMsc0JBQXNCLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN2RixDQUFDO1lBQ0QsT0FBTyxHQUFHLENBQUM7UUFDYixDQUFDLENBQUMsQ0FBQztRQUNILHlGQUF5RjtRQUN6RixrREFBa0Q7UUFDbEQsMEZBQTBGO1FBQzFGLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekQsT0FBTyxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLENBQUM7SUFDOUUsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsZUFBZSxDQUFDLE1BQThCO1FBQ2xELE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RHLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNqRCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDN0IsU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QixNQUFNLFdBQVcsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM1QyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFDRCxNQUFNLFdBQVcsR0FBRyxlQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BGLElBQUksYUFBYSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDaEMsQ0FBQzthQUFNLElBQUksWUFBWSxFQUFFLENBQUM7WUFDeEIsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUNoQyxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEVBQUUsQ0FBQztRQUNoRCxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxNQUErQjtRQUNwRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBZ0M7UUFDcEQsTUFBTSxFQUNKLE9BQU8sRUFDUCxTQUFTLEVBQ1QsWUFBWSxFQUFFLEVBQUUsV0FBVyxFQUFFLEdBQzlCLEdBQUcsTUFBTSxDQUFDO1FBRVgsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksOEJBQW1CLENBQUMsb0JBQW9CLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUVELElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBRUQsTUFBTSxpQkFBaUIsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDMUcsTUFBTSxPQUFPLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFMUYsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3hELE1BQU0sSUFBSSxxQkFBVSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLHlCQUF5QixFQUFFLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUUxRyxPQUFPLFdBQVcsS0FBSyxPQUFPLENBQUM7SUFDakMsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFnQztRQUN0RCxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBRTlELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7UUFDakQsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQyxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxNQUFNLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFM0Isa0RBQWtEO1FBQ2xELE1BQU0sbUJBQW1CLEdBQUcsUUFBUSxDQUFDLElBQUksS0FBSyxhQUFhLENBQUM7UUFFNUQsOENBQThDO1FBQzlDLElBQUksbUJBQW1CLElBQUksWUFBWSxFQUFFLHFCQUFxQixFQUFFLENBQUM7WUFDL0Qsd0NBQXdDO1lBQ3hDLElBQUksQ0FBQyxrQ0FBa0MsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDNUQsQ0FBQzthQUFNLENBQUM7WUFDTixRQUFRLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDcEIsS0FBSyxLQUFLO29CQUNSLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7b0JBQzlDLE1BQU07Z0JBQ1IsS0FBSyxPQUFPO29CQUNWLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7b0JBQ3hELE1BQU07Z0JBQ1I7b0JBQ0Usd0RBQXdEO29CQUN4RCxJQUFJLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ3RDLE1BQU07WUFDVixDQUFDO1FBQ0gsQ0FBQztRQUVELHlEQUF5RDtRQUN6RCxJQUFJLFlBQVksRUFBRSwwQkFBMEIsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUM7Z0JBQ3pDLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztZQUN4RSxDQUFDO1lBQ0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFlBQVksRUFBRSxFQUFFLFdBQXFCLENBQUM7WUFFakUsMkRBQTJEO1lBQzNELElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1lBQzlELENBQUM7WUFFRCxJQUFJLE1BQU0sQ0FBQyxFQUFFLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQzlCLE1BQU0sSUFBSSxnQ0FBcUIsQ0FDN0Isd0VBQXdFLEVBQ3hFLE1BQU0sQ0FBQyxFQUFFLEVBQ1QsQ0FBQyxRQUFRLENBQUMsRUFDVixNQUFNLENBQ1AsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSyx3QkFBd0IsQ0FBQyxNQUFXO1FBQzFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQ2pFLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxNQUFNLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUN0RCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssc0JBQXNCLENBQUMsTUFBVyxFQUFFLFFBQWE7UUFDdkQsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXRDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7UUFDcEUsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUVELDhDQUE4QztRQUM5QyxJQUFJLFFBQVEsQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDMUQsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxJQUFJLEtBQUssQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO1lBQ3ZFLENBQUM7WUFFRCxNQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakQsTUFBTSxjQUFjLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzNELE1BQU0sZUFBZSxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQztZQUNsRCxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzlDLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFFaEMsSUFBSSxjQUFjLEtBQUssWUFBWSxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sSUFBSSxLQUFLLENBQUMsMkVBQTJFLENBQUMsQ0FBQztZQUMvRixDQUFDO1lBRUQsSUFBSSxlQUFlLENBQUMsV0FBVyxFQUFFLEtBQUssYUFBYSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQ2xFLE1BQU0sSUFBSSxLQUFLLENBQUMsK0RBQStELENBQUMsQ0FBQztZQUNuRixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0NBQWdDLENBQUMsTUFBVyxFQUFFLFFBQWE7UUFDakUsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXRDLHFDQUFxQztRQUNyQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSyxzQkFBc0IsQ0FBQyxTQUFpQjtRQUM5QyxrRUFBa0U7UUFDbEUsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsbURBQW1EO1FBQ25ELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzQiwyQ0FBMkM7UUFDM0MsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuRCxJQUFJLGVBQWUsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzVELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFekMsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7T0FFRztJQUNLLGtDQUFrQyxDQUFDLE1BQVcsRUFBRSxRQUFhO1FBQ25FLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV0QyxvREFBb0Q7UUFDcEQsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUNqRixDQUFDO1FBRUQsZ0RBQWdEO1FBQ2hELElBQUksSUFBQSxpQkFBUSxFQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksS0FBSyxDQUFDLHlFQUF5RSxDQUFDLENBQUM7UUFDN0YsQ0FBQztRQUVELDhEQUE4RDtRQUM5RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDNUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxxRkFBcUYsQ0FBQyxDQUFDO1FBQ3pHLENBQUM7UUFFRCw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLHdEQUF3RCxDQUFDLENBQUM7UUFDNUUsQ0FBQztRQUVELHVFQUF1RTtRQUN2RSxJQUFJLGVBQWUsR0FBa0IsSUFBSSxDQUFDO1FBRTFDLHFEQUFxRDtRQUNyRCxJQUFJLFFBQVEsQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLElBQUksUUFBUSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEcsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDaEQsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDZCxlQUFlLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDO1FBQ0Qsc0VBQXNFO2FBQ2pFLElBQUksUUFBUSxDQUFDLFVBQVUsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyRyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUN4QixlQUFlLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNyRSxDQUFDO1FBQ0gsQ0FBQztRQUVELDJEQUEyRDtRQUMzRCxJQUFJLGVBQWUsS0FBSyxJQUFJLElBQUksTUFBTSxDQUFDLE9BQU8sS0FBSyxlQUFlLEVBQUUsQ0FBQztZQUNuRSxNQUFNLElBQUksS0FBSyxDQUNiLDJEQUEyRCxlQUFlLGlDQUFpQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQzVILENBQUM7UUFDSixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsUUFBUSxDQUFDLEdBQVc7UUFDbEIsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsdUJBQXVCLENBQUMsTUFBa0I7UUFDeEMsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCx5QkFBeUI7UUFDdkIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsb0JBQW9CO0lBQ3BCLHNCQUFzQjtRQUNwQixPQUFPLHdCQUFhLENBQUMsT0FBTyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILHdCQUF3QjtRQUN0QixPQUFPO1lBQ0wsdUJBQXVCLEVBQUUsSUFBSTtZQUM3QixnQ0FBZ0MsRUFBRSxLQUFLO1NBQ3hDLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsaUJBQWlCLENBQUMsV0FBbUIsRUFBRSxNQUF1QjtRQUNsRSxNQUFNLGtCQUFrQixHQUFHLE1BQU0sTUFBTSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzdFLG1EQUFtRDtRQUNuRCxPQUFPLGtCQUFrQixDQUFDLE1BQU0sQ0FBQztJQUNuQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsU0FBUyxDQUFDLEtBQWEsRUFBRSxVQUFrQixFQUFFLElBQVk7UUFDdkQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUF1QjtRQUMxQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUU3RixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztRQUNwRixDQUFDO1FBRUQsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQzdDLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7UUFFRCxtQ0FBbUM7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQztZQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3JGLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLElBQUksSUFBSSxzQkFBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO1lBQ3ZFLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLHVDQUFrQixDQUFDLENBQUMsQ0FBQyx1Q0FBa0IsQ0FBQztRQUMzRixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMseUNBQW9CLENBQUMsQ0FBQyxDQUFDLHlDQUFvQixDQUFDO1FBRWpHLGVBQUssQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMseUJBQXlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBRS9DLElBQUksT0FBMkIsQ0FBQztRQUNoQyxJQUFJLFNBQTZCLENBQUM7UUFDbEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztZQUMxRixDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNILE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO2dCQUMzRixTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQztnQkFDL0YsTUFBTSxjQUFjLEdBQUcsZUFBSyxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM5RCxNQUFNLGdCQUFnQixHQUFHLGVBQUssQ0FBQyx1QkFBdUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDbEUsU0FBUyxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUN2RyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDWCxNQUFNLElBQUksS0FBSyxDQUNiLHdGQUF3RixHQUFHLENBQUMsQ0FBQyxPQUFPLENBQ3JHLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3RyxNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRS9FLHFEQUFxRDtRQUNyRCxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQztRQUN0QyxNQUFNLGVBQWUsR0FBRyxJQUFJLHNCQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUVoSCxJQUFJLElBQUksc0JBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxJQUFJLHNCQUFTLENBQUMsZUFBZSxDQUFDLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUcsTUFBTSxJQUFJLEtBQUssQ0FDYixnREFBZ0Q7Z0JBQzlDLGFBQWE7Z0JBQ2IsUUFBUTtnQkFDUixNQUFNLENBQUMsR0FBRztnQkFDVix3QkFBd0I7Z0JBQ3hCLHNCQUFzQixDQUN6QixDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksV0FBK0IsQ0FBQztRQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3ZCLFdBQVcsR0FBRyxNQUFNLE1BQU07aUJBQ3ZCLE1BQU0sRUFBRTtpQkFDUixFQUFFLEVBQUU7aUJBQ0osSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDO1FBRUQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7UUFDeEUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkZBQTZGLENBQUMsQ0FBQztRQUNqSCxDQUFDO1FBQ0QsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDL0IsTUFBTSxTQUFTLEdBQUcsVUFBVSxHQUFHLGlCQUFpQixDQUFDO1FBRWpELFNBQVM7YUFDTixHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO2FBQ25DLFNBQVMsQ0FBQyxJQUFJLENBQUM7YUFDZixNQUFNLENBQUM7WUFDTixPQUFPLEVBQUUsTUFBTSxDQUFDLFdBQVc7U0FDNUIsQ0FBQzthQUNELEVBQUUsQ0FBQztZQUNGLE9BQU8sRUFBRSxNQUFNLENBQUMsbUJBQW1CO1NBQ3BDLENBQUM7YUFDRCxNQUFNLENBQUMsZUFBZSxDQUFDO2FBQ3ZCLFNBQVMsQ0FBQyxTQUFTLENBQUM7YUFDcEIsV0FBVyxDQUFDLFdBQVcsQ0FBQzthQUN4QixVQUFVLENBQUMsSUFBSSxzQkFBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQ2hELFNBQVMsQ0FBQyxJQUFJLHNCQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUVsRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksR0FBRyxJQUFJLFVBQVUsQ0FBQyxlQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUMvRCxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFFRCw2QkFBNkI7UUFDN0IsSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNwQixNQUFNLEVBQUUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFZLENBQUM7WUFFckMsT0FBTztnQkFDTCxLQUFLLEVBQUUsZUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7Z0JBQzFELElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtnQkFDakIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7Z0JBQzNCLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDekIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxXQUFXO2dCQUMzQixJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDckIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxHQUFHO2dCQUNuQixNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUMsUUFBUSxFQUFFO2dCQUNqRCxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7Z0JBQzdCLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUztnQkFDM0IsU0FBUyxFQUFFLFNBQVM7Z0JBQ3BCLFdBQVcsRUFBRSxXQUFXO2dCQUN4QixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsZUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztnQkFDakYsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ3pELGNBQWMsRUFBRSxDQUFDO2FBQ2xCLENBQUM7UUFDSixDQUFDO1FBRUQsbUNBQW1DO1FBQ25DLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNqQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFFbkMsTUFBTSxFQUFFLEdBQUcsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkMsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBWSxDQUFDO1FBRXJDLE9BQU87WUFDTCxFQUFFLEVBQUUsZUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDMUQsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ2IsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDckIsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHO1lBQ2YsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQzdCLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUztZQUMzQixTQUFTLEVBQUUsU0FBUztZQUNwQixXQUFXLEVBQUUsV0FBVztZQUN4QixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsZUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztTQUNsRixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLG9CQUFvQixDQUFDLEVBQ3pCLDJCQUEyQixFQUMzQixVQUFVLEdBQ2tCO1FBQzVCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUNELElBQUksQ0FBQztZQUNILE1BQU0sS0FBSyxHQUFHLGVBQU0sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pGLE1BQU0sTUFBTSxHQUFHLGVBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXhGLE9BQU8sTUFBTSxNQUFNLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDdEQsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRSxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNLLDJCQUEyQixDQUFDLGVBQXVCO1FBQ3pELDhCQUE4QjtRQUM5QixJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUN6QyxPQUFPLGVBQWUsQ0FBQztRQUN6QixDQUFDO1FBRUQsd0JBQXdCO1FBQ3hCLElBQUkscUJBQU8sQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUM1RCxNQUFNLFVBQVUsR0FBRyxxQkFBTyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUMxRSxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNoRSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDckMsT0FBTyxXQUFXLENBQUM7WUFDckIsQ0FBQztZQUNELE1BQU0sSUFBSSxpQ0FBc0IsQ0FBQywyRUFBMkUsQ0FBQyxDQUFDO1lBQzlHLHdCQUF3QjtRQUMxQixDQUFDO2FBQU0sSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDL0QsTUFBTSxFQUFFLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUM7WUFDekQsTUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxPQUFPLFdBQVcsQ0FBQztZQUNyQixDQUFDO1lBQ0QsTUFBTSxJQUFJLGlDQUFzQixDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUVELE1BQU0sSUFBSSxpQ0FBc0IsQ0FBQyxxRUFBcUUsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFTyxVQUFVO1FBQ2hCLE9BQU8sSUFBSSxPQUFPLENBQUMseUJBQXlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQy9FLENBQUM7SUFFRCxrQkFBa0I7SUFDbEIsaUJBQWlCLENBQUMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFlBQVksRUFBMkI7UUFDekUsSUFBSSxZQUFZLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFFRCxJQUFJLE9BQU8sQ0FBQztRQUNaLElBQUksQ0FBQztZQUNILE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUNELElBQUksU0FBUyxJQUFJLFNBQVMsS0FBSyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ3hDLENBQUM7UUFFRCxPQUFPO0lBQ1QsQ0FBQztDQUNGO0FBcDNCRCxvQkFvM0JDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgU2VlZFZhbGlkYXRvciB9IGZyb20gJy4vc2VlZFZhbGlkYXRvcic7XG5pbXBvcnQgeyBjb2lucywgQ29pbkZhbWlseSB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgQWxnb0xpYiBmcm9tICcuL2xpYic7XG5pbXBvcnQge1xuICBBZGRyZXNzQ29pblNwZWNpZmljLFxuICBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25PcHRpb25zLFxuICBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25SZXN1bHQsXG4gIEJhc2VDb2luLFxuICBCaXRHb0Jhc2UsXG4gIEludmFsaWRBZGRyZXNzRXJyb3IsXG4gIEludmFsaWRLZXksXG4gIEtleUluZGljZXMsXG4gIEtleVBhaXIsXG4gIFBhcnNlZFRyYW5zYWN0aW9uLFxuICBQYXJzZVRyYW5zYWN0aW9uT3B0aW9ucyxcbiAgU2lnbmVkVHJhbnNhY3Rpb24sXG4gIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgYXMgQmFzZVNpZ25UcmFuc2FjdGlvbk9wdGlvbnMsXG4gIFRva2VuTWFuYWdlbWVudFR5cGUsXG4gIFRyYW5zYWN0aW9uRXhwbGFuYXRpb24sXG4gIFRyYW5zYWN0aW9uUmVjaXBpZW50LFxuICBUcmFuc2FjdGlvblR5cGUsXG4gIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IsXG4gIFZlcmlmeUFkZHJlc3NPcHRpb25zLFxuICBWZXJpZnlUcmFuc2FjdGlvbk9wdGlvbnMsXG4gIE5vdFN1cHBvcnRlZCxcbiAgTXVsdGlzaWdUeXBlLFxuICBtdWx0aXNpZ1R5cGVzLFxuICBBdWRpdERlY3J5cHRlZEtleVBhcmFtcyxcbiAgVHhJbnRlbnRNaXNtYXRjaEVycm9yLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgc3RlbGxhciBmcm9tICdzdGVsbGFyLXNkayc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgVXRpbHMgZnJvbSAnLi9saWIvdXRpbHMnO1xuaW1wb3J0IHsgVHhEYXRhIH0gZnJvbSAnLi9saWIvaWZhY2VzJztcbmltcG9ydCAqIGFzIGFsZ29zZGsgZnJvbSAnYWxnb3Nkayc7XG5pbXBvcnQge1xuICBNQUlOTkVUX0dFTkVTSVNfSEFTSCxcbiAgTUFJTk5FVF9HRU5FU0lTX0lELFxuICBURVNUTkVUX0dFTkVTSVNfSEFTSCxcbiAgVEVTVE5FVF9HRU5FU0lTX0lELFxufSBmcm9tICcuL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXInO1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnYnVmZmVyJztcbmltcG9ydCB7IHRvTnVtYmVyIH0gZnJvbSAnbG9kYXNoJztcblxuY29uc3QgU1VQUE9SVEVEX0FERFJFU1NfVkVSU0lPTiA9IDE7XG5jb25zdCBNU0lHX1RIUkVTSE9MRCA9IDI7IC8vIG0gaW4gbS1vZi1uXG5cbmV4cG9ydCBpbnRlcmZhY2UgQWxnb0FkZHJlc3NDb2luU3BlY2lmaWNzIGV4dGVuZHMgQWRkcmVzc0NvaW5TcGVjaWZpYyB7XG4gIHJvb3RBZGRyZXNzOiBzdHJpbmc7XG4gIGJpdGdvS2V5OiBzdHJpbmc7XG4gIGJpdGdvUHViS2V5Pzogc3RyaW5nO1xuICBhZGRyZXNzVmVyc2lvbjogbnVtYmVyO1xuICB0aHJlc2hvbGQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWZXJpZnlBbGdvQWRkcmVzc09wdGlvbnMgZXh0ZW5kcyBWZXJpZnlBZGRyZXNzT3B0aW9ucyB7XG4gIGNoYWluOiBudW1iZXI7XG4gIGluZGV4OiBudW1iZXI7XG4gIGNvaW46IHN0cmluZztcbiAgd2FsbGV0OiBzdHJpbmc7XG4gIGNvaW5TcGVjaWZpYzogQWxnb0FkZHJlc3NDb2luU3BlY2lmaWNzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFsZ29UcmFuc2FjdGlvbkV4cGxhbmF0aW9uIGV4dGVuZHMgVHJhbnNhY3Rpb25FeHBsYW5hdGlvbiB7XG4gIG1lbW8/OiBzdHJpbmc7XG4gIHR5cGU/OiBzdHJpbmcgfCBudW1iZXI7XG4gIHZvdGVLZXk/OiBzdHJpbmc7XG4gIHNlbGVjdGlvbktleT86IHN0cmluZztcbiAgdm90ZUZpcnN0PzogbnVtYmVyO1xuICB2b3RlTGFzdD86IG51bWJlcjtcbiAgdm90ZUtleURpbHV0aW9uPzogbnVtYmVyO1xuICB0b2tlbklkPzogbnVtYmVyO1xuICBvcGVyYXRpb25zPzogVHJhbnNhY3Rpb25PcGVyYXRpb25bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2FjdGlvbk9wZXJhdGlvbiB7XG4gIHR5cGU6IHN0cmluZztcbiAgY29pbjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBCYXNlU2lnblRyYW5zYWN0aW9uT3B0aW9ucyB7XG4gIHR4UHJlYnVpbGQ6IFRyYW5zYWN0aW9uUHJlYnVpbGQ7XG4gIHBydjogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zYWN0aW9uUHJlYnVpbGQge1xuICB0eEhleDogc3RyaW5nO1xuICBoYWxmU2lnbmVkPzoge1xuICAgIHR4SGV4OiBzdHJpbmc7XG4gIH07XG4gIHR4SW5mbzoge1xuICAgIGZyb206IHN0cmluZztcbiAgICB0bzogc3RyaW5nO1xuICAgIGFtb3VudDogc3RyaW5nO1xuICAgIGZlZTogbnVtYmVyO1xuICAgIGZpcnN0Um91bmQ6IG51bWJlcjtcbiAgICBsYXN0Um91bmQ6IG51bWJlcjtcbiAgICBnZW5lc2lzSUQ6IHN0cmluZztcbiAgICBnZW5lc2lzSGFzaDogc3RyaW5nO1xuICAgIG5vdGU/OiBzdHJpbmc7XG4gIH07XG4gIGtleXM6IHN0cmluZ1tdO1xuICBhZGRyZXNzVmVyc2lvbjogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZ1bGx5U2lnbmVkVHJhbnNhY3Rpb24ge1xuICB0eEhleDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEhhbGZTaWduZWRUcmFuc2FjdGlvbiB7XG4gIGhhbGZTaWduZWQ6IHtcbiAgICB0eEhleDogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zYWN0aW9uRmVlIHtcbiAgZmVlOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEV4cGxhaW5UcmFuc2FjdGlvbk9wdGlvbnMge1xuICB0eEhleD86IHN0cmluZztcbiAgaGFsZlNpZ25lZD86IHtcbiAgICB0eEhleDogc3RyaW5nO1xuICB9O1xuICBwdWJsaWNLZXlzPzogc3RyaW5nW107XG4gIGZlZUluZm86IFRyYW5zYWN0aW9uRmVlO1xufVxuXG5pbnRlcmZhY2UgTm9kZVBhcmFtcyB7XG4gIHRva2VuOiBzdHJpbmc7XG4gIGJhc2VTZXJ2ZXI6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZlcmlmaWVkVHJhbnNhY3Rpb25QYXJhbWV0ZXJzIHtcbiAgdHhIZXg6IHN0cmluZztcbiAgYWRkcmVzc1ZlcnNpb246IG51bWJlcjtcbiAgc2lnbmVyczogc3RyaW5nW107XG4gIHBydjogc3RyaW5nO1xuICBpc0hhbGZTaWduZWQ6IGJvb2xlYW47XG4gIG51bWJlclNpZ25lcnM6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWNvdmVyeU9wdGlvbnMge1xuICBiYWNrdXBLZXk6IHN0cmluZztcbiAgdXNlcktleTogc3RyaW5nO1xuICByb290QWRkcmVzczogc3RyaW5nO1xuICByZWNvdmVyeURlc3RpbmF0aW9uOiBzdHJpbmc7XG4gIGJpdGdvS2V5OiBzdHJpbmc7XG4gIHdhbGxldFBhc3NwaHJhc2U/OiBzdHJpbmc7XG4gIGZlZTogbnVtYmVyO1xuICBmaXJzdFJvdW5kPzogbnVtYmVyO1xuICBub3RlPzogc3RyaW5nO1xuICBub2RlUGFyYW1zOiBOb2RlUGFyYW1zO1xufVxuXG5pbnRlcmZhY2UgUmVjb3ZlcnlJbmZvIHtcbiAgaWQ6IHN0cmluZztcbiAgdHg6IHN0cmluZztcbiAgY29pbjogc3RyaW5nO1xuICBmZWU6IG51bWJlcjtcbiAgZmlyc3RSb3VuZDogbnVtYmVyO1xuICBsYXN0Um91bmQ6IG51bWJlcjtcbiAgZ2VuZXNpc0lkOiBzdHJpbmc7XG4gIGdlbmVzaXNIYXNoOiBzdHJpbmc7XG4gIG5vdGU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT2ZmbGluZVZhdWx0VHhJbmZvIHtcbiAgdHhIZXg6IHN0cmluZztcbiAgdXNlcktleTogc3RyaW5nO1xuICBiYWNrdXBLZXk6IHN0cmluZztcbiAgYml0Z29LZXk6IHN0cmluZztcbiAgdHlwZT86IHN0cmluZztcbiAgYWRkcmVzczogc3RyaW5nO1xuICBjb2luOiBzdHJpbmc7XG4gIGZlZUluZm86IG51bWJlcjtcbiAgYW1vdW50OiBzdHJpbmc7XG4gIGZpcnN0Um91bmQ6IG51bWJlcjtcbiAgbGFzdFJvdW5kOiBudW1iZXI7XG4gIGdlbmVzaXNJZDogc3RyaW5nO1xuICBnZW5lc2lzSGFzaDogc3RyaW5nO1xuICBub3RlPzogc3RyaW5nO1xuICBhZGRyZXNzVmVyc2lvbjogbnVtYmVyO1xuICBrZXlzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcm9hZGNhc3RUcmFuc2FjdGlvbk9wdGlvbnMgZXh0ZW5kcyBCYXNlQnJvYWRjYXN0VHJhbnNhY3Rpb25PcHRpb25zIHtcbiAgbm9kZVBhcmFtczogTm9kZVBhcmFtcztcbn1cblxuZXhwb3J0IGNsYXNzIEFsZ28gZXh0ZW5kcyBCYXNlQ29pbiB7XG4gIHJlYWRvbmx5IEVOQUJMRV9UT0tFTjogVG9rZW5NYW5hZ2VtZW50VHlwZSA9ICdlbmFibGV0b2tlbic7XG4gIHJlYWRvbmx5IERJU0FCTEVfVE9LRU46IFRva2VuTWFuYWdlbWVudFR5cGUgPSAnZGlzYWJsZXRva2VuJztcblxuICBjb25zdHJ1Y3RvcihiaXRnbzogQml0R29CYXNlKSB7XG4gICAgc3VwZXIoYml0Z28pO1xuICB9XG5cbiAgc3RhdGljIGNyZWF0ZUluc3RhbmNlKGJpdGdvOiBCaXRHb0Jhc2UpOiBCYXNlQ29pbiB7XG4gICAgcmV0dXJuIG5ldyBBbGdvKGJpdGdvKTtcbiAgfVxuXG4gIGdldENoYWluKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdhbGdvJztcbiAgfVxuXG4gIGdldEJhc2VDaGFpbigpOiBzdHJpbmcge1xuICAgIHJldHVybiAnYWxnbyc7XG4gIH1cblxuICBnZXRGYW1pbHkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ2FsZ28nO1xuICB9XG5cbiAgZ2V0RnVsbE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gJ0FsZ29yYW5kJztcbiAgfVxuXG4gIGdldEJhc2VGYWN0b3IoKTogbnVtYmVyIHwgc3RyaW5nIHtcbiAgICByZXR1cm4gMWU2O1xuICB9XG5cbiAgLyoqXG4gICAqIEZsYWcgZm9yIHNlbmRpbmcgdmFsdWUgb2YgMFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBva2F5IHRvIHNlbmQgMCB2YWx1ZSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICB2YWx1ZWxlc3NUcmFuc2ZlckFsbG93ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQWxnb3JhbmQgc3VwcG9ydHMgYWNjb3VudCBjb25zb2xpZGF0aW9ucy4gVGhlc2UgYXJlIHRyYW5zZmVycyBmcm9tIHRoZSByZWNlaXZlIGFkZHJlc3Nlc1xuICAgKiB0byB0aGUgbWFpbiBhZGRyZXNzLlxuICAgKi9cbiAgYWxsb3dzQWNjb3VudENvbnNvbGlkYXRpb25zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIGluaGVyaXRkb2MgKi9cbiAgZGVyaXZlS2V5V2l0aFNlZWQoKTogeyBkZXJpdmF0aW9uUGF0aDogc3RyaW5nOyBrZXk6IHN0cmluZyB9IHtcbiAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkKCdtZXRob2QgZGVyaXZlS2V5V2l0aFNlZWQgbm90IHN1cHBvcnRlZCBmb3IgZWRkc2EgY3VydmUnKTtcbiAgfVxuXG4gIC8qKiBpbmhlcml0ZG9jICovXG4gIGdlbmVyYXRlS2V5UGFpcihzZWVkPzogQnVmZmVyKTogS2V5UGFpciB7XG4gICAgY29uc3Qga2V5UGFpciA9IHNlZWQgPyBuZXcgQWxnb0xpYi5LZXlQYWlyKHsgc2VlZCB9KSA6IG5ldyBBbGdvTGliLktleVBhaXIoKTtcbiAgICBjb25zdCBrZXlzID0ga2V5UGFpci5nZXRLZXlzKCk7XG4gICAgaWYgKCFrZXlzLnBydikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHBydiBpbiBrZXkgZ2VuZXJhdGlvbi4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHViOiBrZXlQYWlyLmdldEFkZHJlc3MoKSxcbiAgICAgIHBydjogQWxnb0xpYi5hbGdvVXRpbHMuZW5jb2RlU2VlZChCdWZmZXIuZnJvbShrZXlQYWlyLmdldFNpZ25pbmdLZXkoKSkpLFxuICAgIH07XG4gIH1cblxuICAvKiogaW5oZXJpdGRvYyAqL1xuICBnZW5lcmF0ZVJvb3RLZXlQYWlyKHNlZWQ/OiBCdWZmZXIpOiBLZXlQYWlyIHtcbiAgICBjb25zdCBrZXlQYWlyID0gc2VlZCA/IG5ldyBBbGdvTGliLktleVBhaXIoeyBzZWVkIH0pIDogbmV3IEFsZ29MaWIuS2V5UGFpcigpO1xuICAgIGNvbnN0IGtleXMgPSBrZXlQYWlyLmdldEtleXMoKTtcbiAgICBpZiAoIWtleXMucHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcHJ2IGluIGtleSBnZW5lcmF0aW9uLicpO1xuICAgIH1cbiAgICByZXR1cm4geyBwcnY6IGtleXMucHJ2ICsga2V5cy5wdWIsIHB1Yjoga2V5cy5wdWIgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgcHVibGljIGtleSBmb3IgdGhlIGNvaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwdWIgdGhlIHB1YiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRQdWIocHViOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMuaXNWYWxpZEFkZHJlc3MocHViKSB8fCBBbGdvTGliLmFsZ29VdGlscy5pc1ZhbGlkUHVibGljS2V5KHB1Yik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIGlucHV0IGlzIHZhbGlkIHNlZWQgZm9yIHRoZSBjb2luXG4gICAqIEluIEFsZ29yYW5kLCB3aGVuIHRoZSBwcml2YXRlIGtleSBpcyBlbmNvZGVkIGFzIGJhc2UzMiBzdHJpbmcgb25seSB0aGUgZmlyc3QgMzIgYnl0ZXMgYXJlIHRha2VuLFxuICAgKiBzbyB0aGUgZW5jb2RlZCB2YWx1ZSBpcyBhY3R1YWxseSB0aGUgc2VlZFxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJ2IHRoZSBwcnYgdG8gYmUgY2hlY2tlZFxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gaXMgaXQgdmFsaWQ/XG4gICAqL1xuICBpc1ZhbGlkUHJ2KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEFsZ29MaWIuYWxnb1V0aWxzLmlzVmFsaWRTZWVkKHBydikgfHwgQWxnb0xpYi5hbGdvVXRpbHMuaXNWYWxpZFByaXZhdGVLZXkocHJ2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgaW5wdXQgaXMgdmFsaWQgcHVibGljIGtleSBmb3IgdGhlIGNvaW5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGFkZHJlc3MgdGhlIHB1YiB0byBiZSBjaGVja2VkXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBpcyBpdCB2YWxpZD9cbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBBbGdvTGliLmFsZ29VdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaWduIG1lc3NhZ2Ugd2l0aCBwcml2YXRlIGtleVxuICAgKlxuICAgKiBAcGFyYW0ga2V5XG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqL1xuICBhc3luYyBzaWduTWVzc2FnZShrZXk6IEtleVBhaXIsIG1lc3NhZ2U6IHN0cmluZyB8IEJ1ZmZlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgY29uc3QgYWxnb0tleXBhaXIgPSBuZXcgQWxnb0xpYi5LZXlQYWlyKHsgcHJ2OiBrZXkucHJ2IH0pO1xuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIobWVzc2FnZSkpIHtcbiAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICB9XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGFsZ29LZXlwYWlyLnNpZ25NZXNzYWdlKG1lc3NhZ2UpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgd2hhdCBrZXkgd2Ugd2lsbCBuZWVkIGZvciBzaWduaW5nYCAtIEFsZ29yYW5kIG5lZWRzIHRoZSBiYWNrdXAsIGJpdGdvIHB1YnMuXG4gICAqL1xuICBrZXlJZHNGb3JTaWduaW5nKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gW0tleUluZGljZXMuVVNFUiwgS2V5SW5kaWNlcy5CQUNLVVAsIEtleUluZGljZXMuQklUR09dO1xuICB9XG5cbiAgZ2V0VG9rZW5OYW1lQnlJZCh0b2tlbklkOiBudW1iZXIgfCBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHRva2VuTmFtZXMgPSBjb2lucy5maWx0ZXIoKGNvaW4pID0+IGNvaW4uZmFtaWx5ID09PSAnYWxnbycgJiYgY29pbi5pc1Rva2VuKS5tYXAoKHsgbmFtZSB9KSA9PiBuYW1lISk7XG4gICAgcmV0dXJuIHRva2VuTmFtZXMuZmluZCgodG9rZW5OYW1lKSA9PiB0b2tlbk5hbWUuc3BsaXQoJy0nKVsxXSA9PT0gYCR7dG9rZW5JZH1gKSB8fCAnQWxnb1Rva2VuIHVua25vd24nO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxhaW4vcGFyc2UgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKi9cbiAgYXN5bmMgZXhwbGFpblRyYW5zYWN0aW9uKHBhcmFtczogRXhwbGFpblRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8QWxnb1RyYW5zYWN0aW9uRXhwbGFuYXRpb24gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB0eEhleCA9IHBhcmFtcy50eEhleCB8fCAocGFyYW1zLmhhbGZTaWduZWQgJiYgcGFyYW1zLmhhbGZTaWduZWQudHhIZXgpO1xuICAgIGlmICghdHhIZXggfHwgIXBhcmFtcy5mZWVJbmZvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgZXhwbGFpbiB0eCBwYXJhbWV0ZXJzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZmFjdG9yeSA9IHRoaXMuZ2V0QnVpbGRlcigpO1xuXG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHR4SGV4KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuXG4gICAgaWYgKHR4LnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5TZW5kKSB7XG4gICAgICBjb25zdCBvdXRwdXRzOiBUcmFuc2FjdGlvblJlY2lwaWVudFtdID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYWRkcmVzczogdHhKc29uLnRvLFxuICAgICAgICAgIGFtb3VudDogdHhKc29uLmFtb3VudCxcbiAgICAgICAgICBtZW1vOiB0eEpzb24ubm90ZSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBvcGVyYXRpb25zOiBUcmFuc2FjdGlvbk9wZXJhdGlvbltdID0gW107XG5cbiAgICAgIGNvbnN0IGlzVG9rZW5UeCA9IHRoaXMuaXNUb2tlblR4KHR4SnNvbi50eXBlKTtcbiAgICAgIGlmIChpc1Rva2VuVHgpIHtcbiAgICAgICAgY29uc3QgdHlwZSA9IEFsZ29MaWIuYWxnb1V0aWxzLmdldFRva2VuVHhUeXBlKHR4SnNvbi5hbW91bnQsIHR4SnNvbi5mcm9tLCB0eEpzb24udG8sIHR4SnNvbi5jbG9zZVJlbWFpbmRlclRvKTtcbiAgICAgICAgb3BlcmF0aW9ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgIGNvaW46IHRoaXMuZ2V0VG9rZW5OYW1lQnlJZCh0eEpzb24udG9rZW5JZCksXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAgICdpZCcsXG4gICAgICAgICdvdXRwdXRBbW91bnQnLFxuICAgICAgICAnY2hhbmdlQW1vdW50JyxcbiAgICAgICAgJ291dHB1dHMnLFxuICAgICAgICAnY2hhbmdlT3V0cHV0cycsXG4gICAgICAgICdmZWUnLFxuICAgICAgICAnbWVtbycsXG4gICAgICAgICd0eXBlJyxcbiAgICAgICAgJ29wZXJhdGlvbnMnLFxuICAgICAgXTtcblxuICAgICAgY29uc3QgZXhwbGFuYXRpb25SZXN1bHQ6IEFsZ29UcmFuc2FjdGlvbkV4cGxhbmF0aW9uID0ge1xuICAgICAgICBkaXNwbGF5T3JkZXIsXG4gICAgICAgIGlkOiB0eEpzb24uaWQsXG4gICAgICAgIG91dHB1dEFtb3VudDogdHhKc29uLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgb3V0cHV0cyxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGZlZTogdHhKc29uLmZlZSxcbiAgICAgICAgbWVtbzogdHhKc29uLm5vdGUsXG4gICAgICAgIHR5cGU6IHR4LnR5cGUudG9TdHJpbmcoKSxcbiAgICAgICAgb3BlcmF0aW9ucyxcbiAgICAgIH07XG5cbiAgICAgIGlmICh0eEpzb24udG9rZW5JZCkge1xuICAgICAgICBleHBsYW5hdGlvblJlc3VsdC50b2tlbklkID0gdHhKc29uLnRva2VuSWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBleHBsYW5hdGlvblJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAodHgudHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uKSB7XG4gICAgICBjb25zdCBkaXNwbGF5T3JkZXIgPSBbXG4gICAgICAgICdpZCcsXG4gICAgICAgICdmZWUnLFxuICAgICAgICAnbWVtbycsXG4gICAgICAgICd0eXBlJyxcbiAgICAgICAgJ3ZvdGVLZXknLFxuICAgICAgICAnc2VsZWN0aW9uS2V5JyxcbiAgICAgICAgJ3ZvdGVGaXJzdCcsXG4gICAgICAgICd2b3RlTGFzdCcsXG4gICAgICAgICd2b3RlS2V5RGlsdXRpb24nLFxuICAgICAgXTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGlzcGxheU9yZGVyLFxuICAgICAgICBpZDogdHhKc29uLmlkLFxuICAgICAgICBvdXRwdXRBbW91bnQ6ICcwJyxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIG91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgZmVlOiB0eEpzb24uZmVlLFxuICAgICAgICBtZW1vOiB0eEpzb24ubm90ZSxcbiAgICAgICAgdHlwZTogdHgudHlwZSxcbiAgICAgICAgdm90ZUtleTogdHhKc29uLnZvdGVLZXksXG4gICAgICAgIHNlbGVjdGlvbktleTogdHhKc29uLnNlbGVjdGlvbktleSxcbiAgICAgICAgdm90ZUZpcnN0OiB0eEpzb24udm90ZUZpcnN0LFxuICAgICAgICB2b3RlTGFzdDogdHhKc29uLnZvdGVMYXN0LFxuICAgICAgICB2b3RlS2V5RGlsdXRpb246IHR4SnNvbi52b3RlS2V5RGlsdXRpb24sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm5zIGlmIGEgdHggaXMgYSB0b2tlbiB0eFxuICAgKiBAcGFyYW0gdHlwZSB7c3RyaW5nfSAtIHR4IHR5cGVcbiAgICogQHJldHVybnMgdHJ1ZSBpZiBpdCdzIGEgdG9rZW4gdHhcbiAgICovXG4gIGlzVG9rZW5UeCh0eXBlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHlwZSA9PT0gJ2F4ZmVyJztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHNlZWQgaXMgYSB2YWxpZCBzdGVsbGFyIHNlZWRcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNlZWQgdGhlIHNlZWQgdG8gY2hlY2tcbiAgICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgdGhlIGlucHV0IGlzIGEgU3RlbGxhciBzZWVkXG4gICAqL1xuICBpc1N0ZWxsYXJTZWVkKHNlZWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBTZWVkVmFsaWRhdG9yLmlzVmFsaWRFZDI1NTE5U2VlZEZvckNvaW4oc2VlZCwgQ29pbkZhbWlseS5YTE0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdGVsbGFyIHNlZWQgdG8gYW4gYWxnbyBzZWVkXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzZWVkIHRoZSBzZWVkIHRvIGNvbnZlcnRcbiAgICogQHJldHVybnMge0Jvb2xlYW4gfCBudWxsfSBzZWVkIGluIGFsZ28gZW5jb2RpbmdcbiAgICovXG4gIGNvbnZlcnRGcm9tU3RlbGxhclNlZWQoc2VlZDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gYXNzdW1lIHRoaXMgaXMgYSB0cnVzdCBjdXN0b2RpYWwgc2VlZCBpZiBpdHMgYSB2YWxpZCBlZDI1NTE5IHBydlxuICAgIGlmICghdGhpcy5pc1N0ZWxsYXJTZWVkKHNlZWQpIHx8IFNlZWRWYWxpZGF0b3IuaGFzQ29tcGV0aW5nU2VlZEZvcm1hdHMoc2VlZCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChTZWVkVmFsaWRhdG9yLmlzVmFsaWRFZDI1NTE5U2VlZEZvckNvaW4oc2VlZCwgQ29pbkZhbWlseS5YTE0pKSB7XG4gICAgICByZXR1cm4gQWxnb0xpYi5hbGdvVXRpbHMuY29udmVydEZyb21TdGVsbGFyU2VlZChzZWVkKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZlcmlmeVNpZ25UcmFuc2FjdGlvblBhcmFtcyhwYXJhbXM6IFNpZ25UcmFuc2FjdGlvbk9wdGlvbnMpOiBWZXJpZmllZFRyYW5zYWN0aW9uUGFyYW1ldGVycyB7XG4gICAgY29uc3QgcHJ2ID0gcGFyYW1zLnBydjtcbiAgICBjb25zdCBhZGRyZXNzVmVyc2lvbiA9IHBhcmFtcy50eFByZWJ1aWxkLmFkZHJlc3NWZXJzaW9uO1xuICAgIGxldCBpc0hhbGZTaWduZWQgPSBmYWxzZTtcblxuICAgIC8vIGl0J3MgcG9zc2libGUgdGhpcyB0eCB3YXMgYWxyZWFkeSBzaWduZWQgLSB0YWtlIHRoZSBoYWxmU2lnbmVkXG4gICAgLy8gdHhIZXggaWYgaXQgaXNcbiAgICBsZXQgdHhIZXggPSBwYXJhbXMudHhQcmVidWlsZC50eEhleDtcbiAgICBpZiAocGFyYW1zLnR4UHJlYnVpbGQuaGFsZlNpZ25lZCkge1xuICAgICAgaXNIYWxmU2lnbmVkID0gdHJ1ZTtcbiAgICAgIHR4SGV4ID0gcGFyYW1zLnR4UHJlYnVpbGQuaGFsZlNpZ25lZC50eEhleDtcbiAgICB9XG5cbiAgICBpZiAoXy5pc1VuZGVmaW5lZCh0eEhleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFByZWJ1aWxkIHBhcmFtZXRlcicpO1xuICAgIH1cblxuICAgIGlmICghXy5pc1N0cmluZyh0eEhleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdHhQcmVidWlsZCBtdXN0IGJlIGFuIG9iamVjdCwgZ290IHR5cGUgJHt0eXBlb2YgdHhIZXh9YCk7XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQocHJ2KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHBydiBwYXJhbWV0ZXIgdG8gc2lnbiB0cmFuc2FjdGlvbicpO1xuICAgIH1cblxuICAgIGlmICghXy5pc1N0cmluZyhwcnYpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHBydiBtdXN0IGJlIGEgc3RyaW5nLCBnb3QgdHlwZSAke3R5cGVvZiBwcnZ9YCk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmhhcyhwYXJhbXMudHhQcmVidWlsZCwgJ2tleXMnKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHB1YmxpYyBrZXlzIHBhcmFtZXRlciB0byBzaWduIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKCFfLmlzTnVtYmVyKGFkZHJlc3NWZXJzaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGFkZHJlc3NWZXJzaW9uIHBhcmFtZXRlciB0byBzaWduIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2lnbmVycyA9IHBhcmFtcy50eFByZWJ1aWxkLmtleXMubWFwKChrZXkpID0+IHtcbiAgICAgIC8vIGlmIHdlIGFyZSByZWNlaXZpbmcgYWRkcmVzc2VzIGRvIG5vdCB0cnkgdG8gY29udmVydCB0aGVtXG4gICAgICBpZiAoIUFsZ29MaWIuYWxnb1V0aWxzLmlzVmFsaWRBZGRyZXNzKGtleSkpIHtcbiAgICAgICAgcmV0dXJuIEFsZ29MaWIuYWxnb1V0aWxzLnB1YmxpY0tleVRvQWxnb0FkZHJlc3MoQWxnb0xpYi5hbGdvVXRpbHMudG9VaW50OEFycmF5KGtleSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGtleTtcbiAgICB9KTtcbiAgICAvLyBUT0RPKGh0dHBzOi8vYml0Z29pbmMuYXRsYXNzaWFuLm5ldC9icm93c2UvU1RMWC02MDY3KTogZml4IHRoZSBudW1iZXIgb2Ygc2lnbmVycyB1c2luZ1xuICAgIC8vIHNob3VsZCBiZSBzaW1pbGFyIHRvIG90aGVyIGNvaW5zIGltcGxlbWVudGF0aW9uXG4gICAgLy8gSWYgd2UgaGF2ZSBhIG51bWJlciB3aXRoIGRpZ2l0cyB0byBlbGltaW5hdGUgdGhlbSB3aXRob3V0IHRha2luZyBhbnkgcm91bmRpbmcgY3JpdGVyaWEuXG4gICAgY29uc3QgbnVtYmVyU2lnbmVycyA9IE1hdGgudHJ1bmMoc2lnbmVycy5sZW5ndGggLyAyKSArIDE7XG4gICAgcmV0dXJuIHsgdHhIZXgsIGFkZHJlc3NWZXJzaW9uLCBzaWduZXJzLCBwcnYsIGlzSGFsZlNpZ25lZCwgbnVtYmVyU2lnbmVycyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGtleWNoYWluIGFuZCBoYWxmLXNpZ24gcHJlYnVpbHQgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtc1xuICAgKiBAcGFyYW0gcGFyYW1zLnR4UHJlYnVpbGQge1RyYW5zYWN0aW9uUHJlYnVpbGR9IHByZWJ1aWxkIG9iamVjdCByZXR1cm5lZCBieSBwbGF0Zm9ybVxuICAgKiBAcGFyYW0gcGFyYW1zLnBydiB7U3RyaW5nfSB1c2VyIHBydlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj59XG4gICAqL1xuICBhc3luYyBzaWduVHJhbnNhY3Rpb24ocGFyYW1zOiBTaWduVHJhbnNhY3Rpb25PcHRpb25zKTogUHJvbWlzZTxTaWduZWRUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IHsgdHhIZXgsIHNpZ25lcnMsIHBydiwgaXNIYWxmU2lnbmVkLCBudW1iZXJTaWduZXJzIH0gPSB0aGlzLnZlcmlmeVNpZ25UcmFuc2FjdGlvblBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odHhIZXgpO1xuICAgIHR4QnVpbGRlci5udW1iZXJPZlJlcXVpcmVkU2lnbmVycyhudW1iZXJTaWduZXJzKTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogcHJ2IH0pO1xuICAgIHR4QnVpbGRlci5zZXRTaWduZXJzKHNpZ25lcnMpO1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgaWYgKCF0cmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICAgIGNvbnN0IHNpZ25lZFR4SGV4ID0gQnVmZmVyLmZyb20odHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGlmIChudW1iZXJTaWduZXJzID09PSAxKSB7XG4gICAgICByZXR1cm4geyB0eEhleDogc2lnbmVkVHhIZXggfTtcbiAgICB9IGVsc2UgaWYgKGlzSGFsZlNpZ25lZCkge1xuICAgICAgcmV0dXJuIHsgdHhIZXg6IHNpZ25lZFR4SGV4IH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IGhhbGZTaWduZWQ6IHsgdHhIZXg6IHNpZ25lZFR4SGV4IH0gfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBwYXJzZVRyYW5zYWN0aW9uKHBhcmFtczogUGFyc2VUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPFBhcnNlZFRyYW5zYWN0aW9uPiB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFkZHJlc3MgY2FuIGJlIHVzZWQgdG8gc2VuZCBmdW5kcy5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcy5hZGRyZXNzIGFkZHJlc3MgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHBhcmFtcy5rZXljaGFpbnMgcHVibGljIGtleXMgdG8gZ2VuZXJhdGUgdGhlIHdhbGxldFxuICAgKi9cbiAgYXN5bmMgaXNXYWxsZXRBZGRyZXNzKHBhcmFtczogVmVyaWZ5QWxnb0FkZHJlc3NPcHRpb25zKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qge1xuICAgICAgYWRkcmVzcyxcbiAgICAgIGtleWNoYWlucyxcbiAgICAgIGNvaW5TcGVjaWZpYzogeyBiaXRnb1B1YktleSB9LFxuICAgIH0gPSBwYXJhbXM7XG5cbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkQWRkcmVzc0Vycm9yKGBpbnZhbGlkIGFkZHJlc3M6ICR7YWRkcmVzc31gKTtcbiAgICB9XG5cbiAgICBpZiAoIWtleWNoYWlucykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGtleWNoYWlucycpO1xuICAgIH1cblxuICAgIGNvbnN0IGVmZmVjdGl2ZUtleWNoYWluID0gYml0Z29QdWJLZXkgPyBrZXljaGFpbnMuc2xpY2UoMCwgLTEpLmNvbmNhdChbeyBwdWI6IGJpdGdvUHViS2V5IH1dKSA6IGtleWNoYWlucztcbiAgICBjb25zdCBwdWJLZXlzID0gZWZmZWN0aXZlS2V5Y2hhaW4ubWFwKChrZXkpID0+IHRoaXMuc3RlbGxhckFkZHJlc3NUb0FsZ29BZGRyZXNzKGtleS5wdWIpKTtcblxuICAgIGlmICghcHViS2V5cy5ldmVyeSgocHViS2V5KSA9PiB0aGlzLmlzVmFsaWRQdWIocHViS2V5KSkpIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkS2V5KCdpbnZhbGlkIHB1YmxpYyBrZXknKTtcbiAgICB9XG5cbiAgICBjb25zdCByb290QWRkcmVzcyA9IEFsZ29MaWIuYWxnb1V0aWxzLm11bHRpc2lnQWRkcmVzcyhTVVBQT1JURURfQUREUkVTU19WRVJTSU9OLCBNU0lHX1RIUkVTSE9MRCwgcHViS2V5cyk7XG5cbiAgICByZXR1cm4gcm9vdEFkZHJlc3MgPT09IGFkZHJlc3M7XG4gIH1cblxuICBhc3luYyB2ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXM6IFZlcmlmeVRyYW5zYWN0aW9uT3B0aW9ucyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0gPSBwYXJhbXM7XG5cbiAgICBpZiAoIXR4UGFyYW1zKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdHhQYXJhbXMnKTtcbiAgICB9XG5cbiAgICBpZiAoIXR4UHJlYnVpbGQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyB0eFByZWJ1aWxkJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0eFByZWJ1aWxkLnR4SGV4KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgdHhIZXggaW4gdHhQcmVidWlsZCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGZhY3RvcnkgPSB0aGlzLmdldEJ1aWxkZXIoKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odHhQcmVidWlsZC50eEhleCk7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcblxuICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgYSB0b2tlbiBlbmFibGVtZW50IHRyYW5zYWN0aW9uXG4gICAgY29uc3QgaXNUb2tlbkVuYWJsZW1lbnRUeCA9IHR4UGFyYW1zLnR5cGUgPT09ICdlbmFibGV0b2tlbic7XG5cbiAgICAvLyBWYWxpZGF0ZSBiYXNlZCBvbiBBbGdvcmFuZCB0cmFuc2FjdGlvbiB0eXBlXG4gICAgaWYgKGlzVG9rZW5FbmFibGVtZW50VHggJiYgdmVyaWZpY2F0aW9uPy52ZXJpZnlUb2tlbkVuYWJsZW1lbnQpIHtcbiAgICAgIC8vIFZhbGlkYXRlIHRva2VuIGVuYWJsZW1lbnQgdHJhbnNhY3Rpb25cbiAgICAgIHRoaXMudmFsaWRhdGVUb2tlbkVuYWJsZW1lbnRUcmFuc2FjdGlvbih0eEpzb24sIHR4UGFyYW1zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3dpdGNoICh0eEpzb24udHlwZSkge1xuICAgICAgICBjYXNlICdwYXknOlxuICAgICAgICAgIHRoaXMudmFsaWRhdGVQYXlUcmFuc2FjdGlvbih0eEpzb24sIHR4UGFyYW1zKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYXhmZXInOlxuICAgICAgICAgIHRoaXMudmFsaWRhdGVBc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24odHhKc29uLCB0eFBhcmFtcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgLy8gRm9yIG90aGVyIHRyYW5zYWN0aW9uIHR5cGVzLCBwZXJmb3JtIGJhc2ljIHZhbGlkYXRpb25cbiAgICAgICAgICB0aGlzLnZhbGlkYXRlQmFzaWNUcmFuc2FjdGlvbih0eEpzb24pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFZlcmlmeSBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9ucyBzZW5kIHRvIGJhc2UgYWRkcmVzc1xuICAgIGlmICh2ZXJpZmljYXRpb24/LmNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzKSB7XG4gICAgICBpZiAoIXdhbGxldD8uY29pblNwZWNpZmljKCk/LnJvb3RBZGRyZXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVybWluZSBiYXNlIGFkZHJlc3MgZm9yIGNvbnNvbGlkYXRpb24nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJvb3RBZGRyZXNzID0gd2FsbGV0LmNvaW5TcGVjaWZpYygpPy5yb290QWRkcmVzcyBhcyBzdHJpbmc7XG5cbiAgICAgIC8vIFZlcmlmeSB0aGUgdHJhbnNhY3Rpb24gcmVjaXBpZW50IG1hdGNoZXMgdGhlIHJvb3RBZGRyZXNzXG4gICAgICBpZiAoIXR4SnNvbi50bykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIGlzIG1pc3NpbmcgcmVjaXBpZW50IGFkZHJlc3MnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR4SnNvbi50byAhPT0gcm9vdEFkZHJlc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR4SW50ZW50TWlzbWF0Y2hFcnJvcihcbiAgICAgICAgICAnQ29uc29saWRhdGlvbiB0cmFuc2FjdGlvbiByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggd2FsbGV0IGJhc2UgYWRkcmVzcycsXG4gICAgICAgICAgdHhKc29uLnRvLFxuICAgICAgICAgIFt0eFBhcmFtc10sXG4gICAgICAgICAgdHhKc29uXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYmFzaWMgdHJhbnNhY3Rpb24gZmllbGRzIGNvbW1vbiB0byBhbGwgdHJhbnNhY3Rpb24gdHlwZXNcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVCYXNpY1RyYW5zYWN0aW9uKHR4SnNvbjogYW55KTogdm9pZCB7XG4gICAgaWYgKCF0eEpzb24uZnJvbSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIHNlbmRlciBhZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0eEpzb24uZmVlIHx8IHR4SnNvbi5mZWUgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IGludmFsaWQgZmVlJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIFBheW1lbnQgKHBheSkgdHJhbnNhY3Rpb25cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVQYXlUcmFuc2FjdGlvbih0eEpzb246IGFueSwgdHhQYXJhbXM6IGFueSk6IGJvb2xlYW4ge1xuICAgIHRoaXMudmFsaWRhdGVCYXNpY1RyYW5zYWN0aW9uKHR4SnNvbik7XG5cbiAgICBpZiAoIXR4SnNvbi50bykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIHJlY2lwaWVudCBhZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgaWYgKHR4SnNvbi5hbW91bnQgPT09IHVuZGVmaW5lZCB8fCB0eEpzb24uYW1vdW50IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBpbnZhbGlkIGFtb3VudCcpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHJlY2lwaWVudHMgaWYgcHJvdmlkZWQgaW4gdHhQYXJhbXNcbiAgICBpZiAodHhQYXJhbXMucmVjaXBpZW50cyAmJiB0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FsZ29yYW5kIHRyYW5zYWN0aW9ucyBjYW4gb25seSBoYXZlIG9uZSByZWNpcGllbnQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhwZWN0ZWRSZWNpcGllbnQgPSB0eFBhcmFtcy5yZWNpcGllbnRzWzBdO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBbW91bnQgPSBleHBlY3RlZFJlY2lwaWVudC5hbW91bnQudG9TdHJpbmcoKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkQWRkcmVzcyA9IGV4cGVjdGVkUmVjaXBpZW50LmFkZHJlc3M7XG4gICAgICBjb25zdCBhY3R1YWxBbW91bnQgPSB0eEpzb24uYW1vdW50LnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBhY3R1YWxBZGRyZXNzID0gdHhKc29uLnRvO1xuXG4gICAgICBpZiAoZXhwZWN0ZWRBbW91bnQgIT09IGFjdHVhbEFtb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoZSB2YWx1ZSBnaXZlbiBieSBjbGllbnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV4cGVjdGVkQWRkcmVzcy50b0xvd2VyQ2FzZSgpICE9PSBhY3R1YWxBZGRyZXNzLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkZXN0aW5hdGlvbiBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIHJlY2lwaWVudCBhZGRyZXNzJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgQXNzZXQgVHJhbnNmZXIgKGF4ZmVyKSB0cmFuc2FjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUFzc2V0VHJhbnNmZXJUcmFuc2FjdGlvbih0eEpzb246IGFueSwgdHhQYXJhbXM6IGFueSk6IGJvb2xlYW4ge1xuICAgIHRoaXMudmFsaWRhdGVCYXNpY1RyYW5zYWN0aW9uKHR4SnNvbik7XG5cbiAgICAvLyBCYXNpYyBhbW91bnQgdmFsaWRhdGlvbiBpZiBwcmVzZW50XG4gICAgaWYgKHR4SnNvbi5hbW91bnQgIT09IHVuZGVmaW5lZCAmJiB0eEpzb24uYW1vdW50IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGFzc2V0IHRyYW5zZmVyIHRyYW5zYWN0aW9uOiBpbnZhbGlkIGFtb3VudCcpO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgdG9rZW4gSUQgZnJvbSB0b2tlbiBuYW1lXG4gICAqIFRva2VuIG5hbWVzIGFyZSBpbiBmb3JtYXQgbGlrZSBcInRhbGdvOkpQVC0xNjIwODU0NDZcIiB3aGVyZSB0aGUgbnVtYmVyIGFmdGVyIHRoZSBsYXN0IGh5cGhlbiBpcyB0aGUgdG9rZW4gSURcbiAgICovXG4gIHByaXZhdGUgZXh0cmFjdFRva2VuSWRGcm9tTmFtZSh0b2tlbk5hbWU6IHN0cmluZyk6IG51bWJlciB8IG51bGwge1xuICAgIC8vIEhhbmRsZSBmb3JtYXQgbGlrZSBcInRhbGdvOkpQVC0xNjIwODU0NDZcIiBvciBcImFsZ286VE9LRU4tMTIzNDU2XCJcbiAgICBjb25zdCBwYXJ0cyA9IHRva2VuTmFtZS5zcGxpdCgnOicpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBHZXQgdGhlIHBhcnQgYWZ0ZXIgY29sb24gKGUuZy4sIFwiSlBULTE2MjA4NTQ0NlwiKVxuICAgIGNvbnN0IHRva2VuUGFydCA9IHBhcnRzWzFdO1xuXG4gICAgLy8gRXh0cmFjdCB0aGUgbnVtYmVyIGFmdGVyIHRoZSBsYXN0IGh5cGhlblxuICAgIGNvbnN0IGxhc3RIeXBoZW5JbmRleCA9IHRva2VuUGFydC5sYXN0SW5kZXhPZignLScpO1xuICAgIGlmIChsYXN0SHlwaGVuSW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB0b2tlbklkU3RyID0gdG9rZW5QYXJ0LnN1YnN0cmluZyhsYXN0SHlwaGVuSW5kZXggKyAxKTtcbiAgICBjb25zdCB0b2tlbklkID0gcGFyc2VJbnQodG9rZW5JZFN0ciwgMTApO1xuXG4gICAgcmV0dXJuIGlzTmFOKHRva2VuSWQpID8gbnVsbCA6IHRva2VuSWQ7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgVG9rZW4gRW5hYmxlbWVudCAob3B0LWluKSB0cmFuc2FjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVRva2VuRW5hYmxlbWVudFRyYW5zYWN0aW9uKHR4SnNvbjogYW55LCB0eFBhcmFtczogYW55KTogYm9vbGVhbiB7XG4gICAgdGhpcy52YWxpZGF0ZUJhc2ljVHJhbnNhY3Rpb24odHhKc29uKTtcblxuICAgIC8vIFZlcmlmeSBpdCdzIGFuIGFzc2V0IHRyYW5zZmVyIChheGZlcikgdHJhbnNhY3Rpb25cbiAgICBpZiAodHhKc29uLnR5cGUgIT09ICdheGZlcicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0b2tlbiBlbmFibGVtZW50IHRyYW5zYWN0aW9uOiBtdXN0IGJlIG9mIHR5cGUgYXhmZXInKTtcbiAgICB9XG5cbiAgICAvLyBWZXJpZnkgYW1vdW50IGlzIDAgKHRva2VuIG9wdC1pbiByZXF1aXJlbWVudClcbiAgICBpZiAodG9OdW1iZXIodHhKc29uLmFtb3VudCkgIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB0b2tlbiBlbmFibGVtZW50IHRyYW5zYWN0aW9uOiBhbW91bnQgbXVzdCBiZSAwIGZvciB0b2tlbiBvcHQtaW4nKTtcbiAgICB9XG5cbiAgICAvLyBWZXJpZnkgc2VuZGVyIGFuZCByZWNpcGllbnQgYXJlIHRoZSBzYW1lIChzZWxmLXRyYW5zYWN0aW9uKVxuICAgIGlmICghdHhKc29uLmZyb20gfHwgIXR4SnNvbi50byB8fCB0eEpzb24uZnJvbSAhPT0gdHhKc29uLnRvKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdG9rZW4gZW5hYmxlbWVudCB0cmFuc2FjdGlvbjogc2VuZGVyIGFuZCByZWNpcGllbnQgbXVzdCBiZSB0aGUgc2FtZSBhZGRyZXNzJyk7XG4gICAgfVxuXG4gICAgLy8gVmVyaWZ5IHRva2VuIElEIGlzIHByZXNlbnRcbiAgICBpZiAoIXR4SnNvbi50b2tlbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdG9rZW4gZW5hYmxlbWVudCB0cmFuc2FjdGlvbjogbWlzc2luZyB0b2tlbiBJRCcpO1xuICAgIH1cblxuICAgIC8vIElmIHR4UGFyYW1zIHNwZWNpZmllcyB0b2tlbiBpbmZvcm1hdGlvbiwgdmVyaWZ5IHRoZSB0b2tlbiBJRCBtYXRjaGVzXG4gICAgbGV0IGV4cGVjdGVkVG9rZW5JZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgICAvLyBDaGVjayBmb3IgZW5hYmxlVG9rZW5zIGFycmF5ICh1c2VkIGluIFRTUyB3YWxsZXRzKVxuICAgIGlmICh0eFBhcmFtcy5lbmFibGVUb2tlbnMgJiYgQXJyYXkuaXNBcnJheSh0eFBhcmFtcy5lbmFibGVUb2tlbnMpICYmIHR4UGFyYW1zLmVuYWJsZVRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCB0b2tlbk5hbWUgPSB0eFBhcmFtcy5lbmFibGVUb2tlbnNbMF0ubmFtZTtcbiAgICAgIGlmICh0b2tlbk5hbWUpIHtcbiAgICAgICAgZXhwZWN0ZWRUb2tlbklkID0gdGhpcy5leHRyYWN0VG9rZW5JZEZyb21OYW1lKHRva2VuTmFtZSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENoZWNrIGZvciByZWNpcGllbnRzIGFycmF5IHdpdGggdG9rZW5OYW1lICh1c2VkIGluIG5vbi1UU1Mgd2FsbGV0cylcbiAgICBlbHNlIGlmICh0eFBhcmFtcy5yZWNpcGllbnRzICYmIEFycmF5LmlzQXJyYXkodHhQYXJhbXMucmVjaXBpZW50cykgJiYgdHhQYXJhbXMucmVjaXBpZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0eFBhcmFtcy5yZWNpcGllbnRzWzBdO1xuICAgICAgaWYgKHJlY2lwaWVudC50b2tlbk5hbWUpIHtcbiAgICAgICAgZXhwZWN0ZWRUb2tlbklkID0gdGhpcy5leHRyYWN0VG9rZW5JZEZyb21OYW1lKHJlY2lwaWVudC50b2tlbk5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFZlcmlmeSB0aGUgdG9rZW4gSUQgbWF0Y2hlcyBpZiB3ZSBoYXZlIGFuIGV4cGVjdGVkIHZhbHVlXG4gICAgaWYgKGV4cGVjdGVkVG9rZW5JZCAhPT0gbnVsbCAmJiB0eEpzb24udG9rZW5JZCAhPT0gZXhwZWN0ZWRUb2tlbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBUb2tlbiBlbmFibGVtZW50IHZlcmlmaWNhdGlvbiBmYWlsZWQ6IGV4cGVjdGVkIHRva2VuIElEICR7ZXhwZWN0ZWRUb2tlbklkfSBidXQgdHJhbnNhY3Rpb24gaGFzIHRva2VuIElEICR7dHhKc29uLnRva2VuSWR9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGRlY29kZVR4KHR4bjogQnVmZmVyKTogdW5rbm93biB7XG4gICAgcmV0dXJuIEFsZ29MaWIuYWxnb1V0aWxzLmRlY29kZUFsZ29UeG4odHhuKTtcbiAgfVxuXG4gIGdldEFkZHJlc3NGcm9tUHVibGljS2V5KHB1YktleTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEFsZ29MaWIuYWxnb1V0aWxzLnB1YmxpY0tleVRvQWxnb0FkZHJlc3MocHViS2V5KTtcbiAgfVxuXG4gIHN1cHBvcnRzRGVyaXZlS2V5V2l0aFNlZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIGluaGVyaXRlZCBkb2MgKi9cbiAgZ2V0RGVmYXVsdE11bHRpc2lnVHlwZSgpOiBNdWx0aXNpZ1R5cGUge1xuICAgIHJldHVybiBtdWx0aXNpZ1R5cGVzLm9uY2hhaW47XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBjb25maWcgZm9yIGhvdyB0b2tlbiBlbmFibGVtZW50cyB3b3JrIGZvciB0aGlzIGNvaW5cbiAgICogQHJldHVybnNcbiAgICogICAgcmVxdWlyZXNUb2tlbkVuYWJsZW1lbnQ6IFRydWUgaWYgdG9rZW5zIG5lZWQgdG8gYmUgZW5hYmxlZCBmb3IgdGhpcyBjb2luXG4gICAqICAgIHN1cHBvcnRzTXVsdGlwbGVUb2tlbkVuYWJsZW1lbnRzOiBUcnVlIGlmIG11bHRpcGxlIHRva2VucyBjYW4gYmUgZW5hYmxlZCBpbiBvbmUgdHJhbnNhY3Rpb25cbiAgICovXG4gIGdldFRva2VuRW5hYmxlbWVudENvbmZpZygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVxdWlyZXNUb2tlbkVuYWJsZW1lbnQ6IHRydWUsXG4gICAgICBzdXBwb3J0c011bHRpcGxlVG9rZW5FbmFibGVtZW50czogZmFsc2UsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBiYWxhbmNlIG9mIHRoZSByb290IGFkZHJlc3MgaW4gYmFzZSB1bml0cyBvZiBhbGdvXG4gICAqIEVnLiBJZiBiYWxhbmNlIGlzIDEgQWxnbywgdGhpcyByZXR1cm5zIDEqMTBeNlxuICAgKiBAcGFyYW0gcm9vdEFkZHJlc3NcbiAgICogQHBhcmFtIGNsaWVudFxuICAgKi9cbiAgYXN5bmMgZ2V0QWNjb3VudEJhbGFuY2Uocm9vdEFkZHJlc3M6IHN0cmluZywgY2xpZW50OiBhbGdvc2RrLkFsZ29kdjIpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IGFjY291bnRJbmZvcm1hdGlvbiA9IGF3YWl0IGNsaWVudC5hY2NvdW50SW5mb3JtYXRpb24ocm9vdEFkZHJlc3MpLmRvKCk7XG4gICAgLy8gRXh0cmFjdCB0aGUgYmFsYW5jZSBmcm9tIHRoZSBhY2NvdW50IGluZm9ybWF0aW9uXG4gICAgcmV0dXJuIGFjY291bnRJbmZvcm1hdGlvbi5hbW91bnQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgQWxnbyBjbGllbnQgZm9yIHRoZSBnaXZlbiB0b2tlbiwgYmFzZVNlcnZlciBhbmQgcG9ydFxuICAgKiBVc2VkIHRvIGludGVyYWN0IHdpdGggdGhlIEFsZ28gbmV0d29ya1xuICAgKi9cbiAgZ2V0Q2xpZW50KHRva2VuOiBzdHJpbmcsIGJhc2VTZXJ2ZXI6IHN0cmluZywgcG9ydDogbnVtYmVyKTogYWxnb3Nkay5BbGdvZHYyIHtcbiAgICByZXR1cm4gbmV3IGFsZ29zZGsuQWxnb2R2Mih0b2tlbiwgYmFzZVNlcnZlciwgcG9ydCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcmVjb3ZlcihwYXJhbXM6IFJlY292ZXJ5T3B0aW9ucyk6IFByb21pc2U8UmVjb3ZlcnlJbmZvIHwgT2ZmbGluZVZhdWx0VHhJbmZvPiB7XG4gICAgY29uc3QgaXNVbnNpZ25lZFN3ZWVwID0gdGhpcy5pc1ZhbGlkUHViKHBhcmFtcy51c2VyS2V5KSAmJiB0aGlzLmlzVmFsaWRQdWIocGFyYW1zLmJhY2t1cEtleSk7XG5cbiAgICBpZiAoIXBhcmFtcy5ub2RlUGFyYW1zKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIHRoZSBkZXRhaWxzIG9mIGFuIEFMR08gbm9kZSB0byB1c2UgZm9yIHJlY292ZXJ5Jyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgdGhlIHJvb3QgYWRkcmVzc1xuICAgIGlmICghdGhpcy5pc1ZhbGlkQWRkcmVzcyhwYXJhbXMucm9vdEFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcm9vdEFkZHJlc3MsIGdvdDogJyArIHBhcmFtcy5yb290QWRkcmVzcyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgdGhlIGRlc3RpbmF0aW9uIGFkZHJlc3NcbiAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3MocGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcmVjb3ZlcnlEZXN0aW5hdGlvbiwgZ290OiAnICsgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMuZmlyc3RSb3VuZCAmJiBuZXcgQmlnTnVtYmVyKHBhcmFtcy5maXJzdFJvdW5kKS5pc05lZ2F0aXZlKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZmlyc3Qgcm91bmQgbmVlZHMgdG8gYmUgYSBwb3NpdGl2ZSB2YWx1ZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGdlbmVzaXNJZCA9IHRoaXMuYml0Z28uZ2V0RW52KCkgPT09ICdwcm9kJyA/IE1BSU5ORVRfR0VORVNJU19JRCA6IFRFU1RORVRfR0VORVNJU19JRDtcbiAgICBjb25zdCBnZW5lc2lzSGFzaCA9IHRoaXMuYml0Z28uZ2V0RW52KCkgPT09ICdwcm9kJyA/IE1BSU5ORVRfR0VORVNJU19IQVNIIDogVEVTVE5FVF9HRU5FU0lTX0hBU0g7XG5cbiAgICBVdGlscy52YWxpZGF0ZUJhc2U2NChnZW5lc2lzSGFzaCk7XG5cbiAgICBpZiAoIWlzVW5zaWduZWRTd2VlcCAmJiAhcGFyYW1zLndhbGxldFBhc3NwaHJhc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignd2FsbGV0UGFzc3BocmFzZSBpcyByZXF1aXJlZCBmb3Igbm9uLWJpdGdvIHJlY292ZXJ5Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG5cbiAgICBsZXQgdXNlclBydjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBiYWNrdXBQcnY6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIWlzVW5zaWduZWRTd2VlcCkge1xuICAgICAgaWYgKCFwYXJhbXMuYml0Z29LZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaXRnbyBwdWJsaWMga2V5IGZyb20gdGhlIGtleUNhcmQgaXMgcmVxdWlyZWQgZm9yIG5vbi1iaXRnbyByZWNvdmVyeScpO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgdXNlclBydiA9IHRoaXMuYml0Z28uZGVjcnlwdCh7IGlucHV0OiBwYXJhbXMudXNlcktleSwgcGFzc3dvcmQ6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlIH0pO1xuICAgICAgICBiYWNrdXBQcnYgPSB0aGlzLmJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcGFyYW1zLmJhY2t1cEtleSwgcGFzc3dvcmQ6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlIH0pO1xuICAgICAgICBjb25zdCB1c2VyS2V5QWRkcmVzcyA9IFV0aWxzLnByaXZhdGVLZXlUb0FsZ29BZGRyZXNzKHVzZXJQcnYpO1xuICAgICAgICBjb25zdCBiYWNrdXBLZXlBZGRyZXNzID0gVXRpbHMucHJpdmF0ZUtleVRvQWxnb0FkZHJlc3MoYmFja3VwUHJ2KTtcbiAgICAgICAgdHhCdWlsZGVyLm51bWJlck9mUmVxdWlyZWRTaWduZXJzKDIpLnNldFNpZ25lcnMoW3VzZXJLZXlBZGRyZXNzLCBiYWNrdXBLZXlBZGRyZXNzLCBwYXJhbXMuYml0Z29LZXldKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICd1bmFibGUgdG8gZGVjcnlwdCB1c2VyS2V5IG9yIGJhY2t1cEtleSB3aXRoIHRoZSB3YWxsZXRQYXNzcGhyYXNlIHByb3ZpZGVkLCBnb3QgZXJyb3I6ICcgKyBlLm1lc3NhZ2VcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmdldENsaWVudChwYXJhbXMubm9kZVBhcmFtcy50b2tlbiwgcGFyYW1zLm5vZGVQYXJhbXMuYmFzZVNlcnZlciwgcGFyYW1zLm5vZGVQYXJhbXMucG9ydCk7XG4gICAgY29uc3QgbmF0aXZlQmFsYW5jZSA9IGF3YWl0IHRoaXMuZ2V0QWNjb3VudEJhbGFuY2UocGFyYW1zLnJvb3RBZGRyZXNzLCBjbGllbnQpO1xuXG4gICAgLy8gQWxnb3JhbmQgYWNjb3VudHMgcmVxdWlyZSBhIG1pbi4gYmFsYW5jZSBvZiAxIEFMR09cbiAgICBjb25zdCBNSU5fTUlDUk9BTEdPU19CQUxBTkNFID0gMTAwMDAwO1xuICAgIGNvbnN0IHNwZW5kYWJsZUFtb3VudCA9IG5ldyBCaWdOdW1iZXIobmF0aXZlQmFsYW5jZSkubWludXMocGFyYW1zLmZlZSkubWludXMoTUlOX01JQ1JPQUxHT1NfQkFMQU5DRSkudG9OdW1iZXIoKTtcblxuICAgIGlmIChuZXcgQmlnTnVtYmVyKHNwZW5kYWJsZUFtb3VudCkuaXNaZXJvKCkgfHwgbmV3IEJpZ051bWJlcihzcGVuZGFibGVBbW91bnQpLmlzTGVzc1RoYW5PckVxdWFsVG8ocGFyYW1zLmZlZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ0luc3VmZmljaWVudCBiYWxhbmNlIHRvIHJlY292ZXIsIGdvdCBiYWxhbmNlOiAnICtcbiAgICAgICAgICBuYXRpdmVCYWxhbmNlICtcbiAgICAgICAgICAnIGZlZTogJyArXG4gICAgICAgICAgcGFyYW1zLmZlZSArXG4gICAgICAgICAgJyBtaW4gYWNjb3VudCBiYWxhbmNlOiAnICtcbiAgICAgICAgICBNSU5fTUlDUk9BTEdPU19CQUxBTkNFXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBsYXRlc3RSb3VuZDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGlmICghcGFyYW1zLmZpcnN0Um91bmQpIHtcbiAgICAgIGxhdGVzdFJvdW5kID0gYXdhaXQgY2xpZW50XG4gICAgICAgIC5zdGF0dXMoKVxuICAgICAgICAuZG8oKVxuICAgICAgICAudGhlbigoc3RhdHVzKSA9PiBzdGF0dXNbJ2xhc3Qtcm91bmQnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgZmlyc3RSb3VuZCA9ICFwYXJhbXMuZmlyc3RSb3VuZCA/IGxhdGVzdFJvdW5kIDogcGFyYW1zLmZpcnN0Um91bmQ7XG4gICAgaWYgKCFmaXJzdFJvdW5kKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBmZXRjaCB0aGUgbGF0ZXN0IHJvdW5kIGZyb20gdGhlIG5vZGUuIFBsZWFzZSBwcm92aWRlIHRoZSBmaXJzdFJvdW5kIG9yIHRyeSBhZ2Fpbi4nKTtcbiAgICB9XG4gICAgY29uc3QgTEFTVF9ST1VORF9CVUZGRVIgPSAxMDAwO1xuICAgIGNvbnN0IGxhc3RSb3VuZCA9IGZpcnN0Um91bmQgKyBMQVNUX1JPVU5EX0JVRkZFUjtcblxuICAgIHR4QnVpbGRlclxuICAgICAgLmZlZSh7IGZlZTogcGFyYW1zLmZlZS50b1N0cmluZygpIH0pXG4gICAgICAuaXNGbGF0RmVlKHRydWUpXG4gICAgICAuc2VuZGVyKHtcbiAgICAgICAgYWRkcmVzczogcGFyYW1zLnJvb3RBZGRyZXNzLFxuICAgICAgfSlcbiAgICAgIC50byh7XG4gICAgICAgIGFkZHJlc3M6IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgfSlcbiAgICAgIC5hbW91bnQoc3BlbmRhYmxlQW1vdW50KVxuICAgICAgLmdlbmVzaXNJZChnZW5lc2lzSWQpXG4gICAgICAuZ2VuZXNpc0hhc2goZ2VuZXNpc0hhc2gpXG4gICAgICAuZmlyc3RSb3VuZChuZXcgQmlnTnVtYmVyKGZpcnN0Um91bmQpLnRvTnVtYmVyKCkpXG4gICAgICAubGFzdFJvdW5kKG5ldyBCaWdOdW1iZXIobGFzdFJvdW5kKS50b051bWJlcigpKTtcblxuICAgIGlmIChwYXJhbXMubm90ZSkge1xuICAgICAgY29uc3Qgbm90ZSA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKHBhcmFtcy5ub3RlLCAndXRmLTgnKSk7XG4gICAgICB0eEJ1aWxkZXIubm90ZShub3RlKTtcbiAgICB9XG5cbiAgICAvLyBDb2xkIHdhbGxldCwgb2ZmbGluZSB2YXVsdFxuICAgIGlmIChpc1Vuc2lnbmVkU3dlZXApIHtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKSBhcyBUeERhdGE7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR4SGV4OiBCdWZmZXIuZnJvbSh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKS50b1N0cmluZygnaGV4JyksXG4gICAgICAgIHR5cGU6IHR4SnNvbi50eXBlLFxuICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogcGFyYW1zLmJpdGdvS2V5LFxuICAgICAgICBhZGRyZXNzOiBwYXJhbXMucm9vdEFkZHJlc3MsXG4gICAgICAgIGNvaW46IHRoaXMuZ2V0Q2hhaW4oKSxcbiAgICAgICAgZmVlSW5mbzogdHhKc29uLmZlZSxcbiAgICAgICAgYW1vdW50OiB0eEpzb24uYW1vdW50ID8/IG5hdGl2ZUJhbGFuY2UudG9TdHJpbmcoKSxcbiAgICAgICAgZmlyc3RSb3VuZDogdHhKc29uLmZpcnN0Um91bmQsXG4gICAgICAgIGxhc3RSb3VuZDogdHhKc29uLmxhc3RSb3VuZCxcbiAgICAgICAgZ2VuZXNpc0lkOiBnZW5lc2lzSWQsXG4gICAgICAgIGdlbmVzaXNIYXNoOiBnZW5lc2lzSGFzaCxcbiAgICAgICAgbm90ZTogdHhKc29uLm5vdGUgPyBCdWZmZXIuZnJvbSh0eEpzb24ubm90ZS5idWZmZXIpLnRvU3RyaW5nKCd1dGYtOCcpIDogdW5kZWZpbmVkLFxuICAgICAgICBrZXlzOiBbcGFyYW1zLnVzZXJLZXksIHBhcmFtcy5iYWNrdXBLZXksIHBhcmFtcy5iaXRnb0tleV0sXG4gICAgICAgIGFkZHJlc3NWZXJzaW9uOiAxLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBOb24tYml0Z28gUmVjb3ZlcnkgKEhvdCB3YWxsZXRzKVxuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB1c2VyUHJ2IH0pO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBiYWNrdXBQcnYgfSk7XG5cbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpIGFzIFR4RGF0YTtcblxuICAgIHJldHVybiB7XG4gICAgICB0eDogQnVmZmVyLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgICAgaWQ6IHR4SnNvbi5pZCxcbiAgICAgIGNvaW46IHRoaXMuZ2V0Q2hhaW4oKSxcbiAgICAgIGZlZTogdHhKc29uLmZlZSxcbiAgICAgIGZpcnN0Um91bmQ6IHR4SnNvbi5maXJzdFJvdW5kLFxuICAgICAgbGFzdFJvdW5kOiB0eEpzb24ubGFzdFJvdW5kLFxuICAgICAgZ2VuZXNpc0lkOiBnZW5lc2lzSWQsXG4gICAgICBnZW5lc2lzSGFzaDogZ2VuZXNpc0hhc2gsXG4gICAgICBub3RlOiB0eEpzb24ubm90ZSA/IEJ1ZmZlci5mcm9tKHR4SnNvbi5ub3RlLmJ1ZmZlcikudG9TdHJpbmcoJ3V0Zi04JykgOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY2NlcHRzIGEgZnVsbHkgc2lnbmVkIHNlcmlhbGl6ZWQgYmFzZTY0IHRyYW5zYWN0aW9uIGFuZCBicm9hZGNhc3RzIGl0IG9uIHRoZSBuZXR3b3JrLlxuICAgKiBVc2VzIHRoZSBleHRlcm5hbCBub2RlIHByb3ZpZGVkIGJ5IHRoZSBjbGllbnRcbiAgICogQHBhcmFtIHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvblxuICAgKiBAcGFyYW0gbm9kZVBhcmFtc1xuICAgKi9cbiAgYXN5bmMgYnJvYWRjYXN0VHJhbnNhY3Rpb24oe1xuICAgIHNlcmlhbGl6ZWRTaWduZWRUcmFuc2FjdGlvbixcbiAgICBub2RlUGFyYW1zLFxuICB9OiBCcm9hZGNhc3RUcmFuc2FjdGlvbk9wdGlvbnMpOiBQcm9taXNlPEJhc2VCcm9hZGNhc3RUcmFuc2FjdGlvblJlc3VsdD4ge1xuICAgIGlmICghbm9kZVBhcmFtcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbGVhc2UgcHJvdmlkZSB0aGUgZGV0YWlscyBvZiB0aGUgYWxnb3JhbmQgbm9kZScpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHhIZXggPSBCdWZmZXIuZnJvbShzZXJpYWxpemVkU2lnbmVkVHJhbnNhY3Rpb24sICdiYXNlNjQnKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBhbGdvVHggPSBVdGlscy50b1VpbnQ4QXJyYXkodHhIZXgpO1xuICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5nZXRDbGllbnQobm9kZVBhcmFtcy50b2tlbiwgbm9kZVBhcmFtcy5iYXNlU2VydmVyLCBub2RlUGFyYW1zLnBvcnQpO1xuXG4gICAgICByZXR1cm4gYXdhaXQgY2xpZW50LnNlbmRSYXdUcmFuc2FjdGlvbihhbGdvVHgpLmRvKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gYnJvYWRjYXN0IHRyYW5zYWN0aW9uLCBlcnJvcjogJyArIGUubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0ZWxsYXIgYW5kIEFsZ29yYW5kIGJvdGggdXNlIGtleXMgb24gdGhlIGVkMjU1MTkgY3VydmUsIGJ1dCB1c2UgZGlmZmVyZW50IGVuY29kaW5ncy5cbiAgICogQXMgdGhlIEhTTSBkb2Vzbid0IGhhdmUgZXhwbGljaXQgc3VwcG9ydCB0byBjcmVhdGUgQWxnb3JhbmQgYWRkcmVzc2VzLCB3ZSB1c2UgdGhlIFN0ZWxsYXJcbiAgICoga2V5cyBhbmQgcmUtZW5jb2RlIHRoZW0gdG8gdGhlIEFsZ29yYW5kIGVuY29kaW5nLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gY3JlYXRpbmcgQWxnb3JhbmQgY3VzdG9kaWFsIHdhbGxldHMgcmV1c2luZyBTdGVsbGFyIGtleXMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzT3JQdWJLZXkgYSBTdGVsbGFyIHB1YmtleSBvciBBbGdvcmFuZCBhZGRyZXNzXG4gICAqIEByZXR1cm4geyp9XG4gICAqL1xuICBwcml2YXRlIHN0ZWxsYXJBZGRyZXNzVG9BbGdvQWRkcmVzcyhhZGRyZXNzT3JQdWJLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8gd2UgaGF2ZSBhbiBBbGdvcmFuZCBhZGRyZXNzXG4gICAgaWYgKHRoaXMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzc09yUHViS2V5KSkge1xuICAgICAgcmV0dXJuIGFkZHJlc3NPclB1YktleTtcbiAgICB9XG5cbiAgICAvLyB3ZSBoYXZlIGEgc3RlbGxhciBrZXlcbiAgICBpZiAoc3RlbGxhci5TdHJLZXkuaXNWYWxpZEVkMjU1MTlQdWJsaWNLZXkoYWRkcmVzc09yUHViS2V5KSkge1xuICAgICAgY29uc3Qgc3RlbGxhclB1YiA9IHN0ZWxsYXIuU3RyS2V5LmRlY29kZUVkMjU1MTlQdWJsaWNLZXkoYWRkcmVzc09yUHViS2V5KTtcbiAgICAgIGNvbnN0IGFsZ29BZGRyZXNzID0gQWxnb0xpYi5hbGdvVXRpbHMuZW5jb2RlQWRkcmVzcyhzdGVsbGFyUHViKTtcbiAgICAgIGlmICh0aGlzLmlzVmFsaWRBZGRyZXNzKGFsZ29BZGRyZXNzKSkge1xuICAgICAgICByZXR1cm4gYWxnb0FkZHJlc3M7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZEFkZHJlc3NFcnJvcignQ2Fubm90IGNvbnZlcnQgU3RlbGxhciBhZGRyZXNzIHRvIGFuIEFsZ29yYW5kIGFkZHJlc3MgdmlhIHN0ZWxsYXIgcHVia2V5LicpO1xuICAgICAgLy8gd2UgaGF2ZSBhIHJvb3QgcHVia2V5XG4gICAgfSBlbHNlIGlmIChBbGdvTGliLmFsZ29VdGlscy5pc1ZhbGlkUHVibGljS2V5KGFkZHJlc3NPclB1YktleSkpIHtcbiAgICAgIGNvbnN0IGtwID0gbmV3IEFsZ29MaWIuS2V5UGFpcih7IHB1YjogYWRkcmVzc09yUHViS2V5IH0pO1xuICAgICAgY29uc3QgYWxnb0FkZHJlc3MgPSBrcC5nZXRBZGRyZXNzKCk7XG4gICAgICBpZiAodGhpcy5pc1ZhbGlkQWRkcmVzcyhhbGdvQWRkcmVzcykpIHtcbiAgICAgICAgcmV0dXJuIGFsZ29BZGRyZXNzO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IoJ0ludmFsaWQgcm9vdCBwdWJrZXkuJyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IoJ05laXRoZXIgYW4gQWxnb3JhbmQgYWRkcmVzcywgYSBzdGVsbGFyIHB1YmtleSBvciBhIHJvb3QgcHVibGljIGtleS4nKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0QnVpbGRlcigpOiBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3Rvcnkge1xuICAgIHJldHVybiBuZXcgQWxnb0xpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCh0aGlzLmdldEJhc2VDaGFpbigpKSk7XG4gIH1cblxuICAvKiogQGluaGVyaXREb2MgKi9cbiAgYXVkaXREZWNyeXB0ZWRLZXkoeyBwdWJsaWNLZXksIHBydiwgbXVsdGlTaWdUeXBlIH06IEF1ZGl0RGVjcnlwdGVkS2V5UGFyYW1zKSB7XG4gICAgaWYgKG11bHRpU2lnVHlwZSA9PT0gJ3RzcycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgbXVsdGlTaWdUeXBlJyk7XG4gICAgfVxuXG4gICAgbGV0IGFsZ29LZXk7XG4gICAgdHJ5IHtcbiAgICAgIGFsZ29LZXkgPSBuZXcgQWxnb0xpYi5LZXlQYWlyKHsgcHJ2IH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwcml2YXRlIGtleTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICAgIGlmIChwdWJsaWNLZXkgJiYgcHVibGljS2V5ICE9PSBhbGdvS2V5LmdldEtleXMoKS5wdWIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwdWJsaWMga2V5Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuO1xuICB9XG59XG4iXX0=