@bitgo-beta/sdk-coin-flrp 1.0.0-alpha.6 → 1.0.0-alpha.61

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 (119) hide show
  1. package/dist/src/flrp.d.ts +10 -17
  2. package/dist/src/flrp.d.ts.map +1 -1
  3. package/dist/src/flrp.js +51 -77
  4. package/dist/src/index.d.ts +0 -1
  5. package/dist/src/index.d.ts.map +1 -1
  6. package/dist/src/index.js +1 -2
  7. package/dist/src/lib/ExportInCTxBuilder.d.ts +44 -0
  8. package/dist/src/lib/ExportInCTxBuilder.d.ts.map +1 -0
  9. package/dist/src/lib/ExportInCTxBuilder.js +151 -0
  10. package/dist/src/lib/ExportInPTxBuilder.d.ts +24 -0
  11. package/dist/src/lib/ExportInPTxBuilder.d.ts.map +1 -0
  12. package/dist/src/lib/ExportInPTxBuilder.js +146 -0
  13. package/dist/src/lib/ImportInCTxBuilder.d.ts +30 -0
  14. package/dist/src/lib/ImportInCTxBuilder.d.ts.map +1 -0
  15. package/dist/src/lib/ImportInCTxBuilder.js +164 -0
  16. package/dist/src/lib/ImportInPTxBuilder.d.ts +31 -0
  17. package/dist/src/lib/ImportInPTxBuilder.d.ts.map +1 -0
  18. package/dist/src/lib/ImportInPTxBuilder.js +147 -0
  19. package/dist/src/lib/atomicInCTransactionBuilder.d.ts +12 -16
  20. package/dist/src/lib/atomicInCTransactionBuilder.d.ts.map +1 -1
  21. package/dist/src/lib/atomicInCTransactionBuilder.js +30 -41
  22. package/dist/src/lib/atomicTransactionBuilder.d.ts +54 -70
  23. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
  24. package/dist/src/lib/atomicTransactionBuilder.js +134 -213
  25. package/dist/src/lib/iface.d.ts +65 -57
  26. package/dist/src/lib/iface.d.ts.map +1 -1
  27. package/dist/src/lib/iface.js +20 -14
  28. package/dist/src/lib/index.d.ts +5 -0
  29. package/dist/src/lib/index.d.ts.map +1 -1
  30. package/dist/src/lib/index.js +12 -2
  31. package/dist/src/lib/keyPair.d.ts +5 -5
  32. package/dist/src/lib/keyPair.d.ts.map +1 -1
  33. package/dist/src/lib/keyPair.js +17 -9
  34. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +41 -0
  35. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/permissionlessValidatorTxBuilder.js +126 -0
  37. package/dist/src/lib/transaction.d.ts +31 -66
  38. package/dist/src/lib/transaction.d.ts.map +1 -1
  39. package/dist/src/lib/transaction.js +339 -199
  40. package/dist/src/lib/transactionBuilder.d.ts +115 -0
  41. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  42. package/dist/src/lib/transactionBuilder.js +232 -0
  43. package/dist/src/lib/transactionBuilderFactory.d.ts +50 -30
  44. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  45. package/dist/src/lib/transactionBuilderFactory.js +129 -72
  46. package/dist/src/lib/utils.d.ts +106 -146
  47. package/dist/src/lib/utils.d.ts.map +1 -1
  48. package/dist/src/lib/utils.js +298 -321
  49. package/dist/test/resources/account.d.ts +81 -0
  50. package/dist/test/resources/account.d.ts.map +1 -0
  51. package/dist/test/resources/account.js +79 -0
  52. package/dist/test/resources/transactionData/exportInC.d.ts +50 -0
  53. package/dist/test/resources/transactionData/exportInC.d.ts.map +1 -0
  54. package/dist/test/resources/transactionData/exportInC.js +58 -0
  55. package/dist/test/resources/transactionData/exportInP.d.ts +52 -0
  56. package/dist/test/resources/transactionData/exportInP.d.ts.map +1 -0
  57. package/dist/test/resources/transactionData/exportInP.js +65 -0
  58. package/dist/test/resources/transactionData/importInC.d.ts +48 -0
  59. package/dist/test/resources/transactionData/importInC.d.ts.map +1 -0
  60. package/dist/test/resources/transactionData/importInC.js +61 -0
  61. package/dist/test/resources/transactionData/importInP.d.ts +58 -0
  62. package/dist/test/resources/transactionData/importInP.d.ts.map +1 -0
  63. package/dist/test/resources/transactionData/importInP.js +73 -0
  64. package/dist/test/unit/flrp.js +449 -68
  65. package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
  66. package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
  67. package/dist/test/unit/lib/exportInCTxBuilder.js +193 -0
  68. package/dist/test/unit/lib/exportInPTxBuilder.d.ts +2 -0
  69. package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -0
  70. package/dist/test/unit/lib/exportInPTxBuilder.js +122 -0
  71. package/dist/test/unit/lib/importInCTxBuilder.d.ts +2 -0
  72. package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -0
  73. package/dist/test/unit/lib/importInCTxBuilder.js +507 -0
  74. package/dist/test/unit/lib/importInPTxBuilder.d.ts +2 -0
  75. package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -0
  76. package/dist/test/unit/lib/importInPTxBuilder.js +126 -0
  77. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  78. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  79. package/dist/test/unit/lib/keyPair.js +158 -0
  80. package/dist/test/unit/lib/signFlowTestSuit.d.ts +20 -0
  81. package/dist/test/unit/lib/signFlowTestSuit.d.ts.map +1 -0
  82. package/dist/test/unit/lib/signFlowTestSuit.js +83 -0
  83. package/dist/test/unit/lib/transactionBuilderFactory.d.ts +2 -0
  84. package/dist/test/unit/lib/transactionBuilderFactory.d.ts.map +1 -0
  85. package/dist/test/unit/lib/transactionBuilderFactory.js +60 -0
  86. package/dist/test/unit/lib/utils.js +572 -207
  87. package/dist/tsconfig.tsbuildinfo +1 -1
  88. package/package.json +19 -10
  89. package/.eslintignore +0 -5
  90. package/.eslintrc.json +0 -7
  91. package/.mocharc.yml +0 -8
  92. package/CHANGELOG.md +0 -0
  93. package/dist/src/iface.d.ts +0 -25
  94. package/dist/src/iface.d.ts.map +0 -1
  95. package/dist/src/iface.js +0 -3
  96. package/dist/src/lib/constants.d.ts +0 -11
  97. package/dist/src/lib/constants.d.ts.map +0 -1
  98. package/dist/src/lib/constants.js +0 -17
  99. package/dist/src/lib/errors.d.ts +0 -8
  100. package/dist/src/lib/errors.d.ts.map +0 -1
  101. package/dist/src/lib/errors.js +0 -19
  102. package/dist/src/lib/exportInCTxBuilder.d.ts +0 -77
  103. package/dist/src/lib/exportInCTxBuilder.d.ts.map +0 -1
  104. package/dist/src/lib/exportInCTxBuilder.js +0 -170
  105. package/dist/src/lib/exportInPTxBuilder.d.ts +0 -30
  106. package/dist/src/lib/exportInPTxBuilder.d.ts.map +0 -1
  107. package/dist/src/lib/exportInPTxBuilder.js +0 -56
  108. package/dist/test/unit/lib/atomicTransactionBuilder.d.ts +0 -2
  109. package/dist/test/unit/lib/atomicTransactionBuilder.d.ts.map +0 -1
  110. package/dist/test/unit/lib/atomicTransactionBuilder.js +0 -222
  111. package/dist/test/unit/lib/exportTxBuilder.d.ts +0 -2
  112. package/dist/test/unit/lib/exportTxBuilder.d.ts.map +0 -1
  113. package/dist/test/unit/lib/exportTxBuilder.js +0 -45
  114. package/dist/test/unit/lib/transaction.d.ts +0 -2
  115. package/dist/test/unit/lib/transaction.d.ts.map +0 -1
  116. package/dist/test/unit/lib/transaction.js +0 -460
  117. package/dist/test/unit/smoke.d.ts +0 -2
  118. package/dist/test/unit/smoke.d.ts.map +0 -1
  119. package/dist/test/unit/smoke.js +0 -23
@@ -34,253 +34,618 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const statics_1 = require("@bitgo-beta/statics");
37
- const sdk_core_1 = require("@bitgo-beta/sdk-core");
38
37
  const assert = __importStar(require("assert"));
39
38
  const utils_1 = require("../../../src/lib/utils");
39
+ const account_1 = require("../../resources/account");
40
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
41
+ const exportInC_1 = require("../../resources/transactionData/exportInC");
42
+ const importInP_1 = require("../../resources/transactionData/importInP");
43
+ const exportInP_1 = require("../../resources/transactionData/exportInP");
44
+ const importInC_1 = require("../../resources/transactionData/importInC");
45
+ const lib_1 = require("../../../src/lib");
46
+ const flarejs_1 = require("@flarenetwork/flarejs");
40
47
  describe('Utils', function () {
41
48
  let utils;
49
+ const network = statics_1.coins.get('flrp').network;
42
50
  beforeEach(function () {
43
51
  utils = new utils_1.Utils();
44
52
  });
53
+ describe('parseUtxoHex', function () {
54
+ it('should parse valid UTXO hex string', async function () {
55
+ const utxoHex = '0x00004e78341d66c1a088658167050e9121925bc97db67d1acfc5735e12d4b58ad2d60000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000070000000011e1a30000000000000000000000000200000003020df6250b04bbdbe8b952a46b7d527aeeeb88ee30ae291f192c747b6010b91f5ae1d09d9c20997a57ff5da59881ac3e3687da723ed8f12c590196fa66ab4bca';
56
+ const parsedUtxo = utils.parseUtxoHex(utxoHex);
57
+ assert.ok(parsedUtxo instanceof flarejs_1.Utxo);
58
+ const utxoId = parsedUtxo.utxoId;
59
+ const pvmapi = new flarejs_1.pvm.PVMApi('https://coston2-api.flare.network');
60
+ const { utxos } = await pvmapi.getUTXOs({
61
+ addresses: ['P-costwo12ll4mfvcsxkrud58mferak8393vsr9h6lkh36f'],
62
+ sourceChain: 'P',
63
+ });
64
+ const utxo = utxos[0];
65
+ assert.strictEqual(utxo.utxoId.txID.toString(), utxoId.txID.toString());
66
+ });
67
+ it('should parse valid UTXO hex string', function () {
68
+ const utxoHex = '0x00004e78341d66c1a088658167050e9121925bc97db67d1acfc5735e12d4b58ad2d60000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000070000000011e1a30000000000000000000000000200000003020df6250b04bbdbe8b952a46b7d527aeeeb88ee30ae291f192c747b6010b91f5ae1d09d9c20997a57ff5da59881ac3e3687da723ed8f12c590196fa66ab4bca';
69
+ const parsedUtxo = utils.parseUtxoHex(utxoHex);
70
+ assert.ok(parsedUtxo instanceof flarejs_1.Utxo);
71
+ assert.ok(parsedUtxo.utxoId, 'utxoId should exist');
72
+ assert.ok(parsedUtxo.assetId, 'assetId should exist');
73
+ assert.ok(parsedUtxo.output, 'output should exist');
74
+ const txIdHex = Buffer.from(parsedUtxo.utxoId.txID.toBytes()).toString('hex');
75
+ assert.strictEqual(txIdHex, '4e78341d66c1a088658167050e9121925bc97db67d1acfc5735e12d4b58ad2d6');
76
+ });
77
+ it('should parse array of UTXO hex strings', function () {
78
+ const utxoHexArray = [
79
+ '0x00004e78341d66c1a088658167050e9121925bc97db67d1acfc5735e12d4b58ad2d60000000058734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000070000000011e1a30000000000000000000000000200000003020df6250b04bbdbe8b952a46b7d527aeeeb88ee30ae291f192c747b6010b91f5ae1d09d9c20997a57ff5da59881ac3e3687da723ed8f12c590196fa66ab4bca',
80
+ ];
81
+ const parsedUtxos = utils.parseUtxoHexArray(utxoHexArray);
82
+ assert.strictEqual(parsedUtxos.length, 1);
83
+ assert.ok(parsedUtxos[0] instanceof flarejs_1.Utxo);
84
+ });
85
+ });
45
86
  describe('includeIn', function () {
46
- it('should return true when all wallet addresses are in output addresses', function () {
47
- const walletAddresses = ['addr1', 'addr2'];
48
- const outputAddresses = ['addr1', 'addr2', 'addr3'];
49
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), true);
87
+ it('should return true when all wallet addresses are in UTXO output addresses', function () {
88
+ const walletAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0], exportInC_1.EXPORT_IN_C.pAddresses[1]];
89
+ const utxoOutputAddresses = [...exportInC_1.EXPORT_IN_C.pAddresses];
90
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), true);
50
91
  });
51
- it('should return false when not all wallet addresses are in output addresses', function () {
52
- const walletAddresses = ['addr1', 'addr2'];
53
- const outputAddresses = ['addr1', 'addr3'];
54
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), false);
92
+ it('should return false when some wallet addresses are not in UTXO output addresses', function () {
93
+ const walletAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0], account_1.ACCOUNT_3.address];
94
+ const utxoOutputAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0], exportInC_1.EXPORT_IN_C.pAddresses[1]];
95
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), false);
55
96
  });
56
97
  it('should return true for empty wallet addresses', function () {
57
98
  const walletAddresses = [];
58
- const outputAddresses = ['addr1', 'addr2'];
59
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), true);
60
- });
61
- it('should return false when wallet address not found in empty output addresses', function () {
62
- const walletAddresses = ['addr1'];
63
- const outputAddresses = [];
64
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), false);
99
+ const utxoOutputAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0]];
100
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), true);
65
101
  });
66
102
  });
67
103
  describe('isValidAddress', function () {
68
- it('should validate single valid Flare addresses', function () {
69
- // Flare addresses start with 'flare:' or 'C-flare:'
70
- const validAddresses = [
71
- 'flare1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6f4avh',
72
- 'C-flare1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6f4avh',
73
- ];
74
- validAddresses.forEach((addr) => {
75
- // Note: The current implementation uses regex validation
76
- // This test will be updated once proper Flare address validation is implemented
77
- const result = utils.isValidAddress(addr);
78
- // Currently returns false due to placeholder implementation
79
- assert.strictEqual(typeof result, 'boolean');
80
- });
104
+ it('should return true for valid mainnet P-chain address', function () {
105
+ assert.strictEqual(utils.isValidAddress(account_1.SEED_ACCOUNT.addressMainnet), true);
81
106
  });
82
- it('should validate array of addresses', function () {
83
- const addresses = [
84
- 'flare1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6f4avh',
85
- 'flare1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6f4avh',
86
- ];
87
- const result = utils.isValidAddress(addresses);
88
- assert.strictEqual(typeof result, 'boolean');
89
- });
90
- it('should validate addresses separated by ~', function () {
91
- const addressString = 'flare1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6f4avh~flare1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6f4avh';
92
- const result = utils.isValidAddress(addressString);
93
- assert.strictEqual(typeof result, 'boolean');
94
- });
95
- it('should reject obviously invalid addresses', function () {
96
- const invalidAddresses = [
97
- '',
98
- 'invalid',
99
- '123',
100
- 'bitcoin1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq',
101
- 'eth:0x1234567890123456789012345678901234567890',
102
- ];
103
- invalidAddresses.forEach((addr) => {
104
- const result = utils.isValidAddress(addr);
105
- // Current implementation may not catch all invalid addresses
106
- assert.strictEqual(typeof result, 'boolean');
107
- });
107
+ it('should return true for valid testnet P-chain address', function () {
108
+ assert.strictEqual(utils.isValidAddress(account_1.SEED_ACCOUNT.addressTestnet), true);
109
+ });
110
+ it('should return true for valid NodeID address', function () {
111
+ assert.strictEqual(utils.isValidAddress('NodeID-abc123xyz'), true);
112
+ });
113
+ it('should return true for array of valid addresses', function () {
114
+ assert.strictEqual(utils.isValidAddress(exportInC_1.EXPORT_IN_C.pAddresses), true);
115
+ });
116
+ it('should return true for tilde-separated addresses', function () {
117
+ const combined = exportInC_1.EXPORT_IN_C.pAddresses.join('~');
118
+ assert.strictEqual(utils.isValidAddress(combined), true);
119
+ });
120
+ it('should return false for invalid address format', function () {
121
+ assert.strictEqual(utils.isValidAddress('invalid'), false);
122
+ });
123
+ it('should return false for address without prefix', function () {
124
+ assert.strictEqual(utils.isValidAddress('flare1abc123'), false);
108
125
  });
109
126
  });
110
- describe('isValidAddressRegex', function () {
111
- it('should test address format with regex', function () {
112
- const testAddress = 'flare1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq6f4avh';
113
- const result = utils['isValidAddressRegex'](testAddress);
114
- assert.strictEqual(typeof result, 'boolean');
127
+ describe('isValidBlockId', function () {
128
+ it('should return true for valid 32-byte hex block ID', function () {
129
+ assert.strictEqual(utils.isValidBlockId(account_1.SEED_ACCOUNT.privateKey), true); // 64 hex chars = 32 bytes
130
+ });
131
+ it('should return false for invalid length block ID', function () {
132
+ assert.strictEqual(utils.isValidBlockId(account_1.INVALID_SHORT_KEYPAIR_KEY), false);
133
+ });
134
+ it('should return false for empty block ID', function () {
135
+ assert.strictEqual(utils.isValidBlockId(''), false);
136
+ });
137
+ });
138
+ describe('isValidPublicKey', function () {
139
+ it('should return true for valid compressed public key starting with 03', function () {
140
+ assert.strictEqual(utils.isValidPublicKey(account_1.SEED_ACCOUNT.publicKey), true);
141
+ });
142
+ it('should return true for valid compressed public key starting with 02', function () {
143
+ assert.strictEqual(utils.isValidPublicKey(account_1.ACCOUNT_1.publicKey), true);
144
+ });
145
+ it('should return true for another valid compressed public key', function () {
146
+ assert.strictEqual(utils.isValidPublicKey(account_1.ACCOUNT_2.publicKey), true);
147
+ });
148
+ it('should return true for valid xpub', function () {
149
+ assert.strictEqual(utils.isValidPublicKey(account_1.SEED_ACCOUNT.xPublicKey), true);
150
+ });
151
+ it('should return true for ACCOUNT_1 xpub', function () {
152
+ assert.strictEqual(utils.isValidPublicKey(account_1.ACCOUNT_1.xPublicKey), true);
153
+ });
154
+ it('should return false for invalid short public key', function () {
155
+ assert.strictEqual(utils.isValidPublicKey(account_1.INVALID_SHORT_KEYPAIR_KEY), false);
115
156
  });
116
- it('should reject empty strings', function () {
117
- const result = utils['isValidAddressRegex']('');
118
- assert.strictEqual(result, false);
157
+ it('should return false for compressed key with wrong prefix', function () {
158
+ const invalidKey = '05' + account_1.SEED_ACCOUNT.privateKey;
159
+ assert.strictEqual(utils.isValidPublicKey(invalidKey), false);
160
+ });
161
+ it('should return false for non-hex public key', function () {
162
+ const invalidKey = 'zz' + account_1.SEED_ACCOUNT.privateKey;
163
+ assert.strictEqual(utils.isValidPublicKey(invalidKey), false);
119
164
  });
120
165
  });
121
- describe('isValidTransactionId', function () {
122
- it('should throw NotImplementedError', function () {
123
- assert.throws(() => utils.isValidTransactionId('txid123'), sdk_core_1.NotImplementedError, 'isValidTransactionId not implemented');
166
+ describe('isValidPrivateKey', function () {
167
+ it('should return true for valid 64-char hex private key', function () {
168
+ assert.strictEqual(utils.isValidPrivateKey(account_1.SEED_ACCOUNT.privateKey), true);
169
+ });
170
+ it('should return true for ACCOUNT_1 private key', function () {
171
+ assert.strictEqual(utils.isValidPrivateKey(account_1.ACCOUNT_1.privateKey), true);
172
+ });
173
+ it('should return true for ACCOUNT_2 private key', function () {
174
+ assert.strictEqual(utils.isValidPrivateKey(account_1.ACCOUNT_2.privateKey), true);
175
+ });
176
+ it('should return true for valid xprv', function () {
177
+ assert.strictEqual(utils.isValidPrivateKey(account_1.SEED_ACCOUNT.xPrivateKey), true);
178
+ });
179
+ it('should return true for 66-char private key ending with 01', function () {
180
+ const extendedKey = account_1.SEED_ACCOUNT.privateKey + '01';
181
+ assert.strictEqual(utils.isValidPrivateKey(extendedKey), true);
182
+ });
183
+ it('should return false for 66-char private key not ending with 01', function () {
184
+ assert.strictEqual(utils.isValidPrivateKey(account_1.INVALID_LONG_KEYPAIR_PRV), false);
185
+ });
186
+ it('should return false for invalid short private key', function () {
187
+ assert.strictEqual(utils.isValidPrivateKey(account_1.INVALID_SHORT_KEYPAIR_KEY), false);
188
+ });
189
+ it('should return false for non-hex private key', function () {
190
+ const invalidKey = 'zz' + account_1.SEED_ACCOUNT.privateKey.slice(2);
191
+ assert.strictEqual(utils.isValidPrivateKey(invalidKey), false);
124
192
  });
125
193
  });
126
- describe('isValidSignature', function () {
127
- it('should throw NotImplementedError', function () {
128
- assert.throws(() => utils.isValidSignature('signature123'), sdk_core_1.NotImplementedError, 'isValidSignature not implemented');
194
+ describe('allHexChars', function () {
195
+ it('should return true for valid private key hex', function () {
196
+ assert.strictEqual(utils.allHexChars(account_1.SEED_ACCOUNT.privateKey), true);
197
+ });
198
+ it('should return true for valid public key hex', function () {
199
+ assert.strictEqual(utils.allHexChars(account_1.SEED_ACCOUNT.publicKey), true);
200
+ });
201
+ it('should return true for hex string with 0x prefix', function () {
202
+ assert.strictEqual(utils.allHexChars(exportInC_1.EXPORT_IN_C.cHexAddress), true);
203
+ });
204
+ it('should return true for valid signature hex', function () {
205
+ assert.strictEqual(utils.allHexChars(account_1.SEED_ACCOUNT.signature), true);
206
+ });
207
+ it('should return false for non-hex characters', function () {
208
+ assert.strictEqual(utils.allHexChars('ghijkl'), false);
209
+ });
210
+ it('should return false for empty string', function () {
211
+ assert.strictEqual(utils.allHexChars(''), false);
129
212
  });
130
213
  });
131
- describe('createSignature', function () {
132
- it('should create signature using secp256k1', function () {
133
- const network = statics_1.coins.get('flrp').network;
134
- const message = Buffer.from('hello world', 'utf8');
135
- const privateKey = Buffer.from('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'hex');
214
+ describe('createSignature and verifySignature', function () {
215
+ it('should create a valid 65-byte signature', function () {
216
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
217
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
136
218
  const signature = utils.createSignature(network, message, privateKey);
137
219
  assert.ok(signature instanceof Buffer);
138
- assert.ok(signature.length > 0);
139
- });
140
- it('should create different signatures for different messages', function () {
141
- const network = statics_1.coins.get('flrp').network;
142
- const message1 = Buffer.from('message 1', 'utf8');
143
- const message2 = Buffer.from('message 2', 'utf8');
144
- const privateKey = Buffer.from('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'hex');
145
- const sig1 = utils.createSignature(network, message1, privateKey);
146
- const sig2 = utils.createSignature(network, message2, privateKey);
147
- assert.notDeepStrictEqual(sig1, sig2);
148
- });
149
- it('should throw error for invalid private key', function () {
150
- const network = statics_1.coins.get('flrp').network;
151
- const message = Buffer.from('hello world', 'utf8');
152
- const invalidPrivateKey = Buffer.from('invalid', 'utf8');
153
- assert.throws(() => utils.createSignature(network, message, invalidPrivateKey), /Failed to create signature/);
220
+ assert.strictEqual(signature.length, 65);
154
221
  });
155
- });
156
- describe('verifySignature', function () {
157
- it('should verify valid signature', function () {
158
- const network = statics_1.coins.get('flrp').network;
159
- const message = Buffer.from('hello world', 'utf8');
160
- const privateKey = Buffer.from('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'hex');
161
- // Create signature
222
+ it('should verify a valid signature', function () {
223
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
224
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
225
+ const publicKey = Buffer.from(account_1.SEED_ACCOUNT.publicKey, 'hex');
162
226
  const signature = utils.createSignature(network, message, privateKey);
163
- // Get public key (this would normally come from the private key)
164
- // For testing, we'll use a mock public key approach
165
- const publicKey = Buffer.from('02' + '0'.repeat(62), 'hex'); // Compressed public key format
166
- // Note: This test may fail if the public key doesn't match the private key
167
- // In a real implementation, you'd derive the public key from the private key
168
- // The method returns false when verification fails instead of throwing
169
- const isValid = utils.verifySignature(network, message, signature, publicKey);
170
- assert.strictEqual(typeof isValid, 'boolean');
171
- // With mock public key, this should return false
172
- assert.strictEqual(isValid, false);
227
+ const sigOnly = signature.slice(0, 64);
228
+ const messageHash = utils.sha256(message);
229
+ const isValid = utils.verifySignature(messageHash, sigOnly, publicKey);
230
+ assert.strictEqual(isValid, true);
173
231
  });
174
232
  it('should return false for invalid signature', function () {
175
- const network = statics_1.coins.get('flrp').network;
176
- const message = Buffer.from('hello world', 'utf8');
177
- const invalidSignature = Buffer.from('invalid signature', 'utf8');
178
- const publicKey = Buffer.from('02' + '0'.repeat(62), 'hex');
179
- // This should return false due to invalid signature format
180
- // The method catches errors internally and returns false
181
- const result = utils.verifySignature(network, message, invalidSignature, publicKey);
182
- assert.strictEqual(result, false);
233
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
234
+ const publicKey = Buffer.from(account_1.SEED_ACCOUNT.publicKey, 'hex');
235
+ const invalidSignature = Buffer.alloc(64);
236
+ const messageHash = utils.sha256(message);
237
+ const isValid = utils.verifySignature(messageHash, invalidSignature, publicKey);
238
+ assert.strictEqual(isValid, false);
239
+ });
240
+ it('should create signature with ACCOUNT_1 keys', function () {
241
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
242
+ const privateKey = Buffer.from(account_1.ACCOUNT_1.privateKey, 'hex');
243
+ const signature = utils.createSignature(network, message, privateKey);
244
+ assert.ok(signature instanceof Buffer);
245
+ assert.strictEqual(signature.length, 65);
183
246
  });
184
247
  });
185
- describe('address parsing utilities', function () {
186
- it('should handle address separator constants', function () {
187
- const { ADDRESS_SEPARATOR } = require('../../../src/lib/iface');
188
- assert.strictEqual(ADDRESS_SEPARATOR, '~');
248
+ describe('createNewSig', function () {
249
+ it('should create a signature from valid signature hex string', function () {
250
+ const sig = utils.createNewSig(account_1.SEED_ACCOUNT.signature);
251
+ assert.ok(sig);
252
+ });
253
+ it('should create a signature from export signature hex', function () {
254
+ const sigHex = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.signature[0]);
255
+ const sig = utils.createNewSig(sigHex);
256
+ assert.ok(sig);
189
257
  });
190
- it('should handle input separator constants', function () {
191
- const { INPUT_SEPARATOR } = require('../../../src/lib/iface');
192
- assert.strictEqual(INPUT_SEPARATOR, ':');
258
+ it('should pad short hex strings', function () {
259
+ const sigHex = account_1.INVALID_SHORT_KEYPAIR_KEY;
260
+ const sig = utils.createNewSig(sigHex);
261
+ assert.ok(sig);
193
262
  });
194
263
  });
195
- describe('error handling', function () {
196
- it('should properly extend base utils', function () {
197
- // Test that utils class exists and has expected methods
198
- assert.ok('isValidAddress' in utils);
199
- assert.ok('includeIn' in utils);
200
- assert.ok('createSignature' in utils);
201
- assert.ok('verifySignature' in utils);
202
- });
203
- it('should handle parsing errors gracefully', function () {
204
- // Test that utils can handle malformed input without crashing
205
- // Note: These may throw errors, which is acceptable behavior
206
- try {
207
- utils.isValidAddress(null);
208
- utils.isValidAddress(undefined);
209
- }
210
- catch (error) {
211
- // Expected behavior - utils should handle or throw meaningful errors
212
- assert.ok(error instanceof Error);
213
- }
264
+ describe('createEmptySigWithAddress and getAddressFromEmptySig', function () {
265
+ it('should create empty signature with embedded C-chain address', function () {
266
+ const addressHex = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.cHexAddress);
267
+ const sig = utils.createEmptySigWithAddress(addressHex);
268
+ assert.ok(sig);
269
+ });
270
+ it('should extract embedded address from empty signature', function () {
271
+ const addressHex = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.cHexAddress).toLowerCase();
272
+ const sig = utils.createEmptySigWithAddress(addressHex);
273
+ // Get signature bytes and convert to hex
274
+ const sigBytes = sig.toBytes();
275
+ const sigHex = Buffer.from(sigBytes).toString('hex');
276
+ const extractedAddress = utils.getAddressFromEmptySig(sigHex);
277
+ assert.strictEqual(extractedAddress, addressHex);
278
+ });
279
+ it('should handle 0x prefixed address', function () {
280
+ const sig = utils.createEmptySigWithAddress(exportInC_1.EXPORT_IN_C.cHexAddress);
281
+ assert.ok(sig);
282
+ });
283
+ it('should return empty string for short signature', function () {
284
+ const shortSig = account_1.SEED_ACCOUNT.privateKey; // 64 chars, less than 130
285
+ assert.strictEqual(utils.getAddressFromEmptySig(shortSig), '');
214
286
  });
215
287
  });
216
- describe('constants validation', function () {
217
- it('should have correct constant values', function () {
218
- const constants = require('../../../src/lib/constants');
219
- assert.strictEqual(typeof constants.DECODED_BLOCK_ID_LENGTH, 'number');
220
- assert.strictEqual(typeof constants.SHORT_PUB_KEY_LENGTH, 'number');
221
- assert.strictEqual(typeof constants.COMPRESSED_PUBLIC_KEY_LENGTH, 'number');
222
- assert.strictEqual(typeof constants.UNCOMPRESSED_PUBLIC_KEY_LENGTH, 'number');
223
- assert.strictEqual(typeof constants.RAW_PRIVATE_KEY_LENGTH, 'number');
224
- assert.strictEqual(typeof constants.SUFFIXED_PRIVATE_KEY_LENGTH, 'number');
225
- assert.strictEqual(typeof constants.PRIVATE_KEY_COMPRESSED_SUFFIX, 'string');
226
- assert.strictEqual(typeof constants.OUTPUT_INDEX_HEX_LENGTH, 'number');
227
- assert.ok(constants.ADDRESS_REGEX instanceof RegExp);
228
- assert.ok(constants.HEX_REGEX instanceof RegExp);
288
+ describe('sha256', function () {
289
+ it('should compute SHA256 hash of message', function () {
290
+ const data = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
291
+ const hash = utils.sha256(data);
292
+ assert.ok(hash instanceof Buffer);
293
+ assert.strictEqual(hash.length, 32);
294
+ });
295
+ it('should produce consistent hash for same input', function () {
296
+ const data = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
297
+ const hash1 = utils.sha256(data);
298
+ const hash2 = utils.sha256(data);
299
+ assert.deepStrictEqual(hash1, hash2);
300
+ });
301
+ it('should produce different hash for different input', function () {
302
+ const data1 = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
303
+ const data2 = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'utf8');
304
+ const hash1 = utils.sha256(data1);
305
+ const hash2 = utils.sha256(data2);
306
+ assert.notDeepStrictEqual(hash1, hash2);
229
307
  });
230
308
  });
231
- describe('Memo Utilities', function () {
232
- it('should convert string to bytes', function () {
233
- const text = 'Hello Flare';
234
- const bytes = utils.stringToBytes(text);
235
- assert.ok(bytes instanceof Uint8Array);
236
- assert.strictEqual(utils.bytesToString(bytes), text);
237
- });
238
- it('should handle UTF-8 strings', function () {
239
- const text = 'Hello 世界 🌍';
240
- const bytes = utils.stringToBytes(text);
241
- assert.strictEqual(utils.bytesToString(bytes), text);
242
- });
243
- it('should create memo bytes from string', function () {
244
- const text = 'Memo text';
245
- const bytes = utils.createMemoBytes(text);
246
- assert.ok(bytes instanceof Uint8Array);
247
- assert.strictEqual(utils.parseMemoBytes(bytes), text);
248
- });
249
- it('should create memo bytes from JSON object', function () {
250
- const obj = { type: 'payment', amount: 1000 };
251
- const bytes = utils.createMemoBytes(obj);
252
- const parsed = utils.parseMemoBytes(bytes);
253
- assert.strictEqual(parsed, JSON.stringify(obj));
254
- });
255
- it('should handle Uint8Array input', function () {
256
- const originalBytes = new Uint8Array([1, 2, 3, 4]);
257
- const bytes = utils.createMemoBytes(originalBytes);
258
- assert.deepStrictEqual(bytes, originalBytes);
259
- });
260
- it('should throw error for invalid memo type', function () {
261
- assert.throws(() => {
262
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
263
- utils.createMemoBytes(123);
264
- }, /Invalid memo format/);
265
- });
266
- it('should parse empty memo', function () {
267
- const emptyBytes = new Uint8Array([]);
268
- const parsed = utils.parseMemoBytes(emptyBytes);
269
- assert.strictEqual(parsed, '');
270
- });
271
- it('should validate memo size', function () {
272
- const smallMemo = new Uint8Array([1, 2, 3]);
273
- const largeMemo = new Uint8Array(5000);
274
- assert.strictEqual(utils.validateMemoSize(smallMemo), true);
275
- assert.strictEqual(utils.validateMemoSize(largeMemo), false);
276
- assert.strictEqual(utils.validateMemoSize(largeMemo, 6000), true);
277
- });
278
- it('should handle special characters in memo', function () {
279
- const specialText = 'Special: \n\t\r\0';
280
- const bytes = utils.createMemoBytes(specialText);
281
- const parsed = utils.parseMemoBytes(bytes);
282
- assert.strictEqual(parsed, specialText);
309
+ describe('validateRawTransaction', function () {
310
+ it('should not throw for valid unsigned hex transaction', function () {
311
+ const rawTx = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.unsignedHex);
312
+ assert.doesNotThrow(() => utils.validateRawTransaction(rawTx));
313
+ });
314
+ it('should not throw for valid signed hex transaction', function () {
315
+ const rawTx = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.signedHex);
316
+ assert.doesNotThrow(() => utils.validateRawTransaction(rawTx));
317
+ });
318
+ it('should not throw for import transaction hex', function () {
319
+ const rawTx = utils.removeHexPrefix(importInP_1.IMPORT_IN_P.unsignedHex);
320
+ assert.doesNotThrow(() => utils.validateRawTransaction(rawTx));
321
+ });
322
+ it('should throw for empty transaction', function () {
323
+ assert.throws(() => utils.validateRawTransaction(''), /Raw transaction is empty/);
324
+ });
325
+ it('should throw for non-hex transaction', function () {
326
+ assert.throws(() => utils.validateRawTransaction('xyz123'), /Raw transaction is not hex string/);
327
+ });
328
+ });
329
+ describe('removeHexPrefix', function () {
330
+ it('should remove 0x prefix from C-chain address', function () {
331
+ assert.strictEqual(utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.cHexAddress), exportInC_1.EXPORT_IN_C.cHexAddress.slice(2));
332
+ });
333
+ it('should remove 0x prefix from unsigned hex', function () {
334
+ assert.strictEqual(utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.unsignedHex), exportInC_1.EXPORT_IN_C.unsignedHex.slice(2));
335
+ });
336
+ it('should return string unchanged if no prefix', function () {
337
+ assert.strictEqual(utils.removeHexPrefix(account_1.SEED_ACCOUNT.privateKey), account_1.SEED_ACCOUNT.privateKey);
338
+ });
339
+ it('should handle empty string', function () {
340
+ assert.strictEqual(utils.removeHexPrefix(''), '');
341
+ });
342
+ });
343
+ describe('outputidxNumberToBuffer and outputidxBufferToNumber', function () {
344
+ it('should handle nonce value', function () {
345
+ const nonceStr = exportInC_1.EXPORT_IN_C.nonce.toString();
346
+ const buffer = utils.outputidxNumberToBuffer(nonceStr);
347
+ const result = utils.outputidxBufferToNumber(buffer);
348
+ assert.strictEqual(result, nonceStr);
349
+ });
350
+ it('should produce 4-byte buffer', function () {
351
+ const buffer = utils.outputidxNumberToBuffer('255');
352
+ assert.strictEqual(buffer.length, 4);
353
+ });
354
+ });
355
+ describe('addressToString', function () {
356
+ it('should convert address buffer to mainnet bech32 string', function () {
357
+ const address = account_1.SEED_ACCOUNT.addressMainnet;
358
+ const addressBuffer = utils.parseAddress(address);
359
+ const result = utils.addressToString('flare', 'P', addressBuffer);
360
+ assert.ok(result.startsWith('P-'));
361
+ assert.ok(result.includes('flare'));
362
+ });
363
+ it('should convert address buffer to testnet bech32 string', function () {
364
+ const address = account_1.SEED_ACCOUNT.addressTestnet;
365
+ const addressBuffer = utils.parseAddress(address);
366
+ const result = utils.addressToString('costwo', 'P', addressBuffer);
367
+ assert.ok(result.startsWith('P-'));
368
+ assert.ok(result.includes('costwo'));
369
+ });
370
+ });
371
+ describe('cb58Encode and cb58Decode', function () {
372
+ it('should encode and decode target chain ID correctly', function () {
373
+ const encoded = exportInC_1.EXPORT_IN_C.targetChainId;
374
+ const decoded = utils.cb58Decode(encoded);
375
+ const reEncoded = utils.cb58Encode(decoded);
376
+ assert.strictEqual(reEncoded, encoded);
377
+ });
378
+ it('should encode and decode source chain ID correctly', function () {
379
+ const encoded = importInP_1.IMPORT_IN_P.sourceChainId;
380
+ const decoded = utils.cb58Decode(encoded);
381
+ const reEncoded = utils.cb58Encode(decoded);
382
+ assert.strictEqual(reEncoded, encoded);
383
+ });
384
+ it('should throw for invalid checksum', function () {
385
+ assert.throws(() => utils.cb58Decode('1111111111111'), /Invalid checksum/);
386
+ });
387
+ });
388
+ describe('parseAddress and stringToAddress', function () {
389
+ it('should parse hex address with 0x prefix', function () {
390
+ const buffer = utils.parseAddress(exportInC_1.EXPORT_IN_C.cHexAddress);
391
+ assert.ok(buffer instanceof Buffer);
392
+ assert.strictEqual(buffer.length, 20);
393
+ });
394
+ it('should parse mainnet bech32 address', function () {
395
+ const buffer = utils.parseAddress(account_1.SEED_ACCOUNT.addressMainnet);
396
+ assert.ok(buffer instanceof Buffer);
397
+ assert.strictEqual(buffer.length, 20);
398
+ });
399
+ it('should parse testnet bech32 address', function () {
400
+ const buffer = utils.parseAddress(account_1.SEED_ACCOUNT.addressTestnet);
401
+ assert.ok(buffer instanceof Buffer);
402
+ assert.strictEqual(buffer.length, 20);
403
+ });
404
+ it('should parse P-chain addresses from export data', function () {
405
+ exportInC_1.EXPORT_IN_C.pAddresses.forEach((address) => {
406
+ const buffer = utils.parseAddress(address);
407
+ assert.ok(buffer instanceof Buffer);
408
+ assert.strictEqual(buffer.length, 20);
409
+ });
410
+ });
411
+ it('should throw for address without dash separator', function () {
412
+ assert.throws(() => utils.parseAddress('flare1abc'), /Valid address should include -/);
413
+ });
414
+ it('should throw for invalid HRP', function () {
415
+ assert.throws(() => utils.parseAddress('P-invalid1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq5evzmy'), /Invalid HRP/);
416
+ });
417
+ });
418
+ describe('flareIdString', function () {
419
+ it('should create Id from private key hex string', function () {
420
+ const id = utils.flareIdString(account_1.SEED_ACCOUNT.privateKey);
421
+ assert.ok(id);
422
+ });
423
+ it('should create Id from asset ID hex', function () {
424
+ // Asset ID is typically 32 bytes (64 hex chars)
425
+ const assetIdHex = account_1.SEED_ACCOUNT.privateKey; // Using as a 32-byte hex
426
+ const id = utils.flareIdString(assetIdHex);
427
+ assert.ok(id);
428
+ });
429
+ });
430
+ describe('recoverySignature', function () {
431
+ it('should recover public key from valid signature', function () {
432
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
433
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
434
+ // Create signature using the same private key (createSignature hashes the message internally)
435
+ const signature = utils.createSignature(network, message, privateKey);
436
+ // Recover public key - pass the hashed message since recoverySignature expects pre-hashed
437
+ const messageHash = utils.sha256(message);
438
+ const recoveredPubKey = utils.recoverySignature(messageHash, signature);
439
+ assert.ok(recoveredPubKey instanceof Buffer);
440
+ assert.strictEqual(recoveredPubKey.length, 33); // Should be compressed public key (33 bytes)
441
+ });
442
+ it('should recover same public key for same message and signature', function () {
443
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
444
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
445
+ const signature = utils.createSignature(network, message, privateKey);
446
+ const messageHash = utils.sha256(message);
447
+ const pubKey1 = utils.recoverySignature(messageHash, signature);
448
+ const pubKey2 = utils.recoverySignature(messageHash, signature);
449
+ assert.deepStrictEqual(pubKey1, pubKey2);
450
+ });
451
+ it('should recover public key that matches original key', function () {
452
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
453
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
454
+ // Get original public key
455
+ const originalPubKey = Buffer.from(secp256k1_1.ecc.pointFromScalar(privateKey, true));
456
+ // Create signature and recover public key
457
+ const signature = utils.createSignature(network, message, privateKey);
458
+ const messageHash = utils.sha256(message);
459
+ const recoveredPubKey = utils.recoverySignature(messageHash, signature);
460
+ // Convert both to hex strings for comparison
461
+ assert.strictEqual(recoveredPubKey.toString('hex'), originalPubKey.toString('hex'));
462
+ });
463
+ it('should recover public key using ACCOUNT_1 keys', function () {
464
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
465
+ const privateKey = Buffer.from(account_1.ACCOUNT_1.privateKey, 'hex');
466
+ const originalPubKey = Buffer.from(secp256k1_1.ecc.pointFromScalar(privateKey, true));
467
+ const signature = utils.createSignature(network, message, privateKey);
468
+ const messageHash = utils.sha256(message);
469
+ const recoveredPubKey = utils.recoverySignature(messageHash, signature);
470
+ assert.strictEqual(recoveredPubKey.toString('hex'), originalPubKey.toString('hex'));
471
+ });
472
+ it('should throw error for invalid signature length', function () {
473
+ const messageHash = utils.sha256(Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8'));
474
+ const invalidSignature = Buffer.from(account_1.INVALID_SHORT_KEYPAIR_KEY, 'hex');
475
+ assert.throws(() => utils.recoverySignature(messageHash, invalidSignature), /Failed to recover signature/);
476
+ });
477
+ it('should throw error for signature with invalid recovery parameter', function () {
478
+ const messageHash = utils.sha256(Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8'));
479
+ const signature = Buffer.alloc(65); // Valid length but all zeros - invalid signature
480
+ assert.throws(() => utils.recoverySignature(messageHash, signature), /Failed to recover signature/);
481
+ });
482
+ it('should recover signature and verify sender address from signed C-chain Export tx', async function () {
483
+ // Transaction from actual build response - C-chain Export tx
484
+ const tx = '0x0000000000010000007278db5c30bed04c05ce209179812850bbb3fe6d46d7eef3744d814c0da55524790000000000000000000000000000000000000000000000000000000000000000000000012a96025ad506b9fbb9023fbdc1665c7f7d7c923f000000000605236658734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd00000000000000000000000158734f94af871c3d131b56131b6fb7a0291eacadd261e69dfb42a9cdf6f7fddd000000070000000006052340000000000000000000000002000000037fa8c7e0c8ad9f09f9179b42b77e94a487c3df758d4ba538f772333ca7bf3668a2fe36648438c79d9b6b77b56effb860eaa430e0e30c4e392f59cd08000000010000000900000001750076e67d9720283a71c6e7a9a88ff662608fefdd3f316f1211957ca1873eee3ee4a74b468bda66176a3e5d3ab54d43a8c0be12348f251a3093c16d9db00cd001c31e9c15';
485
+ const expectedSenderAddress = '0x2a96025ad506b9fbb9023fbdc1665c7f7d7c923f';
486
+ const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp'));
487
+ const txn = (await factory.from(tx).build());
488
+ const signablePayload = txn.signablePayload;
489
+ const signatures = txn.signature;
490
+ const sig = Buffer.from(utils.removeHexPrefix(signatures[0]), 'hex');
491
+ // Recover public key from signature (signablePayload is already SHA256 hashed)
492
+ const recoveredPubKey = utils.recoverySignature(signablePayload, sig);
493
+ // Get the sender address from the transaction inputs
494
+ const txInputs = txn.inputs;
495
+ const senderAddressFromTx = txInputs[0].address.toLowerCase();
496
+ // Verify sender address matches expected
497
+ assert.strictEqual(senderAddressFromTx, expectedSenderAddress.toLowerCase(), 'Transaction sender address does not match expected');
498
+ // Derive address from recovered public key
499
+ const derivedEvmAddress = '0x' + Buffer.from(new flarejs_1.Address(flarejs_1.secp256k1.publicKeyToEthAddress(recoveredPubKey)).toBytes()).toString('hex');
500
+ // Verify the recovered public key matches the sender
501
+ assert.strictEqual(derivedEvmAddress.toLowerCase(), senderAddressFromTx, 'Recovered public key does not match sender address');
502
+ // Also verify signature validity
503
+ const sigOnly = sig.slice(0, 64);
504
+ const isValid = utils.verifySignature(signablePayload, sigOnly, recoveredPubKey);
505
+ assert.strictEqual(isValid, true, 'Signature verification failed');
506
+ });
507
+ });
508
+ describe('isTransactionOf', function () {
509
+ const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get('tflrp'));
510
+ const utilsInstance = new utils_1.Utils();
511
+ const testnetNetwork = statics_1.coins.get('tflrp').network;
512
+ const pChainBlockchainIdHex = Buffer.from(utilsInstance.cb58Decode(testnetNetwork.blockchainID)).toString('hex');
513
+ const cChainBlockchainIdHex = Buffer.from(utilsInstance.cb58Decode(testnetNetwork.cChainBlockchainID)).toString('hex');
514
+ it('should return true for Import in P transaction with matching P-chain blockchain ID', async function () {
515
+ const txBuilder = factory
516
+ .getImportInPBuilder()
517
+ .threshold(importInP_1.IMPORT_IN_P.threshold)
518
+ .locktime(importInP_1.IMPORT_IN_P.locktime)
519
+ .fromPubKey(importInP_1.IMPORT_IN_P.corethAddresses)
520
+ .to(importInP_1.IMPORT_IN_P.pAddresses)
521
+ .externalChainId(importInP_1.IMPORT_IN_P.sourceChainId)
522
+ .feeState(importInP_1.IMPORT_IN_P.feeState)
523
+ .context(importInP_1.IMPORT_IN_P.context)
524
+ .utxos(importInP_1.IMPORT_IN_P.utxoHex);
525
+ const tx = (await txBuilder.build());
526
+ const flareTransaction = tx.getFlareTransaction();
527
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, pChainBlockchainIdHex), true);
528
+ });
529
+ it('should return false for Import in P transaction with non-matching C-chain blockchain ID', async function () {
530
+ const txBuilder = factory
531
+ .getImportInPBuilder()
532
+ .threshold(importInP_1.IMPORT_IN_P.threshold)
533
+ .locktime(importInP_1.IMPORT_IN_P.locktime)
534
+ .fromPubKey(importInP_1.IMPORT_IN_P.corethAddresses)
535
+ .to(importInP_1.IMPORT_IN_P.pAddresses)
536
+ .externalChainId(importInP_1.IMPORT_IN_P.sourceChainId)
537
+ .feeState(importInP_1.IMPORT_IN_P.feeState)
538
+ .context(importInP_1.IMPORT_IN_P.context)
539
+ .utxos(importInP_1.IMPORT_IN_P.utxoHex);
540
+ const tx = (await txBuilder.build());
541
+ const flareTransaction = tx.getFlareTransaction();
542
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, cChainBlockchainIdHex), false);
543
+ });
544
+ it('should return true for Export in P transaction with matching P-chain blockchain ID', async function () {
545
+ const txBuilder = factory
546
+ .getExportInPBuilder()
547
+ .threshold(exportInP_1.EXPORT_IN_P.threshold)
548
+ .locktime(exportInP_1.EXPORT_IN_P.locktime)
549
+ .fromPubKey(exportInP_1.EXPORT_IN_P.pAddresses)
550
+ .externalChainId(exportInP_1.EXPORT_IN_P.sourceChainId)
551
+ .feeState(exportInP_1.EXPORT_IN_P.feeState)
552
+ .context(exportInP_1.EXPORT_IN_P.context)
553
+ .amount(exportInP_1.EXPORT_IN_P.amount)
554
+ .utxos(exportInP_1.EXPORT_IN_P.utxos);
555
+ const tx = (await txBuilder.build());
556
+ const flareTransaction = tx.getFlareTransaction();
557
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, pChainBlockchainIdHex), true);
558
+ });
559
+ it('should return false for Export in P transaction with non-matching C-chain blockchain ID', async function () {
560
+ const txBuilder = factory
561
+ .getExportInPBuilder()
562
+ .threshold(exportInP_1.EXPORT_IN_P.threshold)
563
+ .locktime(exportInP_1.EXPORT_IN_P.locktime)
564
+ .fromPubKey(exportInP_1.EXPORT_IN_P.pAddresses)
565
+ .externalChainId(exportInP_1.EXPORT_IN_P.sourceChainId)
566
+ .feeState(exportInP_1.EXPORT_IN_P.feeState)
567
+ .context(exportInP_1.EXPORT_IN_P.context)
568
+ .amount(exportInP_1.EXPORT_IN_P.amount)
569
+ .utxos(exportInP_1.EXPORT_IN_P.utxos);
570
+ const tx = (await txBuilder.build());
571
+ const flareTransaction = tx.getFlareTransaction();
572
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, cChainBlockchainIdHex), false);
573
+ });
574
+ it('should return true for Import in C transaction with matching C-chain blockchain ID', async function () {
575
+ const txBuilder = factory
576
+ .getImportInCBuilder()
577
+ .threshold(importInC_1.IMPORT_IN_C.threshold)
578
+ .locktime(importInC_1.IMPORT_IN_C.locktime)
579
+ .fromPubKey(importInC_1.IMPORT_IN_C.pAddresses)
580
+ .externalChainId(importInC_1.IMPORT_IN_C.sourceChainId)
581
+ .fee(importInC_1.IMPORT_IN_C.fee)
582
+ .context(importInC_1.IMPORT_IN_C.context)
583
+ .to(importInC_1.IMPORT_IN_C.to)
584
+ .utxos(importInC_1.IMPORT_IN_C.utxos);
585
+ const tx = (await txBuilder.build());
586
+ const flareTransaction = tx.getFlareTransaction();
587
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, cChainBlockchainIdHex), true);
588
+ });
589
+ it('should return false for Import in C transaction with non-matching P-chain blockchain ID', async function () {
590
+ const txBuilder = factory
591
+ .getImportInCBuilder()
592
+ .threshold(importInC_1.IMPORT_IN_C.threshold)
593
+ .locktime(importInC_1.IMPORT_IN_C.locktime)
594
+ .fromPubKey(importInC_1.IMPORT_IN_C.pAddresses)
595
+ .externalChainId(importInC_1.IMPORT_IN_C.sourceChainId)
596
+ .fee(importInC_1.IMPORT_IN_C.fee)
597
+ .context(importInC_1.IMPORT_IN_C.context)
598
+ .to(importInC_1.IMPORT_IN_C.to)
599
+ .utxos(importInC_1.IMPORT_IN_C.utxos);
600
+ const tx = (await txBuilder.build());
601
+ const flareTransaction = tx.getFlareTransaction();
602
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, pChainBlockchainIdHex), false);
603
+ });
604
+ it('should return true for Export in C transaction with matching C-chain blockchain ID', async function () {
605
+ const txBuilder = factory
606
+ .getExportInCBuilder()
607
+ .fromPubKey(exportInC_1.EXPORT_IN_C.cHexAddress)
608
+ .nonce(exportInC_1.EXPORT_IN_C.nonce)
609
+ .amount(exportInC_1.EXPORT_IN_C.amount)
610
+ .threshold(exportInC_1.EXPORT_IN_C.threshold)
611
+ .locktime(exportInC_1.EXPORT_IN_C.locktime)
612
+ .to(exportInC_1.EXPORT_IN_C.pAddresses)
613
+ .fee(exportInC_1.EXPORT_IN_C.fee)
614
+ .context(exportInC_1.EXPORT_IN_C.context);
615
+ const tx = (await txBuilder.build());
616
+ const flareTransaction = tx.getFlareTransaction();
617
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, cChainBlockchainIdHex), true);
618
+ });
619
+ it('should return false for Export in C transaction with non-matching P-chain blockchain ID', async function () {
620
+ const txBuilder = factory
621
+ .getExportInCBuilder()
622
+ .fromPubKey(exportInC_1.EXPORT_IN_C.cHexAddress)
623
+ .nonce(exportInC_1.EXPORT_IN_C.nonce)
624
+ .amount(exportInC_1.EXPORT_IN_C.amount)
625
+ .threshold(exportInC_1.EXPORT_IN_C.threshold)
626
+ .locktime(exportInC_1.EXPORT_IN_C.locktime)
627
+ .to(exportInC_1.EXPORT_IN_C.pAddresses)
628
+ .fee(exportInC_1.EXPORT_IN_C.fee)
629
+ .context(exportInC_1.EXPORT_IN_C.context);
630
+ const tx = (await txBuilder.build());
631
+ const flareTransaction = tx.getFlareTransaction();
632
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, pChainBlockchainIdHex), false);
633
+ });
634
+ it('should return false for invalid blockchain ID', async function () {
635
+ const txBuilder = factory
636
+ .getImportInPBuilder()
637
+ .threshold(importInP_1.IMPORT_IN_P.threshold)
638
+ .locktime(importInP_1.IMPORT_IN_P.locktime)
639
+ .fromPubKey(importInP_1.IMPORT_IN_P.corethAddresses)
640
+ .to(importInP_1.IMPORT_IN_P.pAddresses)
641
+ .externalChainId(importInP_1.IMPORT_IN_P.sourceChainId)
642
+ .feeState(importInP_1.IMPORT_IN_P.feeState)
643
+ .context(importInP_1.IMPORT_IN_P.context)
644
+ .utxos(importInP_1.IMPORT_IN_P.utxoHex);
645
+ const tx = (await txBuilder.build());
646
+ const flareTransaction = tx.getFlareTransaction();
647
+ assert.strictEqual(utilsInstance.isTransactionOf(flareTransaction, 'invalidblockchainid'), false);
283
648
  });
284
649
  });
285
650
  });
286
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQTBEO0FBQzFELG1EQUEyRDtBQUMzRCwrQ0FBaUM7QUFDakMsa0RBQStDO0FBRS9DLFFBQVEsQ0FBQyxPQUFPLEVBQUU7SUFDaEIsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDO1FBQ1QsS0FBSyxHQUFHLElBQUksYUFBSyxFQUFFLENBQUM7SUFDdEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLEVBQUUsQ0FBQyxzRUFBc0UsRUFBRTtZQUN6RSxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMzQyxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFFcEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxlQUFlLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM5RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyRUFBMkUsRUFBRTtZQUM5RSxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMzQyxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUUzQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLGVBQWUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtDQUErQyxFQUFFO1lBQ2xELE1BQU0sZUFBZSxHQUFhLEVBQUUsQ0FBQztZQUNyQyxNQUFN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QyxDQUFDO1lBQ2pELE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFM0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29pbnMsIEZsYXJlTmV0d29yayB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgTm90SW1wbGVtZW50ZWRFcnJvciB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliL3V0aWxzJztcblxuZGVzY3JpYmUoJ1V0aWxzJywgZnVuY3Rpb24gKCkge1xuICBsZXQgdXRpbHM6IFV0aWxzO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHV0aWxzID0gbmV3IFV0aWxzKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpbmNsdWRlSW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGFsbCB3YWxsZXQgYWRkcmVzc2VzIGFyZSBpbiBvdXRwdXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzc2VzID0gWydhZGRyMScsICdhZGRyMiddO1xuICAgICAgY29uc3Qgb3V0cHV0QWRkcmVzc2VzID0gWydhZGRyMScsICdhZGRyMicsICdhZGRyMyddO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaW5jbHVkZUluKHdhbGxldEFkZHJlc3Nlcywgb3V0cHV0QWRkcmVzc2VzKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSB3aGVuIG5vdCBhbGwgd2FsbGV0IGFkZHJlc3NlcyBhcmUgaW4gb3V0cHV0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEFkZHJlc3NlcyA9IFsnYWRkcjEnLCAnYWRkcjInXTtcbiAgICAgIGNvbnN0IG91dHB1dEFkZHJlc3NlcyA9IFsnYWRkcjEnLCAnYWRkcjMnXTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIG91dHB1dEFkZHJlc3NlcyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGVtcHR5IHdhbGxldCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXM6IHN0cmluZ1tdID0gW107XG4gICAgICBjb25zdCBvdXRwdXRBZGRyZXNzZXMgPSBbJ2FkZHIxJywgJ2FkZHIyJ107XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCBvdXRwdXRBZGRyZXNzZXMpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIHdoZW4gd2FsbGV0IGFkZHJlc3Mgbm90IGZvdW5kIGluIGVtcHR5IG91dHB1dCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXMgPSBbJ2FkZHIxJ107XG4gICAgICBjb25zdCBvdXRwdXRBZGRyZXNzZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCBvdXRwdXRBZGRyZXNzZXMpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkQWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHNpbmdsZSB2YWxpZCBGbGFyZSBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBGbGFyZSBhZGRyZXNzZXMgc3RhcnQgd2l0aCAnZmxhcmU6JyBvciAnQy1mbGFyZTonXG4gICAgICBjb25zdCB2YWxpZEFkZHJlc3NlcyA9IFtcbiAgICAgICAgJ2ZsYXJlMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2ZjRhdmgnLFxuICAgICAgICAnQy1mbGFyZTFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxNmY0YXZoJyxcbiAgICAgIF07XG5cbiAgICAgIHZhbGlkQWRkcmVzc2VzLmZvckVhY2goKGFkZHIpID0+IHtcbiAgICAgICAgLy8gTm90ZTogVGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24gdXNlcyByZWdleCB2YWxpZGF0aW9uXG4gICAgICAgIC8vIFRoaXMgdGVzdCB3aWxsIGJlIHVwZGF0ZWQgb25jZSBwcm9wZXIgRmxhcmUgYWRkcmVzcyB2YWxpZGF0aW9uIGlzIGltcGxlbWVudGVkXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHIpO1xuICAgICAgICAvLyBDdXJyZW50bHkgcmV0dXJucyBmYWxzZSBkdWUgdG8gcGxhY2Vob2xkZXIgaW1wbGVtZW50YXRpb25cbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdib29sZWFuJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYXJyYXkgb2YgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc2VzID0gW1xuICAgICAgICAnZmxhcmUxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcTZmNGF2aCcsXG4gICAgICAgICdmbGFyZTFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYTZmNGF2aCcsXG4gICAgICBdO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzZXMpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdib29sZWFuJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFkZHJlc3NlcyBzZXBhcmF0ZWQgYnkgficsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3NTdHJpbmcgPVxuICAgICAgICAnZmxhcmUxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcTZmNGF2aH5mbGFyZTFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYTZmNGF2aCc7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3NTdHJpbmcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdib29sZWFuJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBvYnZpb3VzbHkgaW52YWxpZCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkQWRkcmVzc2VzID0gW1xuICAgICAgICAnJyxcbiAgICAgICAgJ2ludmFsaWQnLFxuICAgICAgICAnMTIzJyxcbiAgICAgICAgJ2JpdGNvaW4xcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcScsXG4gICAgICAgICdldGg6MHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwJyxcbiAgICAgIF07XG5cbiAgICAgIGludmFsaWRBZGRyZXNzZXMuZm9yRWFjaCgoYWRkcikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyKTtcbiAgICAgICAgLy8gQ3VycmVudCBpbXBsZW1lbnRhdGlvbiBtYXkgbm90IGNhdGNoIGFsbCBpbnZhbGlkIGFkZHJlc3Nlc1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIHJlc3VsdCwgJ2Jvb2xlYW4nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZEFkZHJlc3NSZWdleCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHRlc3QgYWRkcmVzcyBmb3JtYXQgd2l0aCByZWdleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRlc3RBZGRyZXNzID0gJ2ZsYXJlMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE2ZjRhdmgnO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHNbJ2lzVmFsaWRBZGRyZXNzUmVnZXgnXSh0ZXN0QWRkcmVzcyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIHJlc3VsdCwgJ2Jvb2xlYW4nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGVtcHR5IHN0cmluZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlsc1snaXNWYWxpZEFkZHJlc3NSZWdleCddKCcnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRUcmFuc2FjdGlvbklkJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdGhyb3cgTm90SW1wbGVtZW50ZWRFcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKCd0eGlkMTIzJyksXG4gICAgICAgIE5vdEltcGxlbWVudGVkRXJyb3IsXG4gICAgICAgICdpc1ZhbGlkVHJhbnNhY3Rpb25JZCBub3QgaW1wbGVtZW50ZWQnXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZFNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHRocm93IE5vdEltcGxlbWVudGVkRXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB1dGlscy5pc1ZhbGlkU2lnbmF0dXJlKCdzaWduYXR1cmUxMjMnKSxcbiAgICAgICAgTm90SW1wbGVtZW50ZWRFcnJvcixcbiAgICAgICAgJ2lzVmFsaWRTaWduYXR1cmUgbm90IGltcGxlbWVudGVkJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZVNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBzaWduYXR1cmUgdXNpbmcgc2VjcDI1NmsxJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yayA9IGNvaW5zLmdldCgnZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdoZWxsbyB3b3JsZCcsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oJzAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYnLCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgYXNzZXJ0Lm9rKHNpZ25hdHVyZSBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQub2soc2lnbmF0dXJlLmxlbmd0aCA+IDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgZGlmZmVyZW50IHNpZ25hdHVyZXMgZm9yIGRpZmZlcmVudCBtZXNzYWdlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ2ZscnAnKS5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcbiAgICAgIGNvbnN0IG1lc3NhZ2UxID0gQnVmZmVyLmZyb20oJ21lc3NhZ2UgMScsICd1dGY4Jyk7XG4gICAgICBjb25zdCBtZXNzYWdlMiA9IEJ1ZmZlci5mcm9tKCdtZXNzYWdlIDInLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKCcwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmJywgJ2hleCcpO1xuXG4gICAgICBjb25zdCBzaWcxID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UxLCBwcml2YXRlS2V5KTtcbiAgICAgIGNvbnN0IHNpZzIgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZTIsIHByaXZhdGVLZXkpO1xuXG4gICAgICBhc3NlcnQubm90RGVlcFN0cmljdEVxdWFsKHNpZzEsIHNpZzIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ2ZscnAnKS5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnaGVsbG8gd29ybGQnLCAndXRmOCcpO1xuICAgICAgY29uc3QgaW52YWxpZFByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSgnaW52YWxpZCcsICd1dGY4Jyk7XG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIGludmFsaWRQcml2YXRlS2V5KSwgL0ZhaWxlZCB0byBjcmVhdGUgc2lnbmF0dXJlLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2ZXJpZnlTaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgdmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yayA9IGNvaW5zLmdldCgnZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdoZWxsbyB3b3JsZCcsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oJzAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYnLCAnaGV4Jyk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmVcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgLy8gR2V0IHB1YmxpYyBrZXkgKHRoaXMgd291bGQgbm9ybWFsbHkgY29tZSBmcm9tIHRoZSBwcml2YXRlIGtleSlcbiAgICAgIC8vIEZvciB0ZXN0aW5nLCB3ZSdsbCB1c2UgYSBtb2NrIHB1YmxpYyBrZXkgYXBwcm9hY2hcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKCcwMicgKyAnMCcucmVwZWF0KDYyKSwgJ2hleCcpOyAvLyBDb21wcmVzc2VkIHB1YmxpYyBrZXkgZm9ybWF0XG5cbiAgICAgIC8vIE5vdGU6IFRoaXMgdGVzdCBtYXkgZmFpbCBpZiB0aGUgcHVibGljIGtleSBkb2Vzbid0IG1hdGNoIHRoZSBwcml2YXRlIGtleVxuICAgICAgLy8gSW4gYSByZWFsIGltcGxlbWVudGF0aW9uLCB5b3UnZCBkZXJpdmUgdGhlIHB1YmxpYyBrZXkgZnJvbSB0aGUgcHJpdmF0ZSBrZXlcbiAgICAgIC8vIFRoZSBtZXRob2QgcmV0dXJucyBmYWxzZSB3aGVuIHZlcmlmaWNhdGlvbiBmYWlscyBpbnN0ZWFkIG9mIHRocm93aW5nXG4gICAgICBjb25zdCBpc1ZhbGlkID0gdXRpbHMudmVyaWZ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSwgcHVibGljS2V5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgaXNWYWxpZCwgJ2Jvb2xlYW4nKTtcbiAgICAgIC8vIFdpdGggbW9jayBwdWJsaWMga2V5LCB0aGlzIHNob3VsZCByZXR1cm4gZmFsc2VcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc1ZhbGlkLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2hlbGxvIHdvcmxkJywgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmUgPSBCdWZmZXIuZnJvbSgnaW52YWxpZCBzaWduYXR1cmUnLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gQnVmZmVyLmZyb20oJzAyJyArICcwJy5yZXBlYXQoNjIpLCAnaGV4Jyk7XG5cbiAgICAgIC8vIFRoaXMgc2hvdWxkIHJldHVybiBmYWxzZSBkdWUgdG8gaW52YWxpZCBzaWduYXR1cmUgZm9ybWF0XG4gICAgICAvLyBUaGUgbWV0aG9kIGNhdGNoZXMgZXJyb3JzIGludGVybmFsbHkgYW5kIHJldHVybnMgZmFsc2VcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLnZlcmlmeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBpbnZhbGlkU2lnbmF0dXJlLCBwdWJsaWNLZXkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYWRkcmVzcyBwYXJzaW5nIHV0aWxpdGllcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBhZGRyZXNzIHNlcGFyYXRvciBjb25zdGFudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IEFERFJFU1NfU0VQQVJBVE9SIH0gPSByZXF1aXJlKCcuLi8uLi8uLi9zcmMvbGliL2lmYWNlJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoQUREUkVTU19TRVBBUkFUT1IsICd+Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBpbnB1dCBzZXBhcmF0b3IgY29uc3RhbnRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyBJTlBVVF9TRVBBUkFUT1IgfSA9IHJlcXVpcmUoJy4uLy4uLy4uL3NyYy9saWIvaWZhY2UnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChJTlBVVF9TRVBBUkFUT1IsICc6Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdlcnJvciBoYW5kbGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IGV4dGVuZCBiYXNlIHV0aWxzJywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVGVzdCB0aGF0IHV0aWxzIGNsYXNzIGV4aXN0cyBhbmQgaGFzIGV4cGVjdGVkIG1ldGhvZHNcbiAgICAgIGFzc2VydC5vaygnaXNWYWxpZEFkZHJlc3MnIGluIHV0aWxzKTtcbiAgICAgIGFzc2VydC5vaygnaW5jbHVkZUluJyBpbiB1dGlscyk7XG4gICAgICBhc3NlcnQub2soJ2NyZWF0ZVNpZ25hdHVyZScgaW4gdXRpbHMpO1xuICAgICAgYXNzZXJ0Lm9rKCd2ZXJpZnlTaWduYXR1cmUnIGluIHV0aWxzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHBhcnNpbmcgZXJyb3JzIGdyYWNlZnVsbHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUZXN0IHRoYXQgdXRpbHMgY2FuIGhhbmRsZSBtYWxmb3JtZWQgaW5wdXQgd2l0aG91dCBjcmFzaGluZ1xuICAgICAgLy8gTm90ZTogVGhlc2UgbWF5IHRocm93IGVycm9ycywgd2hpY2ggaXMgYWNjZXB0YWJsZSBiZWhhdmlvclxuICAgICAgdHJ5IHtcbiAgICAgICAgdXRpbHMuaXNWYWxpZEFkZHJlc3MobnVsbCBhcyB1bmtub3duIGFzIHN0cmluZyk7XG4gICAgICAgIHV0aWxzLmlzVmFsaWRBZGRyZXNzKHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIHN0cmluZyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBFeHBlY3RlZCBiZWhhdmlvciAtIHV0aWxzIHNob3VsZCBoYW5kbGUgb3IgdGhyb3cgbWVhbmluZ2Z1bCBlcnJvcnNcbiAgICAgICAgYXNzZXJ0Lm9rKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY29uc3RhbnRzIHZhbGlkYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgY29uc3RhbnQgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29uc3RhbnRzID0gcmVxdWlyZSgnLi4vLi4vLi4vc3JjL2xpYi9jb25zdGFudHMnKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiBjb25zdGFudHMuREVDT0RFRF9CTE9DS19JRF9MRU5HVEgsICdudW1iZXInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLlNIT1JUX1BVQl9LRVlfTEVOR1RILCAnbnVtYmVyJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIGNvbnN0YW50cy5DT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RILCAnbnVtYmVyJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIGNvbnN0YW50cy5VTkNPTVBSRVNTRURfUFVCTElDX0tFWV9MRU5HVEgsICdudW1iZXInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLlJBV19QUklWQVRFX0tFWV9MRU5HVEgsICdudW1iZXInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLlNVRkZJWEVEX1BSSVZBVEVfS0VZX0xFTkdUSCwgJ251bWJlcicpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiBjb25zdGFudHMuUFJJVkFURV9LRVlfQ09NUFJFU1NFRF9TVUZGSVgsICdzdHJpbmcnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLk9VVFBVVF9JTkRFWF9IRVhfTEVOR1RILCAnbnVtYmVyJyk7XG4gICAgICBhc3NlcnQub2soY29uc3RhbnRzLkFERFJFU1NfUkVHRVggaW5zdGFuY2VvZiBSZWdFeHApO1xuICAgICAgYXNzZXJ0Lm9rKGNvbnN0YW50cy5IRVhfUkVHRVggaW5zdGFuY2VvZiBSZWdFeHApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnTWVtbyBVdGlsaXRpZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHN0cmluZyB0byBieXRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRleHQgPSAnSGVsbG8gRmxhcmUnO1xuICAgICAgY29uc3QgYnl0ZXMgPSB1dGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXG4gICAgICBhc3NlcnQub2soYnl0ZXMgaW5zdGFuY2VvZiBVaW50OEFycmF5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5ieXRlc1RvU3RyaW5nKGJ5dGVzKSwgdGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBVVEYtOCBzdHJpbmdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGV4dCA9ICdIZWxsbyDkuJbnlYwg8J+MjSc7XG4gICAgICBjb25zdCBieXRlcyA9IHV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5ieXRlc1RvU3RyaW5nKGJ5dGVzKSwgdGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBtZW1vIGJ5dGVzIGZyb20gc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGV4dCA9ICdNZW1vIHRleHQnO1xuICAgICAgY29uc3QgYnl0ZXMgPSB1dGlscy5jcmVhdGVNZW1vQnl0ZXModGV4dCk7XG5cbiAgICAgIGFzc2VydC5vayhieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnBhcnNlTWVtb0J5dGVzKGJ5dGVzKSwgdGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBtZW1vIGJ5dGVzIGZyb20gSlNPTiBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvYmogPSB7IHR5cGU6ICdwYXltZW50JywgYW1vdW50OiAxMDAwIH07XG4gICAgICBjb25zdCBieXRlcyA9IHV0aWxzLmNyZWF0ZU1lbW9CeXRlcyhvYmopO1xuICAgICAgY29uc3QgcGFyc2VkID0gdXRpbHMucGFyc2VNZW1vQnl0ZXMoYnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLCBKU09OLnN0cmluZ2lmeShvYmopKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIFVpbnQ4QXJyYXkgaW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvcmlnaW5hbEJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDIsIDMsIDRdKTtcbiAgICAgIGNvbnN0IGJ5dGVzID0gdXRpbHMuY3JlYXRlTWVtb0J5dGVzKG9yaWdpbmFsQnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGJ5dGVzLCBvcmlnaW5hbEJ5dGVzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgbWVtbyB0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHV0aWxzLmNyZWF0ZU1lbW9CeXRlcygxMjMgYXMgYW55KTtcbiAgICAgIH0sIC9JbnZhbGlkIG1lbW8gZm9ybWF0Lyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIGVtcHR5IG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbXB0eUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoW10pO1xuICAgICAgY29uc3QgcGFyc2VkID0gdXRpbHMucGFyc2VNZW1vQnl0ZXMoZW1wdHlCeXRlcyk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQsICcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgbWVtbyBzaXplJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc21hbGxNZW1vID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDIsIDNdKTtcbiAgICAgIGNvbnN0IGxhcmdlTWVtbyA9IG5ldyBVaW50OEFycmF5KDUwMDApO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMudmFsaWRhdGVNZW1vU2l6ZShzbWFsbE1lbW8pLCB0cnVlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy52YWxpZGF0ZU1lbW9TaXplKGxhcmdlTWVtbyksIGZhbHNlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy52YWxpZGF0ZU1lbW9TaXplKGxhcmdlTWVtbywgNjAwMCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzcGVjaWFsVGV4dCA9ICdTcGVjaWFsOiBcXG5cXHRcXHJcXDAnO1xuICAgICAgY29uc3QgYnl0ZXMgPSB1dGlscy5jcmVhdGVNZW1vQnl0ZXMoc3BlY2lhbFRleHQpO1xuICAgICAgY29uc3QgcGFyc2VkID0gdXRpbHMucGFyc2VNZW1vQnl0ZXMoYnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLCBzcGVjaWFsVGV4dCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
651
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQTBEO0FBQzFELCtDQUFpQztBQUNqQyxrREFBK0M7QUFDL0MscURBT2lDO0FBQ2pDLHFEQUE0QztBQUM1Qyx5RUFBd0U7QUFDeEUseUVBQXdFO0FBQ3hFLHlFQUF3RTtBQUN4RSx5RUFBd0U7QUFDeEUsMENBQTBFO0FBQzFFLG1EQUFzRTtBQUV0RSxRQUFRLENBQUMsT0FBTyxFQUFFO0lBQ2hCLElBQUksS0FBWSxDQUFDO0lBQ2pCLE1BQU0sT0FBTyxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBdUIsQ0FBQztJQUUxRCxVQUFVLENBQUM7UUFDVCxLQUFLLEdBQUcsSUFBSSxhQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDdkIsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEtBQUs7WUFDNUMsTUFBTSxPQUFPLEdBQ1gsd1VBQXdVLENBQUM7WUFDM1UsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsRUFBRSxDQUFDLFVBQVUsWUFBWSxjQUFJLENBQUMsQ0FBQztZQUN0QyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO1lBRWpDLE1BQU0sTUFBTSxHQUFHLElBQUksYUFBRyxDQUFDLE1BQU0sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ3RDLFNBQVMsRUFBRSxDQUFDLGlEQUFpRCxDQUFDO2dCQUM5RCxXQUFXLEVBQUUsR0FBRzthQUNq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QU0sU0FBUyxHQUFHLE9BQU87aUJBQ3RCLG1CQUFtQixFQUFFO2lCQUNyQixTQUFTLENBQUMsdUJBQVcsQ0FBQyxTQUFTLENBQUM7aUJBQ2hDLFFBQVEsQ0FBQyx1QkFBVyxDQUFDLFFBQVEsQ0FBQztpQkFDOUIsVUFBVSxDQUFDLHVCQUFXLENBQUMsZUFBZSxDQUFDO2lCQUN2QyxFQUFFLENBQUMsdUJBQVcsQ0FBQyxVQUFVLENBQUM7aUJBQzFCLGVBQWUsQ0FBQyx1QkFBVyxDQUFDLGFBQWEsQ0FBQztpQkFDMUMsUUFBUSxDQUFDLHVCQUFXLENBQUMsUUFBUSxDQUFDO2lCQUM5QixPQUFPLENBQUMsdUJBQVcsQ0FBQyxPQUFPLENBQUM7aUJBQzVCLEtBQUssQ0FBQyx1QkFBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRTlCLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQWdCLENBQUM7WUFDcEQsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUVsRCxNQUFNLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLEVBQUUscUJBQXFCLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNwRyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb2lucywgRmxhcmVOZXR3b3JrIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5pbXBvcnQge1xuICBTRUVEX0FDQ09VTlQsXG4gIEFDQ09VTlRfMSxcbiAgQUNDT1VOVF8yLFxuICBBQ0NPVU5UXzMsXG4gIElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVksXG4gIElOVkFMSURfTE9OR19LRVlQQUlSX1BSVixcbn0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2FjY291bnQnO1xuaW1wb3J0IHsgZWNjIH0gZnJvbSAnQGJpdGdvLWJldGEvc2VjcDI1NmsxJztcbmltcG9ydCB7IEVYUE9SVF9JTl9DIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9leHBvcnRJbkMnO1xuaW1wb3J0IHsgSU1QT1JUX0lOX1AgfSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvdHJhbnNhY3Rpb25EYXRhL2ltcG9ydEluUCc7XG5pbXBvcnQgeyBFWFBPUlRfSU5fUCB9IGZyb20gJy4uLy4uL3Jlc291cmNlcy90cmFuc2FjdGlvbkRhdGEvZXhwb3J0SW5QJztcbmltcG9ydCB7IElNUE9SVF9JTl9DIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9pbXBvcnRJbkMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSwgVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IHNlY3AyNTZrMSwgQWRkcmVzcywgVXR4bywgcHZtIH0gZnJvbSAnQGZsYXJlbmV0d29yay9mbGFyZWpzJztcblxuZGVzY3JpYmUoJ1V0aWxzJywgZnVuY3Rpb24gKCkge1xuICBsZXQgdXRpbHM6IFV0aWxzO1xuICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgdXRpbHMgPSBuZXcgVXRpbHMoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3BhcnNlVXR4b0hleCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHBhcnNlIHZhbGlkIFVUWE8gaGV4IHN0cmluZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHV0eG9IZXggPVxuICAgICAgICAnMHgwMDAwNGU3ODM0MWQ2NmMxYTA4ODY1ODE2NzA1MGU5MTIxOTI1YmM5N2RiNjdkMWFjZmM1NzM1ZTEyZDRiNThhZDJkNjAwMDAwMDAwNTg3MzRmOTRhZjg3MWMzZDEzMWI1NjEzMWI2ZmI3YTAyOTFlYWNhZGQyNjFlNjlkZmI0MmE5Y2RmNmY3ZmRkZDAwMDAwMDA3MDAwMDAwMDAxMWUxYTMwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAzMDIwZGY2MjUwYjA0YmJkYmU4Yjk1MmE0NmI3ZDUyN2FlZWViODhlZTMwYWUyOTFmMTkyYzc0N2I2MDEwYjkxZjVhZTFkMDlkOWMyMDk5N2E1N2ZmNWRhNTk4ODFhYzNlMzY4N2RhNzIzZWQ4ZjEyYzU5MDE5NmZhNjZhYjRiY2EnO1xuICAgICAgY29uc3QgcGFyc2VkVXR4byA9IHV0aWxzLnBhcnNlVXR4b0hleCh1dHhvSGV4KTtcbiAgICAgIGFzc2VydC5vayhwYXJzZWRVdHhvIGluc3RhbmNlb2YgVXR4byk7XG4gICAgICBjb25zdCB1dHhvSWQgPSBwYXJzZWRVdHhvLnV0eG9JZDtcblxuICAgICAgY29uc3QgcHZtYXBpID0gbmV3IHB2bS5QVk1BcGkoJ2h0dHBzOi8vY29zdG9uMi1hcGkuZmxhcmUubmV0d29yaycpO1xuICAgICAgY29uc3QgeyB1dHhvcyB9ID0gYXdhaXQgcHZtYXBpLmdldFVUWE9zKHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJ1AtY29zdHdvMTJsbDRtZnZjc3hrcnVkNThtZmVyYWs4MzkzdnNyOWg2bGtoMzZmJ10sXG4gICAgICAgIHNvdXJjZUNoYWluOiAnUCcsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHV0eG8gPSB1dHhvc1swXTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dHhvLnV0eG9JZC50eElELnRvU3RyaW5nKCksIHV0eG9JZC50eElELnRvU3RyaW5nKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSB2YWxpZCBVVFhPIGhleCBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1dHhvSGV4ID1cbiAgICAgICAgJzB4MDAwMDRlNzgzNDFkNjZjMWEwODg2NTgxNjcwNTBlOTEyMTkyNWJjOTdkYjY3ZDFhY2ZjNTczNWUxMmQ0YjU4YWQyZDYwMDAwMDAwMDU4NzM0Zjk0YWY4NzFjM2QxMzFiNTYxMzFiNmZiN2EwMjkxZWFjYWRkMjYxZTY5ZGZiNDJhOWNkZjZmN2ZkZGQwMDAwMDAwNzAwMDAwMDAwMTFlMWEzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDIwMDAwMDAwMzAyMGRmNjI1MGIwNGJiZGJlOGI5NTJhNDZiN2Q1MjdhZWVlYjg4ZWUzMGFlMjkxZjE5MmM3NDdiNjAxMGI5MWY1YWUxZDA5ZDljMjA5OTdhNTdmZjVkYTU5ODgxYWMzZTM2ODdkYTcyM2VkOGYxMmM1OTAxOTZmYTY2YWI0YmNhJztcbiAgICAgIGNvbnN0IHBhcnNlZFV0eG8gPSB1dGlscy5wYXJzZVV0eG9IZXgodXR4b0hleCk7XG5cbiAgICAgIGFzc2VydC5vayhwYXJzZWRVdHhvIGluc3RhbmNlb2YgVXR4byk7XG4gICAgICBhc3NlcnQub2socGFyc2VkVXR4by51dHhvSWQsICd1dHhvSWQgc2hvdWxkIGV4aXN0Jyk7XG4gICAgICBhc3NlcnQub2socGFyc2VkVXR4by5hc3NldElkLCAnYXNzZXRJZCBzaG91bGQgZXhpc3QnKTtcbiAgICAgIGFzc2VydC5vayhwYXJzZWRVdHhvLm91dHB1dCwgJ291dHB1dCBzaG91bGQgZXhpc3QnKTtcblxuICAgICAgY29uc3QgdHhJZEhleCA9IEJ1ZmZlci5mcm9tKHBhcnNlZFV0eG8udXR4b0lkLnR4SUQudG9CeXRlcygpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHhJZEhleCwgJzRlNzgzNDFkNjZjMWEwODg2NTgxNjcwNTBlOTEyMTkyNWJjOTdkYjY3ZDFhY2ZjNTczNWUxMmQ0YjU4YWQyZDYnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYXJyYXkgb2YgVVRYTyBoZXggc3RyaW5ncycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHV0eG9IZXhBcnJheSA9IFtcbiAgICAgICAgJzB4MDAwMDRlNzgzNDFkNjZjMWEwODg2NTgxNjcwNTBlOTEyMTkyNWJjOTdkYjY3ZDFhY2ZjNTczNWUxMmQ0YjU4YWQyZDYwMDAwMDAwMDU4NzM0Zjk0YWY4NzFjM2QxMzFiNTYxMzFiNmZiN2EwMjkxZWFjYWRkMjYxZTY5ZGZiNDJhOWNkZjZmN2ZkZGQwMDAwMDAwNzAwMDAwMDAwMTFlMWEzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDIwMDAwMDAwMzAyMGRmNjI1MGIwNGJiZGJlOGI5NTJhNDZiN2Q1MjdhZWVlYjg4ZWUzMGFlMjkxZjE5MmM3NDdiNjAxMGI5MWY1YWUxZDA5ZDljMjA5OTdhNTdmZjVkYTU5ODgxYWMzZTM2ODdkYTcyM2VkOGYxMmM1OTAxOTZmYTY2YWI0YmNhJyxcbiAgICAgIF07XG4gICAgICBjb25zdCBwYXJzZWRVdHhvcyA9IHV0aWxzLnBhcnNlVXR4b0hleEFycmF5KHV0eG9IZXhBcnJheSk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWRVdHhvcy5sZW5ndGgsIDEpO1xuICAgICAgYXNzZXJ0Lm9rKHBhcnNlZFV0eG9zWzBdIGluc3RhbmNlb2YgVXR4byk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpbmNsdWRlSW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIGFsbCB3YWxsZXQgYWRkcmVzc2VzIGFyZSBpbiBVVFhPIG91dHB1dCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXMgPSBbRVhQT1JUX0lOX0MucEFkZHJlc3Nlc1swXSwgRVhQT1JUX0lOX0MucEFkZHJlc3Nlc1sxXV07XG4gICAgICBjb25zdCB1dHhvT3V0cHV0QWRkcmVzc2VzID0gWy4uLkVYUE9SVF9JTl9DLnBBZGRyZXNzZXNdO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIHV0eG9PdXRwdXRBZGRyZXNzZXMpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIHdoZW4gc29tZSB3YWxsZXQgYWRkcmVzc2VzIGFyZSBub3QgaW4gVVRYTyBvdXRwdXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzc2VzID0gW0VYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMF0sIEFDQ09VTlRfMy5hZGRyZXNzXTtcbiAgICAgIGNvbnN0IHV0eG9PdXRwdXRBZGRyZXNzZXMgPSBbRVhQT1JUX0lOX0MucEFkZHJlc3Nlc1swXSwgRVhQT1JUX0lOX0MucEFkZHJlc3Nlc1sxXV07XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaW5jbHVkZUluKHdhbGxldEFkZHJlc3NlcywgdXR4b091dHB1dEFkZHJlc3NlcyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGVtcHR5IHdhbGxldCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXM6IHN0cmluZ1tdID0gW107XG4gICAgICBjb25zdCB1dHhvT3V0cHV0QWRkcmVzc2VzID0gW0VYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMF1dO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIHV0eG9PdXRwdXRBZGRyZXNzZXMpLCB0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIG1haW5uZXQgUC1jaGFpbiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKFNFRURfQUNDT1VOVC5hZGRyZXNzTWFpbm5ldCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgdGVzdG5ldCBQLWNoYWluIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBOb2RlSUQgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcygnTm9kZUlELWFiYzEyM3h5eicpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGFycmF5IG9mIHZhbGlkIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhFWFBPUlRfSU5fQy5wQWRkcmVzc2VzKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB0aWxkZS1zZXBhcmF0ZWQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tYmluZWQgPSBFWFBPUlRfSU5fQy5wQWRkcmVzc2VzLmpvaW4oJ34nKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhjb21iaW5lZCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGludmFsaWQgYWRkcmVzcyBmb3JtYXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoJ2ludmFsaWQnKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGFkZHJlc3Mgd2l0aG91dCBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoJ2ZsYXJlMWFiYzEyMycpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkQmxvY2tJZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCAzMi1ieXRlIGhleCBibG9jayBJRCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZChTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSksIHRydWUpOyAvLyA2NCBoZXggY2hhcnMgPSAzMiBieXRlc1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGludmFsaWQgbGVuZ3RoIGJsb2NrIElEJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVkpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgZW1wdHkgYmxvY2sgSUQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoJycpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkUHVibGljS2V5JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIGNvbXByZXNzZWQgcHVibGljIGtleSBzdGFydGluZyB3aXRoIDAzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoU0VFRF9BQ0NPVU5ULnB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgY29tcHJlc3NlZCBwdWJsaWMga2V5IHN0YXJ0aW5nIHdpdGggMDInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShBQ0NPVU5UXzEucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBhbm90aGVyIHZhbGlkIGNvbXByZXNzZWQgcHVibGljIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KEFDQ09VTlRfMi5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHhwdWInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShTRUVEX0FDQ09VTlQueFB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgQUNDT1VOVF8xIHhwdWInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShBQ0NPVU5UXzEueFB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGludmFsaWQgc2hvcnQgcHVibGljIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVkpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgY29tcHJlc3NlZCBrZXkgd2l0aCB3cm9uZyBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkS2V5ID0gJzA1JyArIFNFRURfQUNDT1VOVC5wcml2YXRlS2V5O1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoaW52YWxpZEtleSksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBub24taGV4IHB1YmxpYyBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkS2V5ID0gJ3p6JyArIFNFRURfQUNDT1VOVC5wcml2YXRlS2V5O1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoaW52YWxpZEtleSksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRQcml2YXRlS2V5JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIDY0LWNoYXIgaGV4IHByaXZhdGUga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KFNFRURfQUNDT1VOVC5wcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBBQ0NPVU5UXzEgcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQUNDT1VOVF8xLnByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIEFDQ09VTlRfMiBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShBQ0NPVU5UXzIucHJpdmF0ZUtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgeHBydicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShTRUVEX0FDQ09VTlQueFByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIDY2LWNoYXIgcHJpdmF0ZSBrZXkgZW5kaW5nIHdpdGggMDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHRlbmRlZEtleSA9IFNFRURfQUNDT1VOVC5wcml2YXRlS2V5ICsgJzAxJztcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShleHRlbmRlZEtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIDY2LWNoYXIgcHJpdmF0ZSBrZXkgbm90IGVuZGluZyB3aXRoIDAxJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KElOVkFMSURfTE9OR19LRVlQQUlSX1BSViksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHNob3J0IHByaXZhdGUga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVkpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3Igbm9uLWhleCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRLZXkgPSAnenonICsgU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkuc2xpY2UoMik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoaW52YWxpZEtleSksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2FsbEhleENoYXJzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHByaXZhdGUga2V5IGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycyhTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgcHVibGljIGtleSBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoU0VFRF9BQ0NPVU5ULnB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgaGV4IHN0cmluZyB3aXRoIDB4IHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycyhFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgc2lnbmF0dXJlIGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycyhTRUVEX0FDQ09VTlQuc2lnbmF0dXJlKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3Igbm9uLWhleCBjaGFyYWN0ZXJzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKCdnaGlqa2wnKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGVtcHR5IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycygnJyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZVNpZ25hdHVyZSBhbmQgdmVyaWZ5U2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgdmFsaWQgNjUtYnl0ZSBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuXG4gICAgICBhc3NlcnQub2soc2lnbmF0dXJlIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduYXR1cmUubGVuZ3RoLCA2NSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ2hleCcpO1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnB1YmxpY0tleSwgJ2hleCcpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCBzaWdPbmx5ID0gc2lnbmF0dXJlLnNsaWNlKDAsIDY0KTtcblxuICAgICAgY29uc3QgbWVzc2FnZUhhc2ggPSB1dGlscy5zaGEyNTYobWVzc2FnZSk7XG4gICAgICBjb25zdCBpc1ZhbGlkID0gdXRpbHMudmVyaWZ5U2lnbmF0dXJlKG1lc3NhZ2VIYXNoLCBzaWdPbmx5LCBwdWJsaWNLZXkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGlzVmFsaWQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGludmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnB1YmxpY0tleSwgJ2hleCcpO1xuICAgICAgY29uc3QgaW52YWxpZFNpZ25hdHVyZSA9IEJ1ZmZlci5hbGxvYyg2NCk7XG5cbiAgICAgIGNvbnN0IG1lc3NhZ2VIYXNoID0gdXRpbHMuc2hhMjU2KG1lc3NhZ2UpO1xuICAgICAgY29uc3QgaXNWYWxpZCA9IHV0aWxzLnZlcmlmeVNpZ25hdHVyZShtZXNzYWdlSGFzaCwgaW52YWxpZFNpZ25hdHVyZSwgcHVibGljS2V5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc1ZhbGlkLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBzaWduYXR1cmUgd2l0aCBBQ0NPVU5UXzEga2V5cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbShBQ0NPVU5UXzEucHJpdmF0ZUtleSwgJ2hleCcpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG5cbiAgICAgIGFzc2VydC5vayhzaWduYXR1cmUgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNpZ25hdHVyZS5sZW5ndGgsIDY1KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZU5ld1NpZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIHNpZ25hdHVyZSBmcm9tIHZhbGlkIHNpZ25hdHVyZSBoZXggc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlTmV3U2lnKFNFRURfQUNDT1VOVC5zaWduYXR1cmUpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIHNpZ25hdHVyZSBmcm9tIGV4cG9ydCBzaWduYXR1cmUgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnSGV4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLnNpZ25hdHVyZVswXSk7XG4gICAgICBjb25zdCBzaWcgPSB1dGlscy5jcmVhdGVOZXdTaWcoc2lnSGV4KTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYWQgc2hvcnQgaGV4IHN0cmluZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWdIZXggPSBJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlTmV3U2lnKHNpZ0hleCk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZUVtcHR5U2lnV2l0aEFkZHJlc3MgYW5kIGdldEFkZHJlc3NGcm9tRW1wdHlTaWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgZW1wdHkgc2lnbmF0dXJlIHdpdGggZW1iZWRkZWQgQy1jaGFpbiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc0hleCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyk7XG4gICAgICBjb25zdCBzaWcgPSB1dGlscy5jcmVhdGVFbXB0eVNpZ1dpdGhBZGRyZXNzKGFkZHJlc3NIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4dHJhY3QgZW1iZWRkZWQgYWRkcmVzcyBmcm9tIGVtcHR5IHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3NIZXggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25zdCBzaWcgPSB1dGlscy5jcmVhdGVFbXB0eVNpZ1dpdGhBZGRyZXNzKGFkZHJlc3NIZXgpO1xuXG4gICAgICAvLyBHZXQgc2lnbmF0dXJlIGJ5dGVzIGFuZCBjb252ZXJ0IHRvIGhleFxuICAgICAgY29uc3Qgc2lnQnl0ZXMgPSBzaWcudG9CeXRlcygpO1xuICAgICAgY29uc3Qgc2lnSGV4ID0gQnVmZmVyLmZyb20oc2lnQnl0ZXMpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgY29uc3QgZXh0cmFjdGVkQWRkcmVzcyA9IHV0aWxzLmdldEFkZHJlc3NGcm9tRW1wdHlTaWcoc2lnSGV4KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChleHRyYWN0ZWRBZGRyZXNzLCBhZGRyZXNzSGV4KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIDB4IHByZWZpeGVkIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWcgPSB1dGlscy5jcmVhdGVFbXB0eVNpZ1dpdGhBZGRyZXNzKEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZW1wdHkgc3RyaW5nIGZvciBzaG9ydCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaG9ydFNpZyA9IFNFRURfQUNDT1VOVC5wcml2YXRlS2V5OyAvLyA2NCBjaGFycywgbGVzcyB0aGFuIDEzMFxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmdldEFkZHJlc3NGcm9tRW1wdHlTaWcoc2hvcnRTaWcpLCAnJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaGEyNTYnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjb21wdXRlIFNIQTI1NiBoYXNoIG9mIG1lc3NhZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBoYXNoID0gdXRpbHMuc2hhMjU2KGRhdGEpO1xuXG4gICAgICBhc3NlcnQub2soaGFzaCBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaGFzaC5sZW5ndGgsIDMyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBjb25zaXN0ZW50IGhhc2ggZm9yIHNhbWUgaW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBoYXNoMSA9IHV0aWxzLnNoYTI1NihkYXRhKTtcbiAgICAgIGNvbnN0IGhhc2gyID0gdXRpbHMuc2hhMjU2KGRhdGEpO1xuXG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGhhc2gxLCBoYXNoMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgZGlmZmVyZW50IGhhc2ggZm9yIGRpZmZlcmVudCBpbnB1dCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGExID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBkYXRhMiA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAndXRmOCcpO1xuICAgICAgY29uc3QgaGFzaDEgPSB1dGlscy5zaGEyNTYoZGF0YTEpO1xuICAgICAgY29uc3QgaGFzaDIgPSB1dGlscy5zaGEyNTYoZGF0YTIpO1xuXG4gICAgICBhc3NlcnQubm90RGVlcFN0cmljdEVxdWFsKGhhc2gxLCBoYXNoMik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2YWxpZGF0ZVJhd1RyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbm90IHRocm93IGZvciB2YWxpZCB1bnNpZ25lZCBoZXggdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy51bnNpZ25lZEhleCk7XG4gICAgICBhc3NlcnQuZG9lc05vdFRocm93KCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHRocm93IGZvciB2YWxpZCBzaWduZWQgaGV4IHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0Muc2lnbmVkSGV4KTtcbiAgICAgIGFzc2VydC5kb2VzTm90VGhyb3coKCkgPT4gdXRpbHMudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihyYXdUeCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgZm9yIGltcG9ydCB0cmFuc2FjdGlvbiBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChJTVBPUlRfSU5fUC51bnNpZ25lZEhleCk7XG4gICAgICBhc3NlcnQuZG9lc05vdFRocm93KCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIGVtcHR5IHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKCcnKSwgL1JhdyB0cmFuc2FjdGlvbiBpcyBlbXB0eS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3Igbm9uLWhleCB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMudmFsaWRhdGVSYXdUcmFuc2FjdGlvbigneHl6MTIzJyksIC9SYXcgdHJhbnNhY3Rpb24gaXMgbm90IGhleCBzdHJpbmcvKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlbW92ZUhleFByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJlbW92ZSAweCBwcmVmaXggZnJvbSBDLWNoYWluIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKSwgRVhQT1JUX0lOX0MuY0hleEFkZHJlc3Muc2xpY2UoMikpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZW1vdmUgMHggcHJlZml4IGZyb20gdW5zaWduZWQgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy51bnNpZ25lZEhleCksIEVYUE9SVF9JTl9DLnVuc2lnbmVkSGV4LnNsaWNlKDIpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHN0cmluZyB1bmNoYW5nZWQgaWYgbm8gcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnJlbW92ZUhleFByZWZpeChTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSksIFNFRURfQUNDT1VOVC5wcml2YXRlS2V5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIGVtcHR5IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5yZW1vdmVIZXhQcmVmaXgoJycpLCAnJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdvdXRwdXRpZHhOdW1iZXJUb0J1ZmZlciBhbmQgb3V0cHV0aWR4QnVmZmVyVG9OdW1iZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgbm9uY2UgdmFsdWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBub25jZVN0ciA9IEVYUE9SVF9JTl9DLm5vbmNlLnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5vdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcihub25jZVN0cik7XG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5vdXRwdXRpZHhCdWZmZXJUb051bWJlcihidWZmZXIpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCBub25jZVN0cik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgNC1ieXRlIGJ1ZmZlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLm91dHB1dGlkeE51bWJlclRvQnVmZmVyKCcyNTUnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCA0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2FkZHJlc3NUb1N0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgYWRkcmVzcyBidWZmZXIgdG8gbWFpbm5ldCBiZWNoMzIgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IFNFRURfQUNDT1VOVC5hZGRyZXNzTWFpbm5ldDtcbiAgICAgIGNvbnN0IGFkZHJlc3NCdWZmZXIgPSB1dGlscy5wYXJzZUFkZHJlc3MoYWRkcmVzcyk7XG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5hZGRyZXNzVG9TdHJpbmcoJ2ZsYXJlJywgJ1AnLCBhZGRyZXNzQnVmZmVyKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5zdGFydHNXaXRoKCdQLScpKTtcbiAgICAgIGFzc2VydC5vayhyZXN1bHQuaW5jbHVkZXMoJ2ZsYXJlJykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IGFkZHJlc3MgYnVmZmVyIHRvIHRlc3RuZXQgYmVjaDMyIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQ7XG4gICAgICBjb25zdCBhZGRyZXNzQnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKGFkZHJlc3MpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuYWRkcmVzc1RvU3RyaW5nKCdjb3N0d28nLCAnUCcsIGFkZHJlc3NCdWZmZXIpO1xuXG4gICAgICBhc3NlcnQub2socmVzdWx0LnN0YXJ0c1dpdGgoJ1AtJykpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5pbmNsdWRlcygnY29zdHdvJykpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY2I1OEVuY29kZSBhbmQgY2I1OERlY29kZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGVuY29kZSBhbmQgZGVjb2RlIHRhcmdldCBjaGFpbiBJRCBjb3JyZWN0bHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbmNvZGVkID0gRVhQT1JUX0lOX0MudGFyZ2V0Q2hhaW5JZDtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSB1dGlscy5jYjU4RGVjb2RlKGVuY29kZWQpO1xuICAgICAgY29uc3QgcmVFbmNvZGVkID0gdXRpbHMuY2I1OEVuY29kZShkZWNvZGVkKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlRW5jb2RlZCwgZW5jb2RlZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVuY29kZSBhbmQgZGVjb2RlIHNvdXJjZSBjaGFpbiBJRCBjb3JyZWN0bHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbmNvZGVkID0gSU1QT1JUX0lOX1Auc291cmNlQ2hhaW5JZDtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSB1dGlscy5jYjU4RGVjb2RlKGVuY29kZWQpO1xuICAgICAgY29uc3QgcmVFbmNvZGVkID0gdXRpbHMuY2I1OEVuY29kZShkZWNvZGVkKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlRW5jb2RlZCwgZW5jb2RlZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIGNoZWNrc3VtJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5jYjU4RGVjb2RlKCcxMTExMTExMTExMTExJyksIC9JbnZhbGlkIGNoZWNrc3VtLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdwYXJzZUFkZHJlc3MgYW5kIHN0cmluZ1RvQWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHBhcnNlIGhleCBhZGRyZXNzIHdpdGggMHggcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKTtcblxuICAgICAgYXNzZXJ0Lm9rKGJ1ZmZlciBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnVmZmVyLmxlbmd0aCwgMjApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBtYWlubmV0IGJlY2gzMiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKFNFRURfQUNDT1VOVC5hZGRyZXNzTWFpbm5ldCk7XG5cbiAgICAgIGFzc2VydC5vayhidWZmZXIgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgdGVzdG5ldCBiZWNoMzIgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQpO1xuXG4gICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCAyMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIFAtY2hhaW4gYWRkcmVzc2VzIGZyb20gZXhwb3J0IGRhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBFWFBPUlRfSU5fQy5wQWRkcmVzc2VzLmZvckVhY2goKGFkZHJlc3MpID0+IHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKGFkZHJlc3MpO1xuICAgICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgYWRkcmVzcyB3aXRob3V0IGRhc2ggc2VwYXJhdG9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5wYXJzZUFkZHJlc3MoJ2ZsYXJlMWFiYycpLCAvVmFsaWQgYWRkcmVzcyBzaG91bGQgaW5jbHVkZSAtLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIEhSUCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucGFyc2VBZGRyZXNzKCdQLWludmFsaWQxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE1ZXZ6bXknKSwgL0ludmFsaWQgSFJQLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdmbGFyZUlkU3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIElkIGZyb20gcHJpdmF0ZSBrZXkgaGV4IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGlkID0gdXRpbHMuZmxhcmVJZFN0cmluZyhTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSk7XG4gICAgICBhc3NlcnQub2soaWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgSWQgZnJvbSBhc3NldCBJRCBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBBc3NldCBJRCBpcyB0eXBpY2FsbHkgMzIgYnl0ZXMgKDY0IGhleCBjaGFycylcbiAgICAgIGNvbnN0IGFzc2V0SWRIZXggPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTsgLy8gVXNpbmcgYXMgYSAzMi1ieXRlIGhleFxuICAgICAgY29uc3QgaWQgPSB1dGlscy5mbGFyZUlkU3RyaW5nKGFzc2V0SWRIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKGlkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlY292ZXJ5U2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IGZyb20gdmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmUgdXNpbmcgdGhlIHNhbWUgcHJpdmF0ZSBrZXkgKGNyZWF0ZVNpZ25hdHVyZSBoYXNoZXMgdGhlIG1lc3NhZ2UgaW50ZXJuYWxseSlcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgLy8gUmVjb3ZlciBwdWJsaWMga2V5IC0gcGFzcyB0aGUgaGFzaGVkIG1lc3NhZ2Ugc2luY2UgcmVjb3ZlcnlTaWduYXR1cmUgZXhwZWN0cyBwcmUtaGFzaGVkXG4gICAgICBjb25zdCBtZXNzYWdlSGFzaCA9IHV0aWxzLnNoYTI1NihtZXNzYWdlKTtcbiAgICAgIGNvbnN0IHJlY292ZXJlZFB1YktleSA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG1lc3NhZ2VIYXNoLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQub2socmVjb3ZlcmVkUHViS2V5IGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkubGVuZ3RoLCAzMyk7IC8vIFNob3VsZCBiZSBjb21wcmVzc2VkIHB1YmxpYyBrZXkgKDMzIGJ5dGVzKVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNhbWUgcHVibGljIGtleSBmb3Igc2FtZSBtZXNzYWdlIGFuZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgY29uc3QgbWVzc2FnZUhhc2ggPSB1dGlscy5zaGEyNTYobWVzc2FnZSk7XG4gICAgICBjb25zdCBwdWJLZXkxID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobWVzc2FnZUhhc2gsIHNpZ25hdHVyZSk7XG4gICAgICBjb25zdCBwdWJLZXkyID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobWVzc2FnZUhhc2gsIHNpZ25hdHVyZSk7XG5cbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocHViS2V5MSwgcHViS2V5Mik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgcHVibGljIGtleSB0aGF0IG1hdGNoZXMgb3JpZ2luYWwga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIC8vIEdldCBvcmlnaW5hbCBwdWJsaWMga2V5XG4gICAgICBjb25zdCBvcmlnaW5hbFB1YktleSA9IEJ1ZmZlci5mcm9tKGVjYy5wb2ludEZyb21TY2FsYXIocHJpdmF0ZUtleSwgdHJ1ZSkgYXMgVWludDhBcnJheSk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmUgYW5kIHJlY292ZXIgcHVibGljIGtleVxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3QgbWVzc2FnZUhhc2ggPSB1dGlscy5zaGEyNTYobWVzc2FnZSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShtZXNzYWdlSGFzaCwgc2lnbmF0dXJlKTtcblxuICAgICAgLy8gQ29udmVydCBib3RoIHRvIGhleCBzdHJpbmdzIGZvciBjb21wYXJpc29uXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVjb3ZlcmVkUHViS2V5LnRvU3RyaW5nKCdoZXgnKSwgb3JpZ2luYWxQdWJLZXkudG9TdHJpbmcoJ2hleCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IHVzaW5nIEFDQ09VTlRfMSBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKEFDQ09VTlRfMS5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IG9yaWdpbmFsUHViS2V5ID0gQnVmZmVyLmZyb20oZWNjLnBvaW50RnJvbVNjYWxhcihwcml2YXRlS2V5LCB0cnVlKSBhcyBVaW50OEFycmF5KTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3QgbWVzc2FnZUhhc2ggPSB1dGlscy5zaGEyNTYobWVzc2FnZSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShtZXNzYWdlSGFzaCwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlY292ZXJlZFB1YktleS50b1N0cmluZygnaGV4JyksIG9yaWdpbmFsUHViS2V5LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIHNpZ25hdHVyZSBsZW5ndGgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlSGFzaCA9IHV0aWxzLnNoYTI1NihCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKSk7XG4gICAgICBjb25zdCBpbnZhbGlkU2lnbmF0dXJlID0gQnVmZmVyLmZyb20oSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWSwgJ2hleCcpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG1lc3NhZ2VIYXNoLCBpbnZhbGlkU2lnbmF0dXJlKSwgL0ZhaWxlZCB0byByZWNvdmVyIHNpZ25hdHVyZS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3Igc2lnbmF0dXJlIHdpdGggaW52YWxpZCByZWNvdmVyeSBwYXJhbWV0ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlSGFzaCA9IHV0aWxzLnNoYTI1NihCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKSk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBCdWZmZXIuYWxsb2MoNjUpOyAvLyBWYWxpZCBsZW5ndGggYnV0IGFsbCB6ZXJvcyAtIGludmFsaWQgc2lnbmF0dXJlXG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobWVzc2FnZUhhc2gsIHNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzaWduYXR1cmUgYW5kIHZlcmlmeSBzZW5kZXIgYWRkcmVzcyBmcm9tIHNpZ25lZCBDLWNoYWluIEV4cG9ydCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFRyYW5zYWN0aW9uIGZyb20gYWN0dWFsIGJ1aWxkIHJlc3BvbnNlIC0gQy1jaGFpbiBFeHBvcnQgdHhcbiAgICAgIGNvbnN0IHR4ID1cbiAgICAgICAgJzB4MDAwMDAwMDAwMDAxMDAwMDAwNzI3OGRiNWMzMGJlZDA0YzA1Y2UyMDkxNzk4MTI4NTBiYmIzZmU2ZDQ2ZDdlZWYzNzQ0ZDgxNGMwZGE1NTUyNDc5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMmE5NjAyNWFkNTA2YjlmYmI5MDIzZmJkYzE2NjVjN2Y3ZDdjOTIzZjAwMDAwMDAwMDYwNTIzNjY1ODczNGY5NGFmODcxYzNkMTMxYjU2MTMxYjZmYjdhMDI5MWVhY2FkZDI2MWU2OWRmYjQyYTljZGY2ZjdmZGRkMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxNTg3MzRmOTRhZjg3MWMzZDEzMWI1NjEzMWI2ZmI3YTAyOTFlYWNhZGQyNjFlNjlkZmI0MmE5Y2RmNmY3ZmRkZDAwMDAwMDA3MDAwMDAwMDAwNjA1MjM0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAzN2ZhOGM3ZTBjOGFkOWYwOWY5MTc5YjQyYjc3ZTk0YTQ4N2MzZGY3NThkNGJhNTM4Zjc3MjMzM2NhN2JmMzY2OGEyZmUzNjY0ODQzOGM3OWQ5YjZiNzdiNTZlZmZiODYwZWFhNDMwZTBlMzBjNGUzOTJmNTljZDA4MDAwMDAwMDEwMDAwMDAwOTAwMDAwMDAxNzUwMDc2ZTY3ZDk3MjAyODNhNzFjNmU3YTlhODhmZjY2MjYwOGZlZmRkM2YzMTZmMTIxMTk1N2NhMTg3M2VlZTNlZTRhNzRiNDY4YmRhNjYxNzZhM2U1ZDNhYjU0ZDQzYThjMGJlMTIzNDhmMjUxYTMwOTNjMTZkOWRiMDBjZDAwMWMzMWU5YzE1JztcbiAgICAgIGNvbnN0IGV4cGVjdGVkU2VuZGVyQWRkcmVzcyA9ICcweDJhOTYwMjVhZDUwNmI5ZmJiOTAyM2ZiZGMxNjY1YzdmN2Q3YzkyM2YnO1xuXG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCd0ZmxycCcpKTtcbiAgICAgIGNvbnN0IHR4biA9IChhd2FpdCBmYWN0b3J5LmZyb20odHgpLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3Qgc2lnbmFibGVQYXlsb2FkID0gdHhuLnNpZ25hYmxlUGF5bG9hZDtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZXMgPSB0eG4uc2lnbmF0dXJlO1xuICAgICAgY29uc3Qgc2lnID0gQnVmZmVyLmZyb20odXRpbHMucmVtb3ZlSGV4UHJlZml4KHNpZ25hdHVyZXNbMF0pLCAnaGV4Jyk7XG5cbiAgICAgIC8vIFJlY292ZXIgcHVibGljIGtleSBmcm9tIHNpZ25hdHVyZSAoc2lnbmFibGVQYXlsb2FkIGlzIGFscmVhZHkgU0hBMjU2IGhhc2hlZClcbiAgICAgIGNvbnN0IHJlY292ZXJlZFB1YktleSA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKHNpZ25hYmxlUGF5bG9hZCwgc2lnKTtcblxuICAgICAgLy8gR2V0IHRoZSBzZW5kZXIgYWRkcmVzcyBmcm9tIHRoZSB0cmFuc2FjdGlvbiBpbnB1dHNcbiAgICAgIGNvbnN0IHR4SW5wdXRzID0gdHhuLmlucHV0cztcbiAgICAgIGNvbnN0IHNlbmRlckFkZHJlc3NGcm9tVHggPSB0eElucHV0c1swXS5hZGRyZXNzLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIC8vIFZlcmlmeSBzZW5kZXIgYWRkcmVzcyBtYXRjaGVzIGV4cGVjdGVkXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIHNlbmRlckFkZHJlc3NGcm9tVHgsXG4gICAgICAgIGV4cGVjdGVkU2VuZGVyQWRkcmVzcy50b0xvd2VyQ2FzZSgpLFxuICAgICAgICAnVHJhbnNhY3Rpb24gc2VuZGVyIGFkZHJlc3MgZG9lcyBub3QgbWF0Y2ggZXhwZWN0ZWQnXG4gICAgICApO1xuXG4gICAgICAvLyBEZXJpdmUgYWRkcmVzcyBmcm9tIHJlY292ZXJlZCBwdWJsaWMga2V5XG4gICAgICBjb25zdCBkZXJpdmVkRXZtQWRkcmVzcyA9XG4gICAgICAgICcweCcgKyBCdWZmZXIuZnJvbShuZXcgQWRkcmVzcyhzZWNwMjU2azEucHVibGljS2V5VG9FdGhBZGRyZXNzKHJlY292ZXJlZFB1YktleSkpLnRvQnl0ZXMoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIHJlY292ZXJlZCBwdWJsaWMga2V5IG1hdGNoZXMgdGhlIHNlbmRlclxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICBkZXJpdmVkRXZtQWRkcmVzcy50b0xvd2VyQ2FzZSgpLFxuICAgICAgICBzZW5kZXJBZGRyZXNzRnJvbVR4LFxuICAgICAgICAnUmVjb3ZlcmVkIHB1YmxpYyBrZXkgZG9lcyBub3QgbWF0Y2ggc2VuZGVyIGFkZHJlc3MnXG4gICAgICApO1xuXG4gICAgICAvLyBBbHNvIHZlcmlmeSBzaWduYXR1cmUgdmFsaWRpdHlcbiAgICAgIGNvbnN0IHNpZ09ubHkgPSBzaWcuc2xpY2UoMCwgNjQpO1xuICAgICAgY29uc3QgaXNWYWxpZCA9IHV0aWxzLnZlcmlmeVNpZ25hdHVyZShzaWduYWJsZVBheWxvYWQsIHNpZ09ubHksIHJlY292ZXJlZFB1YktleSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNWYWxpZCwgdHJ1ZSwgJ1NpZ25hdHVyZSB2ZXJpZmljYXRpb24gZmFpbGVkJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1RyYW5zYWN0aW9uT2YnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndGZscnAnKSk7XG4gICAgY29uc3QgdXRpbHNJbnN0YW5jZSA9IG5ldyBVdGlscygpO1xuICAgIGNvbnN0IHRlc3RuZXROZXR3b3JrID0gY29pbnMuZ2V0KCd0ZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgIGNvbnN0IHBDaGFpbkJsb2NrY2hhaW5JZEhleCA9IEJ1ZmZlci5mcm9tKHV0aWxzSW5zdGFuY2UuY2I1OERlY29kZSh0ZXN0bmV0TmV0d29yay5ibG9ja2NoYWluSUQpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgY29uc3QgY0NoYWluQmxvY2tjaGFpbklkSGV4ID0gQnVmZmVyLmZyb20odXRpbHNJbnN0YW5jZS5jYjU4RGVjb2RlKHRlc3RuZXROZXR3b3JrLmNDaGFpbkJsb2NrY2hhaW5JRCkpLnRvU3RyaW5nKFxuICAgICAgJ2hleCdcbiAgICApO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgSW1wb3J0IGluIFAgdHJhbnNhY3Rpb24gd2l0aCBtYXRjaGluZyBQLWNoYWluIGJsb2NrY2hhaW4gSUQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRJbXBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZChJTVBPUlRfSU5fUC50aHJlc2hvbGQpXG4gICAgICAgIC5sb2NrdGltZShJTVBPUlRfSU5fUC5sb2NrdGltZSlcbiAgICAgICAgLmZyb21QdWJLZXkoSU1QT1JUX0lOX1AuY29yZXRoQWRkcmVzc2VzKVxuICAgICAgICAudG8oSU1QT1JUX0lOX1AucEFkZHJlc3NlcylcbiAgICAgICAgLmV4dGVybmFsQ2hhaW5JZChJTVBPUlRfSU5fUC5zb3VyY2VDaGFpbklkKVxuICAgICAgICAuZmVlU3RhdGUoSU1QT1JUX0lOX1AuZmVlU3RhdGUpXG4gICAgICAgIC5jb250ZXh0KElNUE9SVF9JTl9QLmNvbnRleHQpXG4gICAgICAgIC51dHhvcyhJTVBPUlRfSU5fUC51dHhvSGV4KTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmxhcmVUcmFuc2FjdGlvbiA9IHR4LmdldEZsYXJlVHJhbnNhY3Rpb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzSW5zdGFuY2UuaXNUcmFuc2FjdGlvbk9mKGZsYXJlVHJhbnNhY3Rpb24sIHBDaGFpbkJsb2NrY2hhaW5JZEhleCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIEltcG9ydCBpbiBQIHRyYW5zYWN0aW9uIHdpdGggbm9uLW1hdGNoaW5nIEMtY2hhaW4gYmxvY2tjaGFpbiBJRCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldEltcG9ydEluUEJ1aWxkZXIoKVxuICAgICAgICAudGhyZXNob2xkKElNUE9SVF9JTl9QLnRocmVzaG9sZClcbiAgICAgICAgLmxvY2t0aW1lKElNUE9SVF9JTl9QLmxvY2t0aW1lKVxuICAgICAgICAuZnJvbVB1YktleShJTVBPUlRfSU5fUC5jb3JldGhBZGRyZXNzZXMpXG4gICAgICAgIC50byhJTVBPUlRfSU5fUC5wQWRkcmVzc2VzKVxuICAgICAgICAuZXh0ZXJuYWxDaGFpbklkKElNUE9SVF9JTl9QLnNvdXJjZUNoYWluSWQpXG4gICAgICAgIC5mZWVTdGF0ZShJTVBPUlRfSU5fUC5mZWVTdGF0ZSlcbiAgICAgICAgLmNvbnRleHQoSU1QT1JUX0lOX1AuY29udGV4dClcbiAgICAgICAgLnV0eG9zKElNUE9SVF9JTl9QLnV0eG9IZXgpO1xuXG4gICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCBmbGFyZVRyYW5zYWN0aW9uID0gdHguZ2V0RmxhcmVUcmFuc2FjdGlvbigpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHNJbnN0YW5jZS5pc1RyYW5zYWN0aW9uT2YoZmxhcmVUcmFuc2FjdGlvbiwgY0NoYWluQmxvY2tjaGFpbklkSGV4KSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgRXhwb3J0IGluIFAgdHJhbnNhY3Rpb24gd2l0aCBtYXRjaGluZyBQLWNoYWluIGJsb2NrY2hhaW4gSUQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRFeHBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZChFWFBPUlRfSU5fUC50aHJlc2hvbGQpXG4gICAgICAgIC5sb2NrdGltZShFWFBPUlRfSU5fUC5sb2NrdGltZSlcbiAgICAgICAgLmZyb21QdWJLZXkoRVhQT1JUX0lOX1AucEFkZHJlc3NlcylcbiAgICAgICAgLmV4dGVybmFsQ2hhaW5JZChFWFBPUlRfSU5fUC5zb3VyY2VDaGFpbklkKVxuICAgICAgICAuZmVlU3RhdGUoRVhQT1JUX0lOX1AuZmVlU3RhdGUpXG4gICAgICAgIC5jb250ZXh0KEVYUE9SVF9JTl9QLmNvbnRleHQpXG4gICAgICAgIC5hbW91bnQoRVhQT1JUX0lOX1AuYW1vdW50KVxuICAgICAgICAudXR4b3MoRVhQT1JUX0lOX1AudXR4b3MpO1xuXG4gICAgICBjb25zdCB0eCA9IChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCBmbGFyZVRyYW5zYWN0aW9uID0gdHguZ2V0RmxhcmVUcmFuc2FjdGlvbigpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHNJbnN0YW5jZS5pc1RyYW5zYWN0aW9uT2YoZmxhcmVUcmFuc2FjdGlvbiwgcENoYWluQmxvY2tjaGFpbklkSGV4KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgRXhwb3J0IGluIFAgdHJhbnNhY3Rpb24gd2l0aCBub24tbWF0Y2hpbmcgQy1jaGFpbiBibG9ja2NoYWluIElEJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0RXhwb3J0SW5QQnVpbGRlcigpXG4gICAgICAgIC50aHJlc2hvbGQoRVhQT1JUX0lOX1AudGhyZXNob2xkKVxuICAgICAgICAubG9ja3RpbWUoRVhQT1JUX0lOX1AubG9ja3RpbWUpXG4gICAgICAgIC5mcm9tUHViS2V5KEVYUE9SVF9JTl9QLnBBZGRyZXNzZXMpXG4gICAgICAgIC5leHRlcm5hbENoYWluSWQoRVhQT1JUX0lOX1Auc291cmNlQ2hhaW5JZClcbiAgICAgICAgLmZlZVN0YXRlKEVYUE9SVF9JTl9QLmZlZVN0YXRlKVxuICAgICAgICAuY29udGV4dChFWFBPUlRfSU5fUC5jb250ZXh0KVxuICAgICAgICAuYW1vdW50KEVYUE9SVF9JTl9QLmFtb3VudClcbiAgICAgICAgLnV0eG9zKEVYUE9SVF9JTl9QLnV0eG9zKTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmxhcmVUcmFuc2FjdGlvbiA9IHR4LmdldEZsYXJlVHJhbnNhY3Rpb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzSW5zdGFuY2UuaXNUcmFuc2FjdGlvbk9mKGZsYXJlVHJhbnNhY3Rpb24sIGNDaGFpbkJsb2NrY2hhaW5JZEhleCksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIEltcG9ydCBpbiBDIHRyYW5zYWN0aW9uIHdpdGggbWF0Y2hpbmcgQy1jaGFpbiBibG9ja2NoYWluIElEJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0SW1wb3J0SW5DQnVpbGRlcigpXG4gICAgICAgIC50aHJlc2hvbGQoSU1QT1JUX0lOX0MudGhyZXNob2xkKVxuICAgICAgICAubG9ja3RpbWUoSU1QT1JUX0lOX0MubG9ja3RpbWUpXG4gICAgICAgIC5mcm9tUHViS2V5KElNUE9SVF9JTl9DLnBBZGRyZXNzZXMpXG4gICAgICAgIC5leHRlcm5hbENoYWluSWQoSU1QT1JUX0lOX0Muc291cmNlQ2hhaW5JZClcbiAgICAgICAgLmZlZShJTVBPUlRfSU5fQy5mZWUpXG4gICAgICAgIC5jb250ZXh0KElNUE9SVF9JTl9DLmNvbnRleHQpXG4gICAgICAgIC50byhJTVBPUlRfSU5fQy50bylcbiAgICAgICAgLnV0eG9zKElNUE9SVF9JTl9DLnV0eG9zKTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmxhcmVUcmFuc2FjdGlvbiA9IHR4LmdldEZsYXJlVHJhbnNhY3Rpb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzSW5zdGFuY2UuaXNUcmFuc2FjdGlvbk9mKGZsYXJlVHJhbnNhY3Rpb24sIGNDaGFpbkJsb2NrY2hhaW5JZEhleCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIEltcG9ydCBpbiBDIHRyYW5zYWN0aW9uIHdpdGggbm9uLW1hdGNoaW5nIFAtY2hhaW4gYmxvY2tjaGFpbiBJRCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldEltcG9ydEluQ0J1aWxkZXIoKVxuICAgICAgICAudGhyZXNob2xkKElNUE9SVF9JTl9DLnRocmVzaG9sZClcbiAgICAgICAgLmxvY2t0aW1lKElNUE9SVF9JTl9DLmxvY2t0aW1lKVxuICAgICAgICAuZnJvbVB1YktleShJTVBPUlRfSU5fQy5wQWRkcmVzc2VzKVxuICAgICAgICAuZXh0ZXJuYWxDaGFpbklkKElNUE9SVF9JTl9DLnNvdXJjZUNoYWluSWQpXG4gICAgICAgIC5mZWUoSU1QT1JUX0lOX0MuZmVlKVxuICAgICAgICAuY29udGV4dChJTVBPUlRfSU5fQy5jb250ZXh0KVxuICAgICAgICAudG8oSU1QT1JUX0lOX0MudG8pXG4gICAgICAgIC51dHhvcyhJTVBPUlRfSU5fQy51dHhvcyk7XG5cbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICAgIGNvbnN0IGZsYXJlVHJhbnNhY3Rpb24gPSB0eC5nZXRGbGFyZVRyYW5zYWN0aW9uKCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlsc0luc3RhbmNlLmlzVHJhbnNhY3Rpb25PZihmbGFyZVRyYW5zYWN0aW9uLCBwQ2hhaW5CbG9ja2NoYWluSWRIZXgpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBFeHBvcnQgaW4gQyB0cmFuc2FjdGlvbiB3aXRoIG1hdGNoaW5nIEMtY2hhaW4gYmxvY2tjaGFpbiBJRCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldEV4cG9ydEluQ0J1aWxkZXIoKVxuICAgICAgICAuZnJvbVB1YktleShFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcylcbiAgICAgICAgLm5vbmNlKEVYUE9SVF9JTl9DLm5vbmNlKVxuICAgICAgICAuYW1vdW50KEVYUE9SVF9JTl9DLmFtb3VudClcbiAgICAgICAgLnRocmVzaG9sZChFWFBPUlRfSU5fQy50aHJlc2hvbGQpXG4gICAgICAgIC5sb2NrdGltZShFWFBPUlRfSU5fQy5sb2NrdGltZSlcbiAgICAgICAgLnRvKEVYUE9SVF9JTl9DLnBBZGRyZXNzZXMpXG4gICAgICAgIC5mZWUoRVhQT1JUX0lOX0MuZmVlKVxuICAgICAgICAuY29udGV4dChFWFBPUlRfSU5fQy5jb250ZXh0KTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmxhcmVUcmFuc2FjdGlvbiA9IHR4LmdldEZsYXJlVHJhbnNhY3Rpb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzSW5zdGFuY2UuaXNUcmFuc2FjdGlvbk9mKGZsYXJlVHJhbnNhY3Rpb24sIGNDaGFpbkJsb2NrY2hhaW5JZEhleCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIEV4cG9ydCBpbiBDIHRyYW5zYWN0aW9uIHdpdGggbm9uLW1hdGNoaW5nIFAtY2hhaW4gYmxvY2tjaGFpbiBJRCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldEV4cG9ydEluQ0J1aWxkZXIoKVxuICAgICAgICAuZnJvbVB1YktleShFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcylcbiAgICAgICAgLm5vbmNlKEVYUE9SVF9JTl9DLm5vbmNlKVxuICAgICAgICAuYW1vdW50KEVYUE9SVF9JTl9DLmFtb3VudClcbiAgICAgICAgLnRocmVzaG9sZChFWFBPUlRfSU5fQy50aHJlc2hvbGQpXG4gICAgICAgIC5sb2NrdGltZShFWFBPUlRfSU5fQy5sb2NrdGltZSlcbiAgICAgICAgLnRvKEVYUE9SVF9JTl9DLnBBZGRyZXNzZXMpXG4gICAgICAgIC5mZWUoRVhQT1JUX0lOX0MuZmVlKVxuICAgICAgICAuY29udGV4dChFWFBPUlRfSU5fQy5jb250ZXh0KTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmxhcmVUcmFuc2FjdGlvbiA9IHR4LmdldEZsYXJlVHJhbnNhY3Rpb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzSW5zdGFuY2UuaXNUcmFuc2FjdGlvbk9mKGZsYXJlVHJhbnNhY3Rpb24sIHBDaGFpbkJsb2NrY2hhaW5JZEhleCksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIGJsb2NrY2hhaW4gSUQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRJbXBvcnRJblBCdWlsZGVyKClcbiAgICAgICAgLnRocmVzaG9sZChJTVBPUlRfSU5fUC50aHJlc2hvbGQpXG4gICAgICAgIC5sb2NrdGltZShJTVBPUlRfSU5fUC5sb2NrdGltZSlcbiAgICAgICAgLmZyb21QdWJLZXkoSU1QT1JUX0lOX1AuY29yZXRoQWRkcmVzc2VzKVxuICAgICAgICAudG8oSU1QT1JUX0lOX1AucEFkZHJlc3NlcylcbiAgICAgICAgLmV4dGVybmFsQ2hhaW5JZChJTVBPUlRfSU5fUC5zb3VyY2VDaGFpbklkKVxuICAgICAgICAuZmVlU3RhdGUoSU1QT1JUX0lOX1AuZmVlU3RhdGUpXG4gICAgICAgIC5jb250ZXh0KElNUE9SVF9JTl9QLmNvbnRleHQpXG4gICAgICAgIC51dHhvcyhJTVBPUlRfSU5fUC51dHhvSGV4KTtcblxuICAgICAgY29uc3QgdHggPSAoYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZmxhcmVUcmFuc2FjdGlvbiA9IHR4LmdldEZsYXJlVHJhbnNhY3Rpb24oKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzSW5zdGFuY2UuaXNUcmFuc2FjdGlvbk9mKGZsYXJlVHJhbnNhY3Rpb24sICdpbnZhbGlkYmxvY2tjaGFpbmlkJyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==