@bitgo-beta/sdk-coin-eth 4.4.1-beta.202 → 4.4.1-beta.2021

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/src/erc20Token.d.ts +1 -1
  2. package/dist/src/erc20Token.d.ts.map +1 -1
  3. package/dist/src/erc20Token.js +49 -28
  4. package/dist/src/erc721Token.d.ts +60 -0
  5. package/dist/src/erc721Token.d.ts.map +1 -0
  6. package/dist/src/erc721Token.js +334 -0
  7. package/dist/src/erc7984Token.d.ts +187 -0
  8. package/dist/src/erc7984Token.d.ts.map +1 -0
  9. package/dist/src/erc7984Token.js +946 -0
  10. package/dist/src/eth.d.ts +10 -8
  11. package/dist/src/eth.d.ts.map +1 -1
  12. package/dist/src/eth.js +54 -39
  13. package/dist/src/index.d.ts +3 -0
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +9 -2
  16. package/dist/src/lib/index.d.ts +1 -0
  17. package/dist/src/lib/index.d.ts.map +1 -1
  18. package/dist/src/lib/index.js +7 -2
  19. package/dist/src/lib/messages/index.d.ts +3 -0
  20. package/dist/src/lib/messages/index.d.ts.map +1 -0
  21. package/dist/src/lib/messages/index.js +6 -0
  22. package/dist/src/lib/transactionBuilder.d.ts +10 -5
  23. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  24. package/dist/src/lib/transactionBuilder.js +17 -7
  25. package/dist/src/lib/transferBuilders/index.d.ts +2 -2
  26. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -1
  27. package/dist/src/lib/transferBuilders/index.js +3 -2
  28. package/dist/src/register.d.ts +2 -0
  29. package/dist/src/register.d.ts.map +1 -1
  30. package/dist/src/register.js +39 -2
  31. package/dist/src/sepeth.d.ts +8 -0
  32. package/dist/src/sepeth.d.ts.map +1 -0
  33. package/dist/src/sepeth.js +14 -0
  34. package/dist/test/fixtures/eth.d.ts +39 -0
  35. package/dist/test/fixtures/eth.d.ts.map +1 -0
  36. package/dist/test/fixtures/eth.js +262 -0
  37. package/dist/test/resources/erc1155Abi.d.ts +40 -0
  38. package/dist/test/resources/erc1155Abi.d.ts.map +1 -0
  39. package/dist/test/resources/erc1155Abi.js +329 -0
  40. package/dist/test/resources/erc721Abi.d.ts +12 -0
  41. package/dist/test/resources/erc721Abi.d.ts.map +1 -0
  42. package/dist/test/resources/erc721Abi.js +34 -0
  43. package/dist/test/resources/eth.d.ts +51 -0
  44. package/dist/test/resources/eth.d.ts.map +1 -0
  45. package/dist/test/resources/eth.js +72 -0
  46. package/dist/test/resources/nftEncodings.d.ts +4 -0
  47. package/dist/test/resources/nftEncodings.d.ts.map +1 -0
  48. package/dist/test/resources/nftEncodings.js +7 -0
  49. package/dist/test/resources/walletSimpleAbi.d.ts +12 -0
  50. package/dist/test/resources/walletSimpleAbi.d.ts.map +1 -0
  51. package/dist/test/resources/walletSimpleAbi.js +44 -0
  52. package/dist/test/unit/erc7984Token.d.ts +2 -0
  53. package/dist/test/unit/erc7984Token.d.ts.map +1 -0
  54. package/dist/test/unit/erc7984Token.js +1589 -0
  55. package/dist/test/unit/eth.d.ts +2 -0
  56. package/dist/test/unit/eth.d.ts.map +1 -0
  57. package/dist/test/unit/eth.js +2701 -0
  58. package/dist/test/unit/ethWallet.d.ts +2 -0
  59. package/dist/test/unit/ethWallet.d.ts.map +1 -0
  60. package/dist/test/unit/ethWallet.js +552 -0
  61. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts +4 -0
  62. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts.map +1 -0
  63. package/dist/test/unit/fixtures/ethMultiSigBackupKey.js +10 -0
  64. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts +5 -0
  65. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts.map +1 -0
  66. package/dist/test/unit/fixtures/ethTssBackupKey.js +25 -0
  67. package/dist/test/unit/getBuilder.d.ts +3 -0
  68. package/dist/test/unit/getBuilder.d.ts.map +1 -0
  69. package/dist/test/unit/getBuilder.js +10 -0
  70. package/dist/test/unit/keyPair.d.ts +2 -0
  71. package/dist/test/unit/keyPair.d.ts.map +1 -0
  72. package/dist/test/unit/keyPair.js +175 -0
  73. package/dist/test/unit/register.d.ts +2 -0
  74. package/dist/test/unit/register.d.ts.map +1 -0
  75. package/dist/test/unit/register.js +75 -0
  76. package/dist/test/unit/transaction.d.ts +2 -0
  77. package/dist/test/unit/transaction.d.ts.map +1 -0
  78. package/dist/test/unit/transaction.js +117 -0
  79. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
  80. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  81. package/dist/test/unit/transactionBuilder/addressInitialization.js +101 -0
  82. package/dist/test/unit/transactionBuilder/contractCall.d.ts +2 -0
  83. package/dist/test/unit/transactionBuilder/contractCall.d.ts.map +1 -0
  84. package/dist/test/unit/transactionBuilder/contractCall.js +101 -0
  85. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts +2 -0
  86. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts.map +1 -0
  87. package/dist/test/unit/transactionBuilder/decryptionDelegation.js +59 -0
  88. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts +2 -0
  89. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.d.ts.map +1 -0
  90. package/dist/test/unit/transactionBuilder/decryptionDelegationTxBuilder.js +136 -0
  91. package/dist/test/unit/transactionBuilder/flushCoins.d.ts +2 -0
  92. package/dist/test/unit/transactionBuilder/flushCoins.d.ts.map +1 -0
  93. package/dist/test/unit/transactionBuilder/flushCoins.js +133 -0
  94. package/dist/test/unit/transactionBuilder/flushTokens.d.ts +2 -0
  95. package/dist/test/unit/transactionBuilder/flushTokens.d.ts.map +1 -0
  96. package/dist/test/unit/transactionBuilder/flushTokens.js +298 -0
  97. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  98. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  99. package/dist/test/unit/transactionBuilder/send.js +331 -0
  100. package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts +2 -0
  101. package/dist/test/unit/transactionBuilder/sendERC7984Token.d.ts.map +1 -0
  102. package/dist/test/unit/transactionBuilder/sendERC7984Token.js +361 -0
  103. package/dist/test/unit/transactionBuilder/sendNFT.d.ts +2 -0
  104. package/dist/test/unit/transactionBuilder/sendNFT.d.ts.map +1 -0
  105. package/dist/test/unit/transactionBuilder/sendNFT.js +295 -0
  106. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts +2 -0
  107. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts.map +1 -0
  108. package/dist/test/unit/transactionBuilder/singleSigSend.js +196 -0
  109. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  110. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  111. package/dist/test/unit/transactionBuilder/walletInitialization.js +436 -0
  112. package/dist/test/unit/transferBuilder.d.ts +2 -0
  113. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  114. package/dist/test/unit/transferBuilder.js +124 -0
  115. package/dist/test/unit/utils.d.ts +2 -0
  116. package/dist/test/unit/utils.d.ts.map +1 -0
  117. package/dist/test/unit/utils.js +74 -0
  118. package/dist/tsconfig.tsbuildinfo +1 -0
  119. package/package.json +17 -13
  120. package/.eslintignore +0 -5
  121. package/.mocharc.yml +0 -8
  122. package/CHANGELOG.md +0 -771
@@ -0,0 +1,2701 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
40
+ const nock_1 = __importDefault(require("nock"));
41
+ const sinon_1 = __importDefault(require("sinon"));
42
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
43
+ const secp256k1 = __importStar(require("secp256k1"));
44
+ const superagent_1 = __importDefault(require("superagent"));
45
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
46
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
47
+ const src_1 = require("../../src");
48
+ const assert_1 = __importDefault(require("assert"));
49
+ const getBuilder_1 = require("./getBuilder");
50
+ const testData = __importStar(require("../resources/eth"));
51
+ const mockData = __importStar(require("../fixtures/eth"));
52
+ const should_1 = __importDefault(require("should"));
53
+ const ethereumjs_abi_1 = __importDefault(require("ethereumjs-abi"));
54
+ const ethMultiSigBackupKey_1 = require("./fixtures/ethMultiSigBackupKey");
55
+ const ethTssBackupKey_1 = require("./fixtures/ethTssBackupKey");
56
+ nock_1.default.enableNetConnect();
57
+ describe('ETH:', function () {
58
+ let bitgo;
59
+ let hopTxBitgoSignature;
60
+ let sandbox;
61
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
62
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
63
+ const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
64
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
65
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
66
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
67
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
68
+ const buildDefiTxHex = async (data) => {
69
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
70
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
71
+ txBuilder.fee({ fee: '10', gasLimit: '100000' });
72
+ txBuilder.counter(1);
73
+ txBuilder.contract(address1);
74
+ txBuilder.data(data);
75
+ return (await txBuilder.build()).toBroadcastFormat();
76
+ };
77
+ const defiCalldata = (signature, values) => {
78
+ const types = signature.slice(signature.indexOf('(') + 1, -1).split(',');
79
+ const methodId = ethereumjs_abi_1.default.methodID(signature.split('(')[0], types);
80
+ return '0x' + Buffer.concat([methodId, ethereumjs_abi_1.default.rawEncode(types, values)]).toString('hex');
81
+ };
82
+ before(function () {
83
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
84
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
85
+ if (!bitgoKey.privateKey) {
86
+ throw new Error('no privateKey');
87
+ }
88
+ const bitgoXpub = bitgoKey.neutered().toBase58();
89
+ hopTxBitgoSignature =
90
+ '0xaa' +
91
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
92
+ const env = 'test';
93
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
94
+ src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
95
+ bitgo.safeRegister(name, coinConstructor);
96
+ });
97
+ bitgo.safeRegister('teth', src_1.Teth.createInstance);
98
+ bitgo.safeRegister('hteth', src_1.Hteth.createInstance);
99
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
100
+ bitgo.initializeTestVars();
101
+ sandbox = sinon_1.default.createSandbox();
102
+ });
103
+ after(function () {
104
+ nock_1.default.cleanAll();
105
+ sandbox.restore();
106
+ });
107
+ describe('EIP1559', function () {
108
+ it('should sign a transaction with EIP1559 fee params', async function () {
109
+ const coin = bitgo.coin('teth');
110
+ const userKeychain = {
111
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
112
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
113
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
114
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
115
+ };
116
+ const halfSignedTransaction = await coin.signTransaction({
117
+ txPrebuild: {
118
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
119
+ isBatch: false,
120
+ recipients: [
121
+ {
122
+ amount: '42',
123
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
124
+ },
125
+ ],
126
+ expireTime: 1627949214,
127
+ contractSequenceId: 12,
128
+ gasLimit: undefined,
129
+ gasPrice: undefined,
130
+ hopTransaction: undefined,
131
+ backupKeyNonce: undefined,
132
+ sequenceId: undefined,
133
+ nextContractSequenceId: 0,
134
+ },
135
+ prv: userKeychain.prv,
136
+ });
137
+ halfSignedTransaction.halfSigned.eip1559.maxPriorityFeePerGas.should.equal(10);
138
+ halfSignedTransaction.halfSigned.eip1559.maxFeePerGas.should.equal(10);
139
+ });
140
+ it('should sign a transaction with EIP1559 fee params for CCR', async function () {
141
+ const coin = bitgo.coin('hteth');
142
+ const signTransaction = sinon_1.default.spy(src_1.AbstractEthLikeNewCoins.prototype, 'signTransaction');
143
+ const userKeychain = {
144
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
145
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
146
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
147
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
148
+ };
149
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
150
+ txBuilder.type(sdk_core_1.TransactionType.Send);
151
+ txBuilder.fee({
152
+ fee: '10',
153
+ gasLimit: '1000',
154
+ });
155
+ const key = testData.KEYPAIR_PRV.getKeys().prv;
156
+ const transferBuilder = txBuilder.transfer();
157
+ transferBuilder
158
+ .amount('0')
159
+ .to('0x19645032c7f1533395d44a629462e751084d3e4c')
160
+ .expirationTime(1590066728)
161
+ .contractSequenceId(5)
162
+ .key(key);
163
+ txBuilder.contract(address1);
164
+ const tx = await txBuilder.build();
165
+ const halfSignedTransaction = await coin.signTransaction({
166
+ txPrebuild: {
167
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
168
+ isBatch: false,
169
+ recipients: [
170
+ {
171
+ amount: '42',
172
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
173
+ },
174
+ ],
175
+ expireTime: 1627949214,
176
+ contractSequenceId: 12,
177
+ gasLimit: undefined,
178
+ gasPrice: undefined,
179
+ hopTransaction: undefined,
180
+ backupKeyNonce: undefined,
181
+ sequenceId: undefined,
182
+ nextContractSequenceId: 0,
183
+ txHex: tx.toBroadcastFormat(),
184
+ },
185
+ prv: userKeychain.prv,
186
+ isEvmBasedCrossChainRecovery: true,
187
+ });
188
+ (0, assert_1.default)(halfSignedTransaction.halfSigned.txHex);
189
+ assert_1.default.strictEqual(halfSignedTransaction.halfSigned.eip1559.maxFeePerGas, 10);
190
+ sandbox.assert.calledOnce(signTransaction);
191
+ });
192
+ });
193
+ describe('Transaction Verification', function () {
194
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async function () {
195
+ const coin = bitgo.coin('teth');
196
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
197
+ const txParams = {
198
+ recipients: [{ amount: '1000000000000', address: address1 }],
199
+ wallet: wallet,
200
+ walletPassphrase: 'fakeWalletPassphrase',
201
+ };
202
+ const txPrebuild = {
203
+ recipients: [{ amount: '1000000000000', address: address1 }],
204
+ nextContractSequenceId: 0,
205
+ gasPrice: 20000000000,
206
+ gasLimit: 500000,
207
+ isBatch: false,
208
+ coin: 'teth',
209
+ wallet: 'fakeWalletId',
210
+ walletContractAddress: 'fakeWalletContractAddress',
211
+ };
212
+ const verification = {};
213
+ const isTransactionVerified = await coin.verifyTransaction({
214
+ txParams,
215
+ txPrebuild: txPrebuild,
216
+ wallet,
217
+ verification,
218
+ });
219
+ isTransactionVerified.should.equal(true);
220
+ });
221
+ it('should verify a batch txPrebuild from the bitgo server that matches the client txParams', async function () {
222
+ const coin = bitgo.coin('teth');
223
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
224
+ const txParams = {
225
+ recipients: [
226
+ { amount: '1000000000000', address: address1 },
227
+ { amount: '2500000000000', address: address2 },
228
+ ],
229
+ wallet: wallet,
230
+ walletPassphrase: 'fakeWalletPassphrase',
231
+ };
232
+ const txPrebuild = {
233
+ recipients: [
234
+ { amount: '3500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
235
+ ],
236
+ nextContractSequenceId: 0,
237
+ gasPrice: 20000000000,
238
+ gasLimit: 500000,
239
+ isBatch: true,
240
+ coin: 'teth',
241
+ walletId: 'fakeWalletId',
242
+ walletContractAddress: 'fakeWalletContractAddress',
243
+ };
244
+ const verification = {};
245
+ const isTransactionVerified = await coin.verifyTransaction({
246
+ txParams,
247
+ txPrebuild: txPrebuild,
248
+ wallet,
249
+ verification,
250
+ });
251
+ isTransactionVerified.should.equal(true);
252
+ });
253
+ it('should verify ENS address resolution changing recipient address in client txParams', async function () {
254
+ const coin = bitgo.coin('teth');
255
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
256
+ const txParams = {
257
+ recipients: [{ amount: '1000000000000', address: 'bitgotestwallet.eth' }],
258
+ wallet: wallet,
259
+ walletPassphrase: 'fakeWalletPassphrase',
260
+ };
261
+ const txPrebuild = {
262
+ recipients: [{ amount: '1000000000000', address: '0x40a663963810449d6e72533657a74f112c3b901a' }],
263
+ nextContractSequenceId: 0,
264
+ gasPrice: 20000000000,
265
+ gasLimit: 500000,
266
+ isBatch: false,
267
+ coin: 'teth',
268
+ walletId: 'fakeWalletId',
269
+ walletContractAddress: 'fakeWalletContractAddress',
270
+ };
271
+ const verification = {};
272
+ const isTransactionVerified = await coin.verifyTransaction({
273
+ txParams,
274
+ txPrebuild: txPrebuild,
275
+ wallet,
276
+ verification,
277
+ });
278
+ isTransactionVerified.should.equal(true);
279
+ });
280
+ it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
281
+ const coin = bitgo.coin('teth');
282
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
283
+ const txParams = {
284
+ recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
285
+ wallet: wallet,
286
+ walletPassphrase: 'fakeWalletPassphrase',
287
+ hop: true,
288
+ };
289
+ const txPrebuild = {
290
+ recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
291
+ nextContractSequenceId: 0,
292
+ gasPrice: 20000000000,
293
+ gasLimit: 500000,
294
+ isBatch: false,
295
+ coin: 'teth',
296
+ walletId: 'fakeWalletId',
297
+ walletContractAddress: 'fakeWalletContractAddress',
298
+ hopTransaction: {
299
+ tx: hopTx,
300
+ id: hopTxid,
301
+ signature: hopTxBitgoSignature,
302
+ paymentId: '2773928196',
303
+ gasPrice: 20000000000,
304
+ gasLimit: 500000,
305
+ amount: '1000000000000000',
306
+ recipient: hopDestinationAddress,
307
+ nonce: 0,
308
+ userReqSig: userReqSig,
309
+ gasPriceMax: 500000000000,
310
+ },
311
+ };
312
+ const verification = {};
313
+ const isTransactionVerified = await coin.verifyTransaction({
314
+ txParams,
315
+ txPrebuild: txPrebuild,
316
+ wallet,
317
+ verification,
318
+ });
319
+ isTransactionVerified.should.equal(true);
320
+ });
321
+ it('should reject when client txParams are missing', async function () {
322
+ const coin = bitgo.coin('teth');
323
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
324
+ const txParams = null;
325
+ const txPrebuild = {
326
+ recipients: [{ amount: '1000000000000', address: address1 }],
327
+ nextContractSequenceId: 0,
328
+ gasPrice: 20000000000,
329
+ gasLimit: 500000,
330
+ isBatch: false,
331
+ coin: 'teth',
332
+ walletId: 'fakeWalletId',
333
+ walletContractAddress: 'fakeWalletContractAddress',
334
+ };
335
+ const verification = {};
336
+ await coin
337
+ .verifyTransaction({ txParams: txParams, txPrebuild: txPrebuild, wallet, verification })
338
+ .should.be.rejectedWith('missing params');
339
+ });
340
+ it('should reject txPrebuild that is both batch and hop', async function () {
341
+ const coin = bitgo.coin('teth');
342
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
343
+ const txParams = {
344
+ recipients: [
345
+ { amount: '1000000000000', address: address1 },
346
+ { amount: '2500000000000', address: address2 },
347
+ ],
348
+ wallet: wallet,
349
+ walletPassphrase: 'fakeWalletPassphrase',
350
+ hop: true,
351
+ };
352
+ const txPrebuild = {
353
+ recipients: [{ amount: '3500000000000', address: address1 }],
354
+ nextContractSequenceId: 0,
355
+ gasPrice: 20000000000,
356
+ gasLimit: 500000,
357
+ isBatch: true,
358
+ coin: 'teth',
359
+ walletId: 'fakeWalletId',
360
+ walletContractAddress: 'fakeWalletContractAddress',
361
+ hopTransaction: {
362
+ tx: hopTx,
363
+ id: hopTxid,
364
+ signature: hopTxBitgoSignature,
365
+ paymentId: '2773928196',
366
+ gasPrice: 20000000000,
367
+ gasLimit: 500000,
368
+ amount: '1000000000000000',
369
+ recipient: hopDestinationAddress,
370
+ nonce: 0,
371
+ userReqSig: userReqSig,
372
+ gasPriceMax: 500000000000,
373
+ },
374
+ };
375
+ const verification = {};
376
+ await coin
377
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
378
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
379
+ });
380
+ it('should reject a txPrebuild with more than one recipient', async function () {
381
+ const coin = bitgo.coin('teth');
382
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
383
+ const txParams = {
384
+ recipients: [
385
+ { amount: '1000000000000', address: address1 },
386
+ { amount: '2500000000000', address: address2 },
387
+ ],
388
+ wallet: wallet,
389
+ walletPassphrase: 'fakeWalletPassphrase',
390
+ };
391
+ const txPrebuild = {
392
+ recipients: [
393
+ { amount: '1000000000000', address: address1 },
394
+ { amount: '2500000000000', address: address2 },
395
+ ],
396
+ nextContractSequenceId: 0,
397
+ gasPrice: 20000000000,
398
+ gasLimit: 500000,
399
+ isBatch: true,
400
+ coin: 'teth',
401
+ walletId: 'fakeWalletId',
402
+ walletContractAddress: 'fakeWalletContractAddress',
403
+ };
404
+ const verification = {};
405
+ await coin
406
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
407
+ .should.be.rejectedWith(`teth doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`);
408
+ });
409
+ it('should reject a hop txPrebuild that does not send to its hop address', async function () {
410
+ const coin = bitgo.coin('teth');
411
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
412
+ const txParams = {
413
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
414
+ wallet: wallet,
415
+ walletPassphrase: 'fakeWalletPassphrase',
416
+ hop: true,
417
+ };
418
+ const txPrebuild = {
419
+ recipients: [{ amount: '5000000000000000', address: address1 }],
420
+ nextContractSequenceId: 0,
421
+ gasPrice: 20000000000,
422
+ gasLimit: 500000,
423
+ isBatch: false,
424
+ coin: 'teth',
425
+ walletId: 'fakeWalletId',
426
+ walletContractAddress: 'fakeWalletContractAddress',
427
+ hopTransaction: {
428
+ tx: hopTx,
429
+ id: hopTxid,
430
+ signature: hopTxBitgoSignature,
431
+ paymentId: '0',
432
+ gasPrice: 20000000000,
433
+ gasLimit: 500000,
434
+ amount: '1000000000000000',
435
+ recipient: hopDestinationAddress,
436
+ nonce: 0,
437
+ userReqSig: userReqSig,
438
+ gasPriceMax: 500000000000,
439
+ },
440
+ };
441
+ const verification = {};
442
+ await coin
443
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
444
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
445
+ });
446
+ it('should reject a batch txPrebuild from the bitgo server with the wrong total amount', async function () {
447
+ const coin = bitgo.coin('teth');
448
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
449
+ const txParams = {
450
+ recipients: [
451
+ { amount: '1000000000000', address: address1 },
452
+ { amount: '2500000000000', address: address2 },
453
+ ],
454
+ wallet: wallet,
455
+ walletPassphrase: 'fakeWalletPassphrase',
456
+ };
457
+ const txPrebuild = {
458
+ recipients: [
459
+ { amount: '5500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
460
+ ],
461
+ nextContractSequenceId: 0,
462
+ gasPrice: 20000000000,
463
+ gasLimit: 500000,
464
+ isBatch: true,
465
+ coin: 'teth',
466
+ walletId: 'fakeWalletId',
467
+ walletContractAddress: 'fakeWalletContractAddress',
468
+ };
469
+ const verification = {};
470
+ await coin
471
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
472
+ .should.be.rejectedWith('batch transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
473
+ });
474
+ it('should reject a batch txPrebuild from the bitgo server that does not send to the batcher contract address', async function () {
475
+ const coin = bitgo.coin('teth');
476
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
477
+ const txParams = {
478
+ recipients: [
479
+ { amount: '1000000000000', address: address1 },
480
+ { amount: '2500000000000', address: address2 },
481
+ ],
482
+ wallet: wallet,
483
+ walletPassphrase: 'fakeWalletPassphrase',
484
+ };
485
+ const txPrebuild = {
486
+ recipients: [{ amount: '3500000000000', address: hopContractAddress }],
487
+ nextContractSequenceId: 0,
488
+ gasPrice: 20000000000,
489
+ gasLimit: 500000,
490
+ isBatch: true,
491
+ coin: 'teth',
492
+ walletId: 'fakeWalletId',
493
+ walletContractAddress: 'fakeWalletContractAddress',
494
+ };
495
+ const verification = {};
496
+ await coin
497
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
498
+ .should.be.rejectedWith('recipient address of txPrebuild does not match batcher address');
499
+ });
500
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
501
+ const coin = bitgo.coin('teth');
502
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
503
+ const txParams = {
504
+ recipients: [{ amount: '1000000000000', address: address1 }],
505
+ wallet: wallet,
506
+ walletPassphrase: 'fakeWalletPassphrase',
507
+ };
508
+ const txPrebuild = {
509
+ recipients: [{ amount: '2000000000000', address: address1 }],
510
+ nextContractSequenceId: 0,
511
+ gasPrice: 20000000000,
512
+ gasLimit: 500000,
513
+ isBatch: false,
514
+ coin: 'teth',
515
+ walletId: 'fakeWalletId',
516
+ walletContractAddress: 'fakeWalletContractAddress',
517
+ };
518
+ const verification = {};
519
+ await coin
520
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
521
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
522
+ });
523
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
524
+ const coin = bitgo.coin('teth');
525
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
526
+ const txParams = {
527
+ recipients: [{ amount: '1000000000000', address: address1 }],
528
+ wallet: wallet,
529
+ walletPassphrase: 'fakeWalletPassphrase',
530
+ };
531
+ const txPrebuild = {
532
+ recipients: [{ amount: '1000000000000', address: address2 }],
533
+ nextContractSequenceId: 0,
534
+ gasPrice: 20000000000,
535
+ gasLimit: 500000,
536
+ isBatch: false,
537
+ coin: 'teth',
538
+ walletId: 'fakeWalletId',
539
+ walletContractAddress: 'fakeWalletContractAddress',
540
+ };
541
+ const verification = {};
542
+ await coin
543
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
544
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
545
+ });
546
+ it('should verify a token txPrebuild from the bitgo server that matches the client txParams', async function () {
547
+ const coin = bitgo.coin('test');
548
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
549
+ const txParams = {
550
+ recipients: [{ amount: '1000000000000', address: address1 }],
551
+ wallet: wallet,
552
+ walletPassphrase: 'fakeWalletPassphrase',
553
+ };
554
+ const txPrebuild = {
555
+ recipients: [{ amount: '1000000000000', address: address1 }],
556
+ nextContractSequenceId: 0,
557
+ gasPrice: 20000000000,
558
+ gasLimit: 500000,
559
+ isBatch: false,
560
+ coin: 'teth',
561
+ token: 'test',
562
+ walletId: 'fakeWalletId',
563
+ walletContractAddress: 'fakeWalletContractAddress',
564
+ };
565
+ const verification = {};
566
+ const isTransactionVerified = await coin.verifyTransaction({
567
+ txParams,
568
+ txPrebuild: txPrebuild,
569
+ wallet,
570
+ verification,
571
+ });
572
+ isTransactionVerified.should.equal(true);
573
+ });
574
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
575
+ const coin = bitgo.coin('teth');
576
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
577
+ const txParams = {
578
+ recipients: [{ amount: '1000000000000', address: address1 }],
579
+ wallet: wallet,
580
+ walletPassphrase: 'fakeWalletPassphrase',
581
+ };
582
+ const txPrebuild = {
583
+ recipients: [{ amount: '1000000000000', address: address1 }],
584
+ nextContractSequenceId: 0,
585
+ gasPrice: 20000000000,
586
+ gasLimit: 500000,
587
+ isBatch: false,
588
+ coin: 'btc',
589
+ walletId: 'fakeWalletId',
590
+ walletContractAddress: 'fakeWalletContractAddress',
591
+ };
592
+ const verification = {};
593
+ await coin
594
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
595
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
596
+ });
597
+ });
598
+ describe('TSS Transaction Verification', function () {
599
+ const expectDefiRejection = async (p, messagePattern) => {
600
+ try {
601
+ await p;
602
+ }
603
+ catch (err) {
604
+ err.should.be.instanceOf(sdk_core_1.TxIntentMismatchRecipientError);
605
+ err.message.should.match(messagePattern);
606
+ return;
607
+ }
608
+ throw new Error('expected verifyTransaction to be rejected, but it resolved');
609
+ };
610
+ it('should verify TSS consolidation transaction when txPrebuild has consolidateId', async function () {
611
+ const coin = bitgo.coin('hteth');
612
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
613
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
614
+ coinSpecific: {
615
+ baseAddress: baseAddress,
616
+ },
617
+ });
618
+ // txParams without recipients (as in consolidation flow)
619
+ const txParams = {
620
+ wallet: wallet,
621
+ walletPassphrase: 'fakeWalletPassphrase',
622
+ };
623
+ // txPrebuild with consolidateId (set by server during consolidation build)
624
+ const txPrebuild = {
625
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
626
+ txHex: '0x',
627
+ coin: 'hteth',
628
+ walletId: 'fakeWalletId',
629
+ };
630
+ const verification = {};
631
+ const isTransactionVerified = await coin.verifyTransaction({
632
+ txParams: txParams,
633
+ txPrebuild: txPrebuild,
634
+ wallet,
635
+ verification,
636
+ walletType: 'tss',
637
+ });
638
+ isTransactionVerified.should.equal(true);
639
+ });
640
+ it('should verify TSS transaction when txParams.type is consolidate', async function () {
641
+ const coin = bitgo.coin('hteth');
642
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
643
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
644
+ coinSpecific: {
645
+ baseAddress: baseAddress,
646
+ },
647
+ });
648
+ const txParams = {
649
+ type: 'consolidate',
650
+ wallet: wallet,
651
+ walletPassphrase: 'fakeWalletPassphrase',
652
+ };
653
+ const txPrebuild = {
654
+ txHex: '0x',
655
+ coin: 'hteth',
656
+ walletId: 'fakeWalletId',
657
+ };
658
+ const verification = {};
659
+ const isTransactionVerified = await coin.verifyTransaction({
660
+ txParams: txParams,
661
+ txPrebuild: txPrebuild,
662
+ wallet,
663
+ verification,
664
+ walletType: 'tss',
665
+ });
666
+ isTransactionVerified.should.equal(true);
667
+ });
668
+ it('should verify TSS transaction when txParams.prebuildTx has consolidateId', async function () {
669
+ const coin = bitgo.coin('hteth');
670
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
671
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
672
+ coinSpecific: {
673
+ baseAddress: baseAddress,
674
+ },
675
+ });
676
+ const txParams = {
677
+ wallet: wallet,
678
+ walletPassphrase: 'fakeWalletPassphrase',
679
+ prebuildTx: {
680
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
681
+ },
682
+ };
683
+ const txPrebuild = {
684
+ txHex: '0x',
685
+ coin: 'hteth',
686
+ walletId: 'fakeWalletId',
687
+ };
688
+ const verification = {};
689
+ const isTransactionVerified = await coin.verifyTransaction({
690
+ txParams: txParams,
691
+ txPrebuild: txPrebuild,
692
+ wallet,
693
+ verification,
694
+ walletType: 'tss',
695
+ });
696
+ isTransactionVerified.should.equal(true);
697
+ });
698
+ it('should reject TSS transaction without recipients, consolidateId, or valid type', async function () {
699
+ const coin = bitgo.coin('hteth');
700
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
701
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
702
+ coinSpecific: {
703
+ baseAddress: baseAddress,
704
+ },
705
+ });
706
+ const txParams = {
707
+ wallet: wallet,
708
+ walletPassphrase: 'fakeWalletPassphrase',
709
+ };
710
+ const txPrebuild = {
711
+ txHex: '0x',
712
+ coin: 'hteth',
713
+ walletId: 'fakeWalletId',
714
+ };
715
+ const verification = {};
716
+ await coin
717
+ .verifyTransaction({
718
+ txParams: txParams,
719
+ txPrebuild: txPrebuild,
720
+ wallet,
721
+ verification,
722
+ walletType: 'tss',
723
+ })
724
+ .should.be.rejectedWith('missing txParams');
725
+ });
726
+ it('should verify TSS transaction with acceleration type', async function () {
727
+ const coin = bitgo.coin('hteth');
728
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
729
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
730
+ coinSpecific: {
731
+ baseAddress: baseAddress,
732
+ },
733
+ });
734
+ const txParams = {
735
+ type: 'acceleration',
736
+ wallet: wallet,
737
+ walletPassphrase: 'fakeWalletPassphrase',
738
+ };
739
+ const txPrebuild = {
740
+ txHex: '0x',
741
+ coin: 'hteth',
742
+ walletId: 'fakeWalletId',
743
+ };
744
+ const verification = {};
745
+ const isTransactionVerified = await coin.verifyTransaction({
746
+ txParams: txParams,
747
+ txPrebuild: txPrebuild,
748
+ wallet,
749
+ verification,
750
+ walletType: 'tss',
751
+ });
752
+ isTransactionVerified.should.equal(true);
753
+ });
754
+ it('should verify TSS transaction with fillNonce type', async function () {
755
+ const coin = bitgo.coin('hteth');
756
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
757
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
758
+ coinSpecific: {
759
+ baseAddress: baseAddress,
760
+ },
761
+ });
762
+ const txParams = {
763
+ type: 'fillNonce',
764
+ wallet: wallet,
765
+ walletPassphrase: 'fakeWalletPassphrase',
766
+ };
767
+ const txPrebuild = {
768
+ txHex: '0x',
769
+ coin: 'hteth',
770
+ walletId: 'fakeWalletId',
771
+ };
772
+ const verification = {};
773
+ const isTransactionVerified = await coin.verifyTransaction({
774
+ txParams: txParams,
775
+ txPrebuild: txPrebuild,
776
+ wallet,
777
+ verification,
778
+ walletType: 'tss',
779
+ });
780
+ isTransactionVerified.should.equal(true);
781
+ });
782
+ it('should verify TSS transaction with defiApprove type', async function () {
783
+ const coin = bitgo.coin('hteth');
784
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
785
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
786
+ coinSpecific: {
787
+ baseAddress: baseAddress,
788
+ },
789
+ });
790
+ // DeFi deposit flow is intent-based: recipients/calldata are built server-side
791
+ // from defiParams, so txParams has no recipients (see CGD-1815).
792
+ const txParams = {
793
+ type: 'defiApprove',
794
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10' },
795
+ wallet: wallet,
796
+ walletPassphrase: 'fakeWalletPassphrase',
797
+ };
798
+ const txPrebuild = {
799
+ txHex: await buildDefiTxHex(defiCalldata('approve(address,uint256)', [address1, '10'])),
800
+ coin: 'hteth',
801
+ walletId: 'fakeWalletId',
802
+ };
803
+ const verification = {};
804
+ const isTransactionVerified = await coin.verifyTransaction({
805
+ txParams: txParams,
806
+ txPrebuild: txPrebuild,
807
+ wallet,
808
+ verification,
809
+ walletType: 'tss',
810
+ });
811
+ isTransactionVerified.should.equal(true);
812
+ });
813
+ it('should verify TSS transaction with wrapApprove type and no recipients', async function () {
814
+ const coin = bitgo.coin('hteth');
815
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
816
+ coinSpecific: {
817
+ baseAddress: '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be',
818
+ },
819
+ });
820
+ // WP derives the underlying token contract, wrapper spender, and approve
821
+ // calldata from tokenName and amount, so the client intent has no recipients.
822
+ const txParams = {
823
+ type: 'wrapApprove',
824
+ tokenName: 'hteth:cusdt',
825
+ amount: '1000000',
826
+ };
827
+ const txPrebuild = {
828
+ txHex: '0x',
829
+ coin: 'hteth',
830
+ walletId: 'fakeWalletId',
831
+ };
832
+ const isTransactionVerified = await coin.verifyTransaction({
833
+ txParams: txParams,
834
+ txPrebuild: txPrebuild,
835
+ wallet,
836
+ verification: {},
837
+ walletType: 'tss',
838
+ });
839
+ isTransactionVerified.should.equal(true);
840
+ });
841
+ it('should verify TSS transaction with defiDeposit type', async function () {
842
+ const coin = bitgo.coin('hteth');
843
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
844
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
845
+ coinSpecific: {
846
+ baseAddress: baseAddress,
847
+ },
848
+ });
849
+ const txParams = {
850
+ type: 'defiDeposit',
851
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10', operationId: 'fakeOperationId' },
852
+ wallet: wallet,
853
+ walletPassphrase: 'fakeWalletPassphrase',
854
+ };
855
+ const txPrebuild = {
856
+ txHex: await buildDefiTxHex(defiCalldata('deposit(uint256,address)', ['10', address1])),
857
+ coin: 'hteth',
858
+ walletId: 'fakeWalletId',
859
+ };
860
+ const verification = {};
861
+ const isTransactionVerified = await coin.verifyTransaction({
862
+ txParams: txParams,
863
+ txPrebuild: txPrebuild,
864
+ wallet,
865
+ verification,
866
+ walletType: 'tss',
867
+ });
868
+ isTransactionVerified.should.equal(true);
869
+ });
870
+ it('should reject DeFi calldata that redirects funds or grants excess approval', async function () {
871
+ const coin = bitgo.coin('hteth');
872
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
873
+ const verify = async (type, defiParams, data) => coin.verifyTransaction({
874
+ txParams: { type, defiParams, wallet },
875
+ txPrebuild: { txHex: await buildDefiTxHex(data), coin: 'hteth', walletId: 'fakeWalletId' },
876
+ wallet,
877
+ verification: {},
878
+ walletType: 'tss',
879
+ });
880
+ // defiApprove: attacker approve(attacker, MAX_UINT256) disguised as defiApprove
881
+ await expectDefiRejection(verify('defiApprove', { vaultId: 'vault', amount: '10' }, defiCalldata('approve(address,uint256)', [address2, '1000000000000000000'])), /amount does not match/);
882
+ // defiDeposit: funds redirected to attacker receiver
883
+ await expectDefiRejection(verify('defiDeposit', { vaultId: 'vault', amount: '10' }, defiCalldata('deposit(uint256,address)', ['10', address2])), /receiver does not match/);
884
+ // defiWithdraw: receiver and owner both attacker
885
+ await expectDefiRejection(verify('defiWithdraw', { vaultId: 'vault', amount: '10' }, defiCalldata('redeem(uint256,address,address)', ['5', address2, address2])), /receiver and owner/);
886
+ });
887
+ it('should reject DeFi calldata with wrong selector, wrong owner alone, or wrong deposit amount', async function () {
888
+ const coin = bitgo.coin('hteth');
889
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
890
+ const verify = async (type, defiParams, data) => coin.verifyTransaction({
891
+ txParams: { type, defiParams, wallet },
892
+ txPrebuild: { txHex: await buildDefiTxHex(data), coin: 'hteth', walletId: 'fakeWalletId' },
893
+ wallet,
894
+ verification: {},
895
+ walletType: 'tss',
896
+ });
897
+ const defiParams = { vaultId: 'vault', amount: '10' };
898
+ // defiApprove with a non-approve selector (transfer disguised as approve)
899
+ await expectDefiRejection(verify('defiApprove', defiParams, defiCalldata('transfer(address,uint256)', [address2, '10'])), /approve\(address,uint256\)/);
900
+ // defiDeposit with a non-deposit selector
901
+ await expectDefiRejection(verify('defiDeposit', defiParams, defiCalldata('approve(address,uint256)', [address1, '10'])), /deposit\(uint256,address\)/);
902
+ // defiWithdraw with a non-redeem selector
903
+ await expectDefiRejection(verify('defiWithdraw', defiParams, defiCalldata('approve(address,uint256)', [address1, '10'])), /redeem\(uint256,address,address\)/);
904
+ // defiWithdraw: receiver ok but owner is attacker
905
+ await expectDefiRejection(verify('defiWithdraw', defiParams, defiCalldata('redeem(uint256,address,address)', ['10', address1, address2])), /receiver and owner/);
906
+ // defiWithdraw: receiver and owner ok but shares do not match defiParams.amount
907
+ await expectDefiRejection(verify('defiWithdraw', defiParams, defiCalldata('redeem(uint256,address,address)', ['999', address1, address1])), /shares do not match/);
908
+ // defiDeposit: receiver ok but amount mismatch
909
+ await expectDefiRejection(verify('defiDeposit', defiParams, defiCalldata('deposit(uint256,address)', ['999', address1])), /amount does not match/);
910
+ });
911
+ it('should fail closed when defi intent parameters are missing or calldata is short', async function () {
912
+ const coin = bitgo.coin('hteth');
913
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
914
+ const verify = async (type, defiParams, data) => coin.verifyTransaction({
915
+ txParams: { type, defiParams, wallet },
916
+ txPrebuild: { txHex: await buildDefiTxHex(data), coin: 'hteth', walletId: 'fakeWalletId' },
917
+ wallet,
918
+ verification: {},
919
+ walletType: 'tss',
920
+ });
921
+ // Missing defiParams for each defi type -> fail closed
922
+ await expectDefiRejection(verify('defiApprove', undefined, defiCalldata('approve(address,uint256)', [address1, '10'])), /missing required intent parameters/);
923
+ await expectDefiRejection(verify('defiDeposit', undefined, defiCalldata('deposit(uint256,address)', ['10', address1])), /missing required intent parameters/);
924
+ await expectDefiRejection(verify('defiWithdraw', undefined, defiCalldata('redeem(uint256,address,address)', ['5', address1, address1])), /missing required intent parameters/);
925
+ // Short/empty calldata with no valid selector prefix -> selector mismatch (fail closed)
926
+ await expectDefiRejection(verify('defiApprove', { vaultId: 'vault', amount: '10' }, '0x'), /approve\(address,uint256\)/);
927
+ });
928
+ it('should verify TSS transaction with defiWithdraw type', async function () {
929
+ const coin = bitgo.coin('hteth');
930
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, { coinSpecific: { baseAddress: address1 } });
931
+ const txParams = {
932
+ type: 'defiWithdraw',
933
+ defiParams: { vaultId: 'hteth-usdc-test', amount: '10' },
934
+ wallet,
935
+ };
936
+ const txPrebuild = {
937
+ txHex: await buildDefiTxHex(defiCalldata('redeem(uint256,address,address)', ['10', address1, address1])),
938
+ coin: 'hteth',
939
+ walletId: 'fakeWalletId',
940
+ };
941
+ const isTransactionVerified = await coin.verifyTransaction({
942
+ txParams: txParams,
943
+ txPrebuild: txPrebuild,
944
+ wallet,
945
+ verification: {},
946
+ walletType: 'tss',
947
+ });
948
+ isTransactionVerified.should.equal(true);
949
+ });
950
+ describe('consolidationToBaseAddress verification', function () {
951
+ it('should verify consolidation when recipient matches base address', async function () {
952
+ const coin = bitgo.coin('hteth');
953
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
954
+ // Build a real transaction that sends to the baseAddress
955
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
956
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
957
+ txBuilder.fee({
958
+ fee: '10',
959
+ gasLimit: '21000',
960
+ });
961
+ txBuilder.counter(1);
962
+ txBuilder.contract(baseAddress);
963
+ txBuilder.value('1000000000000000000');
964
+ const tx = await txBuilder.build();
965
+ const txHex = tx.toBroadcastFormat();
966
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
967
+ coinSpecific: {
968
+ baseAddress: baseAddress,
969
+ },
970
+ });
971
+ const txParams = {
972
+ type: 'consolidate',
973
+ wallet: wallet,
974
+ walletPassphrase: 'fakeWalletPassphrase',
975
+ };
976
+ const txPrebuild = {
977
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
978
+ txHex: txHex,
979
+ coin: 'hteth',
980
+ walletId: 'fakeWalletId',
981
+ };
982
+ const verification = {
983
+ consolidationToBaseAddress: true,
984
+ };
985
+ const isTransactionVerified = await coin.verifyTransaction({
986
+ txParams: txParams,
987
+ txPrebuild: txPrebuild,
988
+ wallet,
989
+ verification,
990
+ walletType: 'tss',
991
+ });
992
+ isTransactionVerified.should.equal(true);
993
+ });
994
+ it('should reject consolidation when recipient does not match base address', async function () {
995
+ const coin = bitgo.coin('hteth');
996
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
997
+ const wrongRecipient = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
998
+ // Build a transaction that sends to a DIFFERENT address (not baseAddress)
999
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1000
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
1001
+ txBuilder.fee({
1002
+ fee: '10',
1003
+ gasLimit: '21000',
1004
+ });
1005
+ txBuilder.counter(1);
1006
+ txBuilder.contract(wrongRecipient);
1007
+ txBuilder.value('1000000000000000000');
1008
+ const tx = await txBuilder.build();
1009
+ const txHex = tx.toBroadcastFormat();
1010
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1011
+ coinSpecific: {
1012
+ baseAddress: baseAddress,
1013
+ },
1014
+ });
1015
+ const txParams = {
1016
+ type: 'consolidate',
1017
+ wallet: wallet,
1018
+ walletPassphrase: 'fakeWalletPassphrase',
1019
+ };
1020
+ const txPrebuild = {
1021
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1022
+ txHex: txHex,
1023
+ coin: 'hteth',
1024
+ walletId: 'fakeWalletId',
1025
+ };
1026
+ const verification = {
1027
+ consolidationToBaseAddress: true,
1028
+ };
1029
+ await coin
1030
+ .verifyTransaction({
1031
+ txParams: txParams,
1032
+ txPrebuild: txPrebuild,
1033
+ wallet,
1034
+ verification,
1035
+ walletType: 'tss',
1036
+ })
1037
+ .should.be.rejectedWith('Consolidation transaction recipient does not match wallet base address');
1038
+ });
1039
+ it('should throw error when txHex is missing for consolidation verification', async function () {
1040
+ const coin = bitgo.coin('hteth');
1041
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1042
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1043
+ coinSpecific: {
1044
+ baseAddress: baseAddress,
1045
+ },
1046
+ });
1047
+ const txParams = {
1048
+ type: 'consolidate',
1049
+ wallet: wallet,
1050
+ walletPassphrase: 'fakeWalletPassphrase',
1051
+ };
1052
+ const txPrebuild = {
1053
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1054
+ // Intentionally missing txHex
1055
+ coin: 'hteth',
1056
+ walletId: 'fakeWalletId',
1057
+ };
1058
+ const verification = {
1059
+ consolidationToBaseAddress: true,
1060
+ };
1061
+ await coin
1062
+ .verifyTransaction({
1063
+ txParams: txParams,
1064
+ txPrebuild: txPrebuild,
1065
+ wallet,
1066
+ verification,
1067
+ walletType: 'tss',
1068
+ })
1069
+ .should.be.rejectedWith('missing txHex in txPrebuild');
1070
+ });
1071
+ it('should verify ERC20 token consolidation when calldata recipient matches base address', async function () {
1072
+ const coin = bitgo.coin('hteth');
1073
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1074
+ const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
1075
+ // Build an ERC20 transfer(address, uint256) tx — mimics what the server returns
1076
+ // for a v6 TSS wallet token consolidation: txJson.to = token contract,
1077
+ // actual recipient is encoded in the 0xa9059cbb calldata
1078
+ const methodId = ethereumjs_abi_1.default.methodID('transfer', ['address', 'uint256']);
1079
+ const encodedParams = ethereumjs_abi_1.default.rawEncode(['address', 'uint256'], [baseAddress, '10000000']);
1080
+ const erc20TransferData = '0x' + Buffer.concat([methodId, encodedParams]).toString('hex');
1081
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1082
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
1083
+ txBuilder.fee({ fee: '10', gasLimit: '60000' });
1084
+ txBuilder.counter(1);
1085
+ txBuilder.contract(tokenContractAddress);
1086
+ txBuilder.data(erc20TransferData);
1087
+ const tx = await txBuilder.build();
1088
+ const txHex = tx.toBroadcastFormat();
1089
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1090
+ coinSpecific: { baseAddress },
1091
+ });
1092
+ const isTransactionVerified = await coin.verifyTransaction({
1093
+ txParams: { type: 'consolidate', wallet, walletPassphrase: 'fake' },
1094
+ txPrebuild: { consolidateId: 'abc123', txHex, coin: 'hteth', walletId: 'fakeWalletId' },
1095
+ wallet,
1096
+ verification: { consolidationToBaseAddress: true },
1097
+ walletType: 'tss',
1098
+ });
1099
+ isTransactionVerified.should.equal(true);
1100
+ });
1101
+ it('should reject ERC20 token consolidation when calldata recipient does not match base address', async function () {
1102
+ const coin = bitgo.coin('hteth');
1103
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1104
+ const wrongRecipient = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
1105
+ const tokenContractAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
1106
+ // Build an ERC20 transfer where calldata recipient is a WRONG address
1107
+ const methodId = ethereumjs_abi_1.default.methodID('transfer', ['address', 'uint256']);
1108
+ const encodedParams = ethereumjs_abi_1.default.rawEncode(['address', 'uint256'], [wrongRecipient, '10000000']);
1109
+ const erc20TransferData = '0x' + Buffer.concat([methodId, encodedParams]).toString('hex');
1110
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1111
+ txBuilder.type(sdk_core_1.TransactionType.ContractCall);
1112
+ txBuilder.fee({ fee: '10', gasLimit: '60000' });
1113
+ txBuilder.counter(1);
1114
+ txBuilder.contract(tokenContractAddress);
1115
+ txBuilder.data(erc20TransferData);
1116
+ const tx = await txBuilder.build();
1117
+ const txHex = tx.toBroadcastFormat();
1118
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1119
+ coinSpecific: { baseAddress },
1120
+ });
1121
+ await coin
1122
+ .verifyTransaction({
1123
+ txParams: { type: 'consolidate', wallet, walletPassphrase: 'fake' },
1124
+ txPrebuild: { consolidateId: 'abc123', txHex, coin: 'hteth', walletId: 'fakeWalletId' },
1125
+ wallet,
1126
+ verification: { consolidationToBaseAddress: true },
1127
+ walletType: 'tss',
1128
+ })
1129
+ .should.be.rejectedWith('Consolidation transaction recipient does not match wallet base address');
1130
+ });
1131
+ it('should throw error when wallet is missing baseAddress for consolidation verification', async function () {
1132
+ const coin = bitgo.coin('hteth');
1133
+ const baseAddress = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
1134
+ // Build a real transaction
1135
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
1136
+ txBuilder.type(sdk_core_1.TransactionType.SingleSigSend);
1137
+ txBuilder.fee({
1138
+ fee: '10',
1139
+ gasLimit: '21000',
1140
+ });
1141
+ txBuilder.counter(1);
1142
+ txBuilder.contract(baseAddress);
1143
+ txBuilder.value('1000000000000000000');
1144
+ const tx = await txBuilder.build();
1145
+ const txHex = tx.toBroadcastFormat();
1146
+ // Wallet without baseAddress
1147
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {
1148
+ coinSpecific: {},
1149
+ });
1150
+ const txParams = {
1151
+ type: 'consolidate',
1152
+ wallet: wallet,
1153
+ walletPassphrase: 'fakeWalletPassphrase',
1154
+ };
1155
+ const txPrebuild = {
1156
+ consolidateId: '68a7d5d0c66e74e216b97173bd558c6d',
1157
+ txHex: txHex,
1158
+ coin: 'hteth',
1159
+ walletId: 'fakeWalletId',
1160
+ };
1161
+ const verification = {
1162
+ consolidationToBaseAddress: true,
1163
+ };
1164
+ await coin
1165
+ .verifyTransaction({
1166
+ txParams: txParams,
1167
+ txPrebuild: txPrebuild,
1168
+ wallet,
1169
+ verification,
1170
+ walletType: 'tss',
1171
+ })
1172
+ .should.be.rejectedWith('Unable to determine base address for consolidation');
1173
+ });
1174
+ });
1175
+ });
1176
+ describe('Address Verification', function () {
1177
+ describe('isWalletAddress', function () {
1178
+ it('should verify an address generated using forwarder version 1', async function () {
1179
+ const coin = bitgo.coin('hteth');
1180
+ const keychains = [
1181
+ {
1182
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
1183
+ source: 'user',
1184
+ type: 'independent',
1185
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVmsa5SriNrfKZZAcAvRgxh1Augm6s8yoD8gSkq2FdZ8YCdVXUgLjf9QxvdYAJK5UthAmpQshU',
1186
+ },
1187
+ {
1188
+ id: '691f638f0b74e73b1f440ea4aceda87e',
1189
+ source: 'backup',
1190
+ type: 'independent',
1191
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqAU9JRod8huYtyV4NY2oeJXsis7r26L1vmLntf9BcZJe1m4CQNSvYWfwpe1hSpo6J4x6YF1eN',
1192
+ },
1193
+ {
1194
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1195
+ source: 'bitgo',
1196
+ type: 'independent',
1197
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1198
+ },
1199
+ ];
1200
+ const params = {
1201
+ address: '0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae',
1202
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
1203
+ coinSpecific: {
1204
+ salt: '0x7',
1205
+ forwarderVersion: 1,
1206
+ },
1207
+ keychains,
1208
+ index: 7,
1209
+ walletVersion: 1,
1210
+ };
1211
+ const isWalletAddr = await coin.isWalletAddress(params);
1212
+ isWalletAddr.should.equal(true);
1213
+ });
1214
+ it('should verify an address generated using forwarder version 2', async function () {
1215
+ const coin = bitgo.coin('hteth');
1216
+ const keychains = [
1217
+ {
1218
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
1219
+ source: 'user',
1220
+ type: 'independent',
1221
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
1222
+ },
1223
+ {
1224
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
1225
+ source: 'backup',
1226
+ type: 'independent',
1227
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
1228
+ },
1229
+ {
1230
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1231
+ source: 'bitgo',
1232
+ type: 'independent',
1233
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1234
+ },
1235
+ ];
1236
+ const params = {
1237
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
1238
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1239
+ coinSpecific: {
1240
+ salt: '0x17',
1241
+ forwarderVersion: 2,
1242
+ },
1243
+ keychains,
1244
+ index: 23,
1245
+ walletVersion: 2,
1246
+ };
1247
+ const isWalletAddr = await coin.isWalletAddress(params);
1248
+ isWalletAddr.should.equal(true);
1249
+ });
1250
+ it('should verify a wallet version 5 forwarder version 4', async function () {
1251
+ const coin = bitgo.coin('hteth');
1252
+ const keychains = [
1253
+ {
1254
+ id: '691e242d93f8d7ad0705887449763c96',
1255
+ source: 'user',
1256
+ type: 'tss',
1257
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1258
+ },
1259
+ {
1260
+ id: '691e242df8b6323d4b08df366864af66',
1261
+ source: 'backup',
1262
+ type: 'tss',
1263
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1264
+ },
1265
+ {
1266
+ id: '691e242c0595b4cfee6f957c1d6458f7',
1267
+ source: 'bitgo',
1268
+ type: 'tss',
1269
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1270
+ },
1271
+ ];
1272
+ const params = {
1273
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
1274
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1275
+ coinSpecific: {
1276
+ salt: '0x75',
1277
+ forwarderVersion: 4,
1278
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1279
+ },
1280
+ keychains,
1281
+ index: 117,
1282
+ walletVersion: 5,
1283
+ };
1284
+ const isWalletAddr = await coin.isWalletAddress(params);
1285
+ isWalletAddr.should.equal(true);
1286
+ });
1287
+ it('should verify a wallet version 6 forwarder version 5', async function () {
1288
+ const coin = bitgo.coin('hteth');
1289
+ const keychains = [
1290
+ {
1291
+ id: '691f630e0c56098288a9b7fa107db144',
1292
+ source: 'user',
1293
+ type: 'tss',
1294
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1295
+ },
1296
+ {
1297
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1298
+ source: 'backup',
1299
+ type: 'tss',
1300
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1301
+ },
1302
+ {
1303
+ id: '691f630d56735e5eb61b06e353fe7639',
1304
+ source: 'bitgo',
1305
+ type: 'tss',
1306
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1307
+ },
1308
+ ];
1309
+ const params = {
1310
+ address: '0xa33f0975f53cdcfcc0cb564d25fb5be03b0651cf',
1311
+ baseAddress: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1312
+ coinSpecific: {
1313
+ forwarderVersion: 5,
1314
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1315
+ },
1316
+ keychains,
1317
+ index: 7,
1318
+ walletVersion: 6,
1319
+ };
1320
+ const isWalletAddr = await coin.isWalletAddress(params);
1321
+ isWalletAddr.should.equal(true);
1322
+ });
1323
+ it('should reject when actual address differs from expected address', async function () {
1324
+ const coin = bitgo.coin('hteth');
1325
+ const params = {
1326
+ address: '0x28904591f735994f050804fda3b61b813b16e04c',
1327
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1328
+ walletVersion: 1,
1329
+ coinSpecific: {
1330
+ salt: '0xc5a',
1331
+ forwarderVersion: 1,
1332
+ },
1333
+ };
1334
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.UnexpectedAddressError);
1335
+ });
1336
+ it('should reject if coinSpecific field is not an object', async function () {
1337
+ const coin = bitgo.coin('teth');
1338
+ const params = {
1339
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1340
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1341
+ };
1342
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressVerificationObjectPropertyError);
1343
+ });
1344
+ it('should reject if the derived address is in invalid format', async function () {
1345
+ const coin = bitgo.coin('teth');
1346
+ const params = {
1347
+ address: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
1348
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1349
+ coinSpecific: {
1350
+ salt: '0xc5a',
1351
+ forwarderVersion: 1,
1352
+ },
1353
+ };
1354
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1355
+ });
1356
+ it('should reject if base address is undefined', async function () {
1357
+ const coin = bitgo.coin('teth');
1358
+ const params = {
1359
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1360
+ coinSpecific: {
1361
+ salt: '0xc5a',
1362
+ forwarderVersion: 1,
1363
+ },
1364
+ };
1365
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1366
+ });
1367
+ it('should reject if base address is in invalid format', async function () {
1368
+ const coin = bitgo.coin('teth');
1369
+ const params = {
1370
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
1371
+ baseAddress: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
1372
+ coinSpecific: {
1373
+ salt: '0xc5a',
1374
+ forwarderVersion: 1,
1375
+ },
1376
+ };
1377
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1378
+ });
1379
+ describe('MPC wallet addresses', function () {
1380
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
1381
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
1382
+ const keychains = [
1383
+ { pub: 'user_pub', commonKeychain },
1384
+ { pub: 'backup_pub', commonKeychain },
1385
+ { pub: 'bitgo_pub', commonKeychain },
1386
+ ];
1387
+ it('should verify an MPC wallet address with forwarder version 3', async function () {
1388
+ const coin = bitgo.coin('teth');
1389
+ const params = {
1390
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
1391
+ coinSpecific: {
1392
+ forwarderVersion: 3,
1393
+ },
1394
+ keychains,
1395
+ index: 0,
1396
+ walletVersion: 3,
1397
+ };
1398
+ const isWalletAddr = await coin.isWalletAddress(params);
1399
+ isWalletAddr.should.equal(true);
1400
+ });
1401
+ it('should verify an MPC wallet address with forwarder version 5', async function () {
1402
+ const coin = bitgo.coin('teth');
1403
+ const params = {
1404
+ address: '0x01153f3adfe454a72589ca9ef74f013c19e54961',
1405
+ coinSpecific: {
1406
+ forwarderVersion: 5,
1407
+ },
1408
+ keychains,
1409
+ index: 0,
1410
+ walletVersion: 6,
1411
+ };
1412
+ const isWalletAddr = await coin.isWalletAddress(params);
1413
+ isWalletAddr.should.equal(true);
1414
+ });
1415
+ it('should reject MPC wallet address with wrong address', async function () {
1416
+ const coin = bitgo.coin('teth');
1417
+ const params = {
1418
+ address: '0x0000000000000000000000000000000000000001',
1419
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1420
+ coinSpecific: {
1421
+ forwarderVersion: 3,
1422
+ },
1423
+ keychains,
1424
+ index: 0,
1425
+ walletVersion: 3,
1426
+ };
1427
+ const isWalletAddr = await coin.isWalletAddress(params);
1428
+ isWalletAddr.should.equal(false);
1429
+ });
1430
+ it('should reject MPC wallet address with invalid address format', async function () {
1431
+ const coin = bitgo.coin('teth');
1432
+ const params = {
1433
+ address: '0xinvalid',
1434
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1435
+ coinSpecific: {
1436
+ forwarderVersion: 3,
1437
+ },
1438
+ keychains,
1439
+ index: 0,
1440
+ walletVersion: 3,
1441
+ };
1442
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), sdk_core_1.InvalidAddressError);
1443
+ });
1444
+ it('should reject if keychains are missing for MPC wallet', async function () {
1445
+ const coin = bitgo.coin('teth');
1446
+ const params = {
1447
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
1448
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1449
+ coinSpecific: {
1450
+ forwarderVersion: 3,
1451
+ },
1452
+ index: 0,
1453
+ walletVersion: 3,
1454
+ };
1455
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
1456
+ });
1457
+ it('should reject if commonKeychain is missing for MPC wallet', async function () {
1458
+ const coin = bitgo.coin('teth');
1459
+ const invalidKeychains = [{ pub: 'user_pub' }, { pub: 'backup_pub' }, { pub: 'bitgo_pub' }];
1460
+ const params = {
1461
+ address: '0x9e7ce8c24d9f76a814e23633e61be7cb8e6e2d5e',
1462
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1463
+ coinSpecific: {
1464
+ forwarderVersion: 3,
1465
+ },
1466
+ keychains: invalidKeychains,
1467
+ index: 0,
1468
+ walletVersion: 3,
1469
+ };
1470
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), Error);
1471
+ });
1472
+ });
1473
+ describe('deriveAddress (MPC)', function () {
1474
+ // Same vector as the MPC isWalletAddress tests above:
1475
+ // commonKeychain @ index 0 -> 0x01153f3adfe454a72589ca9ef74f013c19e54961
1476
+ const commonKeychain = '03f9c2fb2e5a8b78a44f5d1e4f906f8e3d7a0e6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9e8d7c6b5a4' +
1477
+ '93827160594857463728190a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
1478
+ const keychains = [
1479
+ { pub: 'user_pub', commonKeychain },
1480
+ { pub: 'backup_pub', commonKeychain },
1481
+ { pub: 'bitgo_pub', commonKeychain },
1482
+ ];
1483
+ it('should derive the expected MPC address for a commonKeychain at index 0', async function () {
1484
+ const coin = bitgo.coin('teth');
1485
+ const result = await coin.deriveAddress({ keychains, index: 0, walletVersion: 3 });
1486
+ result.address.should.equal('0x01153f3adfe454a72589ca9ef74f013c19e54961');
1487
+ result.index.should.equal(0);
1488
+ assert_1.default.strictEqual(result.derivationPath, 'm/0');
1489
+ });
1490
+ it('round-trips with isWalletAddress (derived address verifies as true)', async function () {
1491
+ const coin = bitgo.coin('teth');
1492
+ const derived = await coin.deriveAddress({ keychains, index: 3, walletVersion: 6 });
1493
+ const verified = await coin.isWalletAddress({
1494
+ address: derived.address,
1495
+ coinSpecific: { forwarderVersion: 5 },
1496
+ keychains,
1497
+ index: 3,
1498
+ walletVersion: 6,
1499
+ });
1500
+ verified.should.equal(true);
1501
+ });
1502
+ it('should throw when neither MPC nor forwarder inputs are provided', async function () {
1503
+ const coin = bitgo.coin('teth');
1504
+ // walletVersion 1 with no coinSpecific.forwarderVersion and no baseAddress is ambiguous
1505
+ await assert_1.default.rejects(async () => coin.deriveAddress({ keychains, index: 0, walletVersion: 1 }), /could not determine an ETH derivation strategy/);
1506
+ });
1507
+ it('should throw if keychains are missing', async function () {
1508
+ const coin = bitgo.coin('teth');
1509
+ await assert_1.default.rejects(async () => coin.deriveAddress({ keychains: [], index: 0, walletVersion: 3 }), /keychains/);
1510
+ });
1511
+ });
1512
+ describe('deriveAddress (forwarder)', function () {
1513
+ // Same vectors as the forwarder isWalletAddress tests above (coin: hteth).
1514
+ // salt == index for BitGo forwarders, so deriving by index reproduces the address.
1515
+ it('derives the exact v1 forwarder address and round-trips', async function () {
1516
+ const coin = bitgo.coin('hteth');
1517
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
1518
+ const result = await coin.deriveAddress({
1519
+ baseAddress,
1520
+ index: 7,
1521
+ walletVersion: 1,
1522
+ coinSpecific: { forwarderVersion: 1 },
1523
+ });
1524
+ result.address.should.equal('0x6069a4baf2360bf67a6d02a7fc43d8f3910016ae');
1525
+ const verified = await coin.isWalletAddress({
1526
+ address: result.address,
1527
+ baseAddress,
1528
+ index: 7,
1529
+ walletVersion: 1,
1530
+ coinSpecific: { salt: '0x7', forwarderVersion: 1 },
1531
+ });
1532
+ verified.should.equal(true);
1533
+ });
1534
+ it('derives the exact v2 forwarder address', async function () {
1535
+ const coin = bitgo.coin('hteth');
1536
+ const result = await coin.deriveAddress({
1537
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1538
+ index: 23,
1539
+ walletVersion: 2,
1540
+ coinSpecific: { forwarderVersion: 2 },
1541
+ });
1542
+ result.address.should.equal('0xf636ceddffe41d106586875c0e56dc8feb6268f7');
1543
+ });
1544
+ it('derives the exact v4 forwarder address (wallet v5, needs feeAddress)', async function () {
1545
+ const coin = bitgo.coin('hteth');
1546
+ const result = await coin.deriveAddress({
1547
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1548
+ index: 117,
1549
+ walletVersion: 5,
1550
+ coinSpecific: { forwarderVersion: 4, feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09' },
1551
+ });
1552
+ result.address.should.equal('0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d');
1553
+ });
1554
+ it('throws if baseAddress is missing for a forwarder', async function () {
1555
+ const coin = bitgo.coin('hteth');
1556
+ await assert_1.default.rejects(async () => coin.deriveAddress({ index: 7, walletVersion: 1, coinSpecific: { forwarderVersion: 1 } }), /baseAddress is required/);
1557
+ });
1558
+ it('throws if feeAddress is missing for a v4 forwarder', async function () {
1559
+ const coin = bitgo.coin('hteth');
1560
+ await assert_1.default.rejects(async () => coin.deriveAddress({
1561
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1562
+ index: 117,
1563
+ walletVersion: 5,
1564
+ coinSpecific: { forwarderVersion: 4 },
1565
+ }), /feeAddress is required/);
1566
+ });
1567
+ it('throws for forwarder version 0 (not derivable)', async function () {
1568
+ const coin = bitgo.coin('hteth');
1569
+ await assert_1.default.rejects(async () => coin.deriveAddress({
1570
+ baseAddress: '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f',
1571
+ index: 0,
1572
+ walletVersion: 1,
1573
+ coinSpecific: { forwarderVersion: 0 },
1574
+ }), /version 0 addresses cannot be derived/);
1575
+ });
1576
+ });
1577
+ describe('Base Address Verification', function () {
1578
+ it('should verify base address for wallet version 6 (TSS)', async function () {
1579
+ const coin = bitgo.coin('hteth');
1580
+ const keychains = [
1581
+ {
1582
+ id: '691f630e0c56098288a9b7fa107db144',
1583
+ source: 'user',
1584
+ type: 'tss',
1585
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1586
+ },
1587
+ {
1588
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1589
+ source: 'backup',
1590
+ type: 'tss',
1591
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1592
+ },
1593
+ {
1594
+ id: '691f630d56735e5eb61b06e353fe7639',
1595
+ source: 'bitgo',
1596
+ type: 'tss',
1597
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1598
+ },
1599
+ ];
1600
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1601
+ const params = {
1602
+ address: baseAddress,
1603
+ baseAddress: baseAddress,
1604
+ coinSpecific: {
1605
+ salt: '0x0',
1606
+ forwarderVersion: 5,
1607
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1608
+ },
1609
+ keychains,
1610
+ index: 0,
1611
+ walletVersion: 6,
1612
+ };
1613
+ const isWalletAddr = await coin.isWalletAddress(params);
1614
+ isWalletAddr.should.equal(true);
1615
+ });
1616
+ it('should verify base address for wallet version 5 (TSS)', async function () {
1617
+ const coin = bitgo.coin('hteth');
1618
+ const keychains = [
1619
+ {
1620
+ id: '691e242d93f8d7ad0705887449763c96',
1621
+ source: 'user',
1622
+ type: 'tss',
1623
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1624
+ },
1625
+ {
1626
+ id: '691e242df8b6323d4b08df366864af66',
1627
+ source: 'backup',
1628
+ type: 'tss',
1629
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1630
+ },
1631
+ {
1632
+ id: '691e242c0595b4cfee6f957c1d6458f7',
1633
+ source: 'bitgo',
1634
+ type: 'tss',
1635
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1636
+ },
1637
+ ];
1638
+ const baseAddress = '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11';
1639
+ const params = {
1640
+ address: baseAddress,
1641
+ baseAddress: baseAddress,
1642
+ coinSpecific: {
1643
+ salt: '0x0',
1644
+ forwarderVersion: 4,
1645
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1646
+ },
1647
+ keychains,
1648
+ index: 0,
1649
+ walletVersion: 5,
1650
+ };
1651
+ const isWalletAddr = await coin.isWalletAddress(params);
1652
+ isWalletAddr.should.equal(true);
1653
+ });
1654
+ it('should reject base address verification with non-zero index', async function () {
1655
+ const coin = bitgo.coin('hteth');
1656
+ const keychains = [
1657
+ {
1658
+ id: '691f630e0c56098288a9b7fa107db144',
1659
+ source: 'user',
1660
+ type: 'tss',
1661
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1662
+ },
1663
+ {
1664
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1665
+ source: 'backup',
1666
+ type: 'tss',
1667
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1668
+ },
1669
+ {
1670
+ id: '691f630d56735e5eb61b06e353fe7639',
1671
+ source: 'bitgo',
1672
+ type: 'tss',
1673
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1674
+ },
1675
+ ];
1676
+ const baseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1677
+ const params = {
1678
+ address: baseAddress,
1679
+ baseAddress: baseAddress,
1680
+ coinSpecific: {
1681
+ salt: '0x0',
1682
+ forwarderVersion: 5,
1683
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1684
+ },
1685
+ keychains,
1686
+ index: 5, // Wrong index - should be 0 for base address
1687
+ walletVersion: 6,
1688
+ };
1689
+ await assert_1.default.rejects(async () => coin.isWalletAddress(params), /Base address verification requires index 0, but got index 5/);
1690
+ });
1691
+ it('should reject base address verification with wrong address', async function () {
1692
+ const coin = bitgo.coin('hteth');
1693
+ const keychains = [
1694
+ {
1695
+ id: '691f630e0c56098288a9b7fa107db144',
1696
+ source: 'user',
1697
+ type: 'tss',
1698
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1699
+ },
1700
+ {
1701
+ id: '691f630f1d3c9fce8f5a730bff826cf9',
1702
+ source: 'backup',
1703
+ type: 'tss',
1704
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1705
+ },
1706
+ {
1707
+ id: '691f630d56735e5eb61b06e353fe7639',
1708
+ source: 'bitgo',
1709
+ type: 'tss',
1710
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1711
+ },
1712
+ ];
1713
+ const wrongAddress = '0x0000000000000000000000000000000000000001';
1714
+ const actualBaseAddress = '0xc012041dac143a59fa491db3a2b67b69bd78b685';
1715
+ const params = {
1716
+ address: wrongAddress,
1717
+ baseAddress: actualBaseAddress,
1718
+ coinSpecific: {
1719
+ salt: '0x0',
1720
+ forwarderVersion: 5,
1721
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1722
+ },
1723
+ keychains,
1724
+ index: 0,
1725
+ walletVersion: 6,
1726
+ };
1727
+ const isWalletAddr = await coin.isWalletAddress(params);
1728
+ isWalletAddr.should.equal(false);
1729
+ });
1730
+ it('should verify base address for wallet version 2 (BIP32) using wallet factory', async function () {
1731
+ const coin = bitgo.coin('hteth');
1732
+ const baseAddress = '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4';
1733
+ const walletSalt = '0x2';
1734
+ const keychains = [
1735
+ {
1736
+ id: '691e8c7b3c8aaa791118d9ce616d3b21',
1737
+ source: 'user',
1738
+ type: 'independent',
1739
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
1740
+ },
1741
+ {
1742
+ id: '691e8c7b1967fd6d9867a22a1a4131a0',
1743
+ source: 'backup',
1744
+ type: 'independent',
1745
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
1746
+ },
1747
+ {
1748
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1749
+ source: 'bitgo',
1750
+ type: 'independent',
1751
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1752
+ },
1753
+ ];
1754
+ const params = {
1755
+ address: baseAddress,
1756
+ baseAddress: baseAddress,
1757
+ coinSpecific: {
1758
+ salt: walletSalt,
1759
+ forwarderVersion: 2,
1760
+ },
1761
+ keychains: keychains,
1762
+ index: 0,
1763
+ walletVersion: 2,
1764
+ };
1765
+ const isWalletAddr = await coin.isWalletAddress(params);
1766
+ isWalletAddr.should.equal(true);
1767
+ });
1768
+ it('should verify base address for wallet version 1 (BIP32) using wallet factory', async function () {
1769
+ const coin = bitgo.coin('hteth');
1770
+ const baseAddress = '0xe1253bcce7d87db522fbceec6e55c9f78c376d9f';
1771
+ const walletSalt = '0x5';
1772
+ const keychains = [
1773
+ {
1774
+ id: '691f638f1d3c9fce8f5aa691569a99eb',
1775
+ source: 'user',
1776
+ type: 'independent',
1777
+ ethAddress: '0xf45dadce751a317957f2a247ff37cb764b97620d',
1778
+ pub: 'xpub661MyMwAqRbcGVb3PfCzwiEX94AB1nJQtzVm...',
1779
+ },
1780
+ {
1781
+ id: '691f638f0b74e73b1f440ea4aceda87e',
1782
+ source: 'backup',
1783
+ type: 'independent',
1784
+ ethAddress: '0x5bdf3ae1d2c2fadeeb70a45872bf4f4252312b55',
1785
+ pub: 'xpub661MyMwAqRbcF46pRHda3sZbuPzza9A9MiqA...',
1786
+ },
1787
+ {
1788
+ id: '68b9ec587d0ba1c7440de551068c36a7',
1789
+ source: 'bitgo',
1790
+ type: 'independent',
1791
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1792
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79Hok...',
1793
+ },
1794
+ ];
1795
+ const params = {
1796
+ address: baseAddress,
1797
+ baseAddress: baseAddress,
1798
+ coinSpecific: {
1799
+ salt: walletSalt,
1800
+ forwarderVersion: 1,
1801
+ },
1802
+ keychains: keychains,
1803
+ index: 0,
1804
+ walletVersion: 1,
1805
+ };
1806
+ const isWalletAddr = await coin.isWalletAddress(params);
1807
+ isWalletAddr.should.equal(true);
1808
+ });
1809
+ });
1810
+ });
1811
+ });
1812
+ describe('Address Creation', function () {
1813
+ it('should pass walletVersion 6 to isWalletAddress during address creation', async function () {
1814
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1815
+ const ethCoin = bitgo.coin('hteth');
1816
+ const walletDataV6 = {
1817
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1818
+ coinSpecific: {
1819
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1820
+ walletVersion: 6,
1821
+ },
1822
+ coin: 'hteth',
1823
+ keys: [
1824
+ '598f606cd8fc24710d2ebad89dce86c2',
1825
+ '598f606cc8e43aef09fcb785221d9dd2',
1826
+ '5935d59cf660764331bafcade1855fd7',
1827
+ ],
1828
+ receiveAddress: {
1829
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
1830
+ },
1831
+ };
1832
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
1833
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1834
+ // Mock keychain requests
1835
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1836
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1837
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1838
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1839
+ source: 'user',
1840
+ type: 'tss',
1841
+ });
1842
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1843
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1844
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1845
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1846
+ source: 'backup',
1847
+ type: 'tss',
1848
+ });
1849
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1850
+ id: '5935d59cf660764331bafcade1855fd7',
1851
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1852
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
1853
+ source: 'bitgo',
1854
+ type: 'tss',
1855
+ });
1856
+ // Mock address creation API
1857
+ (0, nock_1.default)(bgUrl)
1858
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
1859
+ .reply(200, {
1860
+ id: '638a48c6c3dba40007a3497fa49a080c',
1861
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
1862
+ chain: 0,
1863
+ index: 0,
1864
+ coin: 'hteth',
1865
+ wallet: ethWalletV6.id(),
1866
+ coinSpecific: {
1867
+ forwarderVersion: 4,
1868
+ salt: '0x0',
1869
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1870
+ },
1871
+ });
1872
+ await ethWalletV6.createAddress({ chain: 0 });
1873
+ isWalletAddressSpy.calledOnce.should.be.true();
1874
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1875
+ calledParams.should.have.property('walletVersion', 6);
1876
+ });
1877
+ it('should pass walletVersion 5 to isWalletAddress during address creation', async function () {
1878
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1879
+ const ethCoin = bitgo.coin('hteth');
1880
+ const walletDataV5 = {
1881
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1882
+ coinSpecific: {
1883
+ baseAddress: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1884
+ walletVersion: 5,
1885
+ },
1886
+ coin: 'hteth',
1887
+ keys: [
1888
+ '598f606cd8fc24710d2ebad89dce86c2',
1889
+ '598f606cc8e43aef09fcb785221d9dd2',
1890
+ '5935d59cf660764331bafcade1855fd7',
1891
+ ],
1892
+ receiveAddress: {
1893
+ address: '0xf1e3d30798acdf3a12fa5beb5fad8efb23d5be11',
1894
+ },
1895
+ };
1896
+ const ethWalletV5 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV5);
1897
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1898
+ // Mock keychain requests
1899
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1900
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1901
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
1902
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1903
+ source: 'user',
1904
+ type: 'tss',
1905
+ });
1906
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1907
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1908
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
1909
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1910
+ source: 'backup',
1911
+ type: 'tss',
1912
+ });
1913
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1914
+ id: '5935d59cf660764331bafcade1855fd7',
1915
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
1916
+ commonKeychain: '02c8a496b16abfe2567520a279e2154642fc3c0e08e629775cb4d845c0c5fbf55ab7ba153e886de65748ed18f4ff8f5cee2242e687399ea3297a1f5524fdefd56c',
1917
+ source: 'bitgo',
1918
+ type: 'tss',
1919
+ });
1920
+ // Mock address creation API
1921
+ (0, nock_1.default)(bgUrl)
1922
+ .post(`/api/v2/hteth/wallet/${ethWalletV5.id()}/address`)
1923
+ .reply(200, {
1924
+ id: '638a48c6c3dba40007a3497fa49a080c',
1925
+ address: '0xd63b5e2b8d1b4fba3625460508900bf2a0499a4d',
1926
+ chain: 0,
1927
+ index: 117,
1928
+ coin: 'hteth',
1929
+ wallet: ethWalletV5.id(),
1930
+ coinSpecific: {
1931
+ forwarderVersion: 4,
1932
+ salt: '0x75',
1933
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1934
+ },
1935
+ });
1936
+ await ethWalletV5.createAddress({ chain: 0 });
1937
+ // Verify isWalletAddress was called with walletVersion 5
1938
+ isWalletAddressSpy.calledOnce.should.be.true();
1939
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
1940
+ calledParams.should.have.property('walletVersion', 5);
1941
+ });
1942
+ it('should pass walletVersion 2 to isWalletAddress during address creation', async function () {
1943
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
1944
+ const ethCoin = bitgo.coin('hteth');
1945
+ const walletDataV2 = {
1946
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
1947
+ coinSpecific: {
1948
+ baseAddress: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1949
+ walletVersion: 2,
1950
+ },
1951
+ coin: 'hteth',
1952
+ keys: [
1953
+ '598f606cd8fc24710d2ebad89dce86c2',
1954
+ '598f606cc8e43aef09fcb785221d9dd2',
1955
+ '5935d59cf660764331bafcade1855fd7',
1956
+ ],
1957
+ receiveAddress: {
1958
+ address: '0xdc485da076ed4a2b19584e9a1fdbb974f89b60f4',
1959
+ },
1960
+ };
1961
+ const ethWalletV2 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV2);
1962
+ const isWalletAddressSpy = sinon_1.default.spy(ethCoin, 'isWalletAddress');
1963
+ // Mock keychain requests
1964
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
1965
+ id: '598f606cd8fc24710d2ebad89dce86c2',
1966
+ pub: 'xpub661MyMwAqRbcGrCxCX39zb3TvYjTqfUGwEUZHjnraRFm1WeMw9gfCD1wwc2wUDmBBZ2TkccJMwf5eBTja8r3z6HMxoTZGW6nvyoJMQFsecv',
1967
+ ethAddress: '0x9d16bb867b792c5e3bf636a0275f2db8601bd7d4',
1968
+ source: 'user',
1969
+ type: 'independent',
1970
+ });
1971
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
1972
+ id: '598f606cc8e43aef09fcb785221d9dd2',
1973
+ pub: 'xpub661MyMwAqRbcGKhdeC4nr1ta8d27xThtfFFHgbxWMrVb595meMS8i3fBMrTz8EdQMWBKHHKzxapGgheoMymVvRcQmaGDykRTBbtXqbiu9ps',
1974
+ ethAddress: '0x2dfce5cfeb5c03fbe680cd39ac0d2b25399b7d22',
1975
+ source: 'backup',
1976
+ type: 'independent',
1977
+ });
1978
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
1979
+ id: '5935d59cf660764331bafcade1855fd7',
1980
+ pub: 'xpub661MyMwAqRbcGzTn5eyNGDkb18R43nH79HokYLc5PXZM19V8UrbuLdVRaCQMs4EeCAjnqmoYXqfyusTU46WoZMDyLpmTzoUX66ZBwGFjt1a',
1981
+ ethAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
1982
+ source: 'bitgo',
1983
+ type: 'independent',
1984
+ });
1985
+ // Mock address creation API
1986
+ (0, nock_1.default)(bgUrl)
1987
+ .post(`/api/v2/hteth/wallet/${ethWalletV2.id()}/address`)
1988
+ .reply(200, {
1989
+ id: '638a48c6c3dba40007a3497fa49a080c',
1990
+ address: '0xf636ceddffe41d106586875c0e56dc8feb6268f7',
1991
+ chain: 0,
1992
+ index: 23,
1993
+ coin: 'hteth',
1994
+ wallet: ethWalletV2.id(),
1995
+ coinSpecific: {
1996
+ forwarderVersion: 2,
1997
+ salt: '0x17',
1998
+ },
1999
+ });
2000
+ await ethWalletV2.createAddress({ chain: 0 });
2001
+ // Verify isWalletAddress was called with walletVersion 2
2002
+ isWalletAddressSpy.calledOnce.should.be.true();
2003
+ const calledParams = isWalletAddressSpy.firstCall.args[0];
2004
+ calledParams.should.have.property('walletVersion', 2);
2005
+ });
2006
+ it('should fail v6 address creation if walletVersion was not passed (simulates old bug)', async function () {
2007
+ const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
2008
+ const ethCoin = bitgo.coin('hteth');
2009
+ const walletDataV6 = {
2010
+ id: '598f606cd8fc24710d2ebadb1d9459bb',
2011
+ coinSpecific: {
2012
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
2013
+ walletVersion: 6,
2014
+ },
2015
+ coin: 'hteth',
2016
+ keys: [
2017
+ '598f606cd8fc24710d2ebad89dce86c2',
2018
+ '598f606cc8e43aef09fcb785221d9dd2',
2019
+ '5935d59cf660764331bafcade1855fd7',
2020
+ ],
2021
+ receiveAddress: {
2022
+ address: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
2023
+ },
2024
+ };
2025
+ const ethWalletV6 = new sdk_core_1.Wallet(bitgo, ethCoin, walletDataV6);
2026
+ // Stub isWalletAddress to simulate the OLD bug where walletVersion was not passed
2027
+ const originalIsWalletAddress = ethCoin.isWalletAddress.bind(ethCoin);
2028
+ const isWalletAddressStub = sinon_1.default.stub(ethCoin, 'isWalletAddress').callsFake(async (params) => {
2029
+ // Remove walletVersion to simulate the old bug
2030
+ const paramsWithoutWalletVersion = { ...params };
2031
+ delete paramsWithoutWalletVersion.walletVersion;
2032
+ return originalIsWalletAddress(paramsWithoutWalletVersion);
2033
+ });
2034
+ // Mock keychain requests
2035
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cd8fc24710d2ebad89dce86c2`).reply(200, {
2036
+ id: '598f606cd8fc24710d2ebad89dce86c2',
2037
+ pub: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
2038
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2039
+ source: 'user',
2040
+ type: 'tss',
2041
+ });
2042
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/598f606cc8e43aef09fcb785221d9dd2`).reply(200, {
2043
+ id: '598f606cc8e43aef09fcb785221d9dd2',
2044
+ pub: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
2045
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2046
+ source: 'backup',
2047
+ type: 'tss',
2048
+ });
2049
+ (0, nock_1.default)(bgUrl).get(`/api/v2/hteth/key/5935d59cf660764331bafcade1855fd7`).reply(200, {
2050
+ id: '5935d59cf660764331bafcade1855fd7',
2051
+ pub: 'xpub661MyMwAqRbcFsXShW8R3hJsHNTYTUwzcejnLkY7KCtaJbDqcGkcBF99BrEJSjNZHeHveiYUrsAdwnjUMGwpgmEbiKcZWRuVA9HxnRaA3r3',
2052
+ commonKeychain: '033b02aac4f038fef5118350b77d302ec6202931ca2e7122aad88994ffefcbc70a6069e662436236abb1619195232c41580204cb202c22357ed8f53e69eac5c69e',
2053
+ source: 'bitgo',
2054
+ type: 'tss',
2055
+ });
2056
+ // Mock address creation API
2057
+ (0, nock_1.default)(bgUrl)
2058
+ .post(`/api/v2/hteth/wallet/${ethWalletV6.id()}/address`)
2059
+ .reply(200, {
2060
+ id: '638a48c6c3dba40007a3497fa49a080c',
2061
+ address: '0xc012041dac143a59fa491db3a2b67b69bd78b685',
2062
+ chain: 0,
2063
+ index: 0,
2064
+ coin: 'hteth',
2065
+ wallet: ethWalletV6.id(),
2066
+ coinSpecific: {
2067
+ forwarderVersion: 4,
2068
+ salt: '0x0',
2069
+ feeAddress: '0xb1e725186990b86ca8efed08a3ccda9c9f400f09',
2070
+ },
2071
+ });
2072
+ // Without walletVersion, address creation should fail because
2073
+ // the code doesn't know to use TSS verification for v6 wallets
2074
+ await assert_1.default.rejects(async () => ethWalletV6.createAddress({ chain: 0 }), sdk_core_1.UnexpectedAddressError);
2075
+ isWalletAddressStub.restore();
2076
+ });
2077
+ });
2078
+ describe('EVM Cross Chain Recovery', function () {
2079
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2080
+ it('should build a recovery transaction for hot wallet', async function () {
2081
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
2082
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
2083
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
2084
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
2085
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
2086
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
2087
+ const destinationAddress = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
2088
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
2089
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
2090
+ const basecoin = bitgo.coin('hteth');
2091
+ (0, nock_1.default)(baseUrl)
2092
+ .get('/api')
2093
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
2094
+ .reply(200, mockData.getTxListResponse);
2095
+ (0, nock_1.default)(baseUrl)
2096
+ .get('/api')
2097
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
2098
+ .reply(200, mockData.getBalanceResponse);
2099
+ (0, nock_1.default)(baseUrl)
2100
+ .get('/api')
2101
+ .query(mockData.getBalanceRequest(walletContractAddress))
2102
+ .reply(200, mockData.getBalanceResponse);
2103
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2104
+ const spy = sinon_1.default.spy(src_1.TransactionBuilder.prototype, 'coinUsesNonPackedEncodingForTxData');
2105
+ await basecoin.recover({
2106
+ userKey: userKey,
2107
+ backupKey: '',
2108
+ walletPassphrase: walletPassphrase,
2109
+ walletContractAddress: walletContractAddress,
2110
+ bitgoFeeAddress: bitgoFeeAddress,
2111
+ recoveryDestination: destinationAddress,
2112
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2113
+ gasLimit: 500000,
2114
+ bitgoDestinationAddress: bitgoDestinationAddress,
2115
+ intendedChain: 'tarbeth',
2116
+ });
2117
+ (0, assert_1.default)(spy.returned(true));
2118
+ });
2119
+ describe('Non-BitGo Recovery for Hot Wallets (MPCv2)', function () {
2120
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2121
+ let bitgo;
2122
+ let basecoin;
2123
+ before(function () {
2124
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2125
+ basecoin = bitgo.coin('hteth');
2126
+ });
2127
+ it('should build a recovery transaction for MPCv2 kind of hot wallets', async function () {
2128
+ (0, nock_1.default)(baseUrl)
2129
+ .get('/api')
2130
+ .query(mockData.getTxListRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
2131
+ .reply(200, mockData.getTxListResponse);
2132
+ (0, nock_1.default)(baseUrl)
2133
+ .get('/api')
2134
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
2135
+ .reply(200, mockData.getBalanceResponse);
2136
+ (0, nock_1.default)(baseUrl)
2137
+ .get('/api')
2138
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().walletContractAddress))
2139
+ .reply(200, mockData.getBalanceResponse);
2140
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2141
+ const params = mockData.getNonBitGoRecoveryForHotWalletsMPCv2();
2142
+ const transaction = await basecoin.recover({
2143
+ userKey: params.userKey,
2144
+ backupKey: params.backupKey,
2145
+ walletPassphrase: params.walletPassphrase,
2146
+ walletContractAddress: params.walletContractAddress,
2147
+ bitgoFeeAddress: params.bitgoFeeAddress,
2148
+ recoveryDestination: params.recoveryDestination,
2149
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2150
+ gasLimit: 500000,
2151
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
2152
+ intendedChain: params.intendedChain,
2153
+ });
2154
+ should_1.default.exist(transaction);
2155
+ transaction.should.have.property('txHex');
2156
+ });
2157
+ it('should throw an error for invalid user key', async function () {
2158
+ const params = mockData.getInvalidNonBitGoRecoveryParams();
2159
+ await assert_1.default.rejects(async () => {
2160
+ await basecoin.recover({
2161
+ userKey: params.userKey,
2162
+ backupKey: params.backupKey,
2163
+ walletPassphrase: params.walletPassphrase,
2164
+ walletContractAddress: params.walletContractAddress,
2165
+ bitgoFeeAddress: params.bitgoFeeAddress,
2166
+ recoveryDestination: params.recoveryDestination,
2167
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
2168
+ gasLimit: 500000,
2169
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
2170
+ intendedChain: params.intendedChain,
2171
+ });
2172
+ }, Error, 'user key is invalid');
2173
+ });
2174
+ });
2175
+ describe('Build Unsigned Sweep for Self-Custody Cold Wallets (MPCv2)', function () {
2176
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2177
+ let bitgo;
2178
+ let basecoin;
2179
+ before(function () {
2180
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2181
+ basecoin = bitgo.coin('hteth');
2182
+ });
2183
+ it('should generate an unsigned sweep without derivation seed', async function () {
2184
+ (0, nock_1.default)(baseUrl)
2185
+ .get('/api')
2186
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2187
+ .reply(200, mockData.getTxListResponse);
2188
+ (0, nock_1.default)(baseUrl)
2189
+ .get('/api')
2190
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2191
+ .reply(200, mockData.getBalanceResponse);
2192
+ (0, nock_1.default)(baseUrl)
2193
+ .get('/api')
2194
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2195
+ .reply(200, mockData.getBalanceResponse);
2196
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2197
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2198
+ const sweepResult = await basecoin.recover({
2199
+ userKey: params.commonKeyChain, // Box A Data
2200
+ backupKey: params.commonKeyChain, // Box B Data
2201
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2202
+ recoveryDestination: params.recoveryDestination, // Destination Address
2203
+ gasLimit: 200000, // Gas Limit
2204
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2205
+ walletContractAddress: params.walletContractAddress,
2206
+ isTss: true,
2207
+ replayProtectionOptions: {
2208
+ chain: '42',
2209
+ hardfork: 'london',
2210
+ },
2211
+ });
2212
+ should_1.default.exist(sweepResult);
2213
+ const output = sweepResult;
2214
+ output.should.have.property('txRequests');
2215
+ output.txRequests.should.have.length(1);
2216
+ output.txRequests[0].should.have.property('transactions');
2217
+ output.txRequests[0].transactions.should.have.length(1);
2218
+ output.txRequests[0].should.have.property('walletCoin');
2219
+ output.txRequests[0].transactions.should.have.length(1);
2220
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2221
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2222
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2223
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2224
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2225
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2226
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2227
+ parsedTx.should.have.property('spendAmount');
2228
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2229
+ });
2230
+ it('should throw an error for invalid address', async function () {
2231
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2232
+ params.recoveryDestination = 'invalidAddress';
2233
+ // Ensure userKey and backupKey are the same
2234
+ params.userKey =
2235
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2236
+ params.backupKey =
2237
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2238
+ await assert_1.default.rejects(async () => {
2239
+ await basecoin.recover({
2240
+ recoveryDestination: params.recoveryDestination, // Destination Address
2241
+ gasLimit: 2000, // Gas Limit
2242
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2243
+ userKey: params.userKey, // Provide the userKey
2244
+ backupKey: params.backupKey, // Provide the backupKey
2245
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
2246
+ isTss: true,
2247
+ replayProtectionOptions: {
2248
+ chain: '42',
2249
+ hardfork: 'london',
2250
+ },
2251
+ });
2252
+ }, Error, 'Error: invalid address');
2253
+ });
2254
+ });
2255
+ describe('Build Unsigned Consolidation for Self-Custody Cold Wallets (MPCv2)', function () {
2256
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
2257
+ let bitgo;
2258
+ let basecoin;
2259
+ before(function () {
2260
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
2261
+ basecoin = bitgo.coin('hteth');
2262
+ });
2263
+ it('should generate an unsigned consolidation for wallet v5', async function () {
2264
+ (0, nock_1.default)(baseUrl)
2265
+ .get('/api')
2266
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2267
+ .times(2)
2268
+ .reply(200, mockData.getTxListResponse);
2269
+ (0, nock_1.default)(baseUrl)
2270
+ .get('/api')
2271
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2272
+ .times(2)
2273
+ .reply(200, mockData.getBalanceResponse);
2274
+ (0, nock_1.default)(baseUrl)
2275
+ .get('/api')
2276
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2277
+ .reply(200, mockData.getBalanceResponse);
2278
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2279
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2280
+ const consolidationResult = await basecoin.recoverConsolidations({
2281
+ backupKey: params.commonKeyChain, // Box B Data
2282
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2283
+ recoveryDestination: params.recoveryDestination, // Destination Address
2284
+ gasLimit: 200000, // Gas Limit
2285
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2286
+ walletContractAddress: params.walletContractAddress,
2287
+ isTss: true,
2288
+ replayProtectionOptions: {
2289
+ chain: '42',
2290
+ hardfork: 'london',
2291
+ },
2292
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
2293
+ startingScanIndex: 1,
2294
+ endingScanIndex: 2,
2295
+ });
2296
+ should_1.default.exist(consolidationResult);
2297
+ const unsignedBuilConsolidation = consolidationResult;
2298
+ unsignedBuilConsolidation.should.have.property('transactions');
2299
+ unsignedBuilConsolidation.transactions.should.have.length(1);
2300
+ const output = unsignedBuilConsolidation.transactions[0];
2301
+ output.should.have.property('txRequests');
2302
+ output.txRequests[0].should.have.property('transactions');
2303
+ output.txRequests[0].transactions.should.have.length(1);
2304
+ output.txRequests[0].should.have.property('walletCoin');
2305
+ output.txRequests[0].transactions.should.have.length(1);
2306
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2307
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2308
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2309
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2310
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2311
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2312
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2313
+ parsedTx.should.have.property('spendAmount');
2314
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2315
+ });
2316
+ it('should generate an unsigned consolidation for wallet v6', async function () {
2317
+ (0, nock_1.default)(baseUrl)
2318
+ .get('/api')
2319
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2320
+ .times(2)
2321
+ .reply(200, mockData.getTxListResponse);
2322
+ (0, nock_1.default)(baseUrl)
2323
+ .get('/api')
2324
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
2325
+ .times(2)
2326
+ .reply(200, mockData.getBalanceResponse);
2327
+ (0, nock_1.default)(baseUrl)
2328
+ .get('/api')
2329
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
2330
+ .reply(200, mockData.getBalanceResponse);
2331
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
2332
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2333
+ const consolidationResult = await basecoin.recoverConsolidations({
2334
+ userKey: params.commonKeyChain, // Box A Data
2335
+ backupKey: params.commonKeyChain, // Box B Data
2336
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
2337
+ recoveryDestination: params.recoveryDestination, // Destination Address
2338
+ gasLimit: 200000, // Gas Limit
2339
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2340
+ isTss: true,
2341
+ walletContractAddress: '123', // Wrong wallet address so that we can skip v5 address generation
2342
+ replayProtectionOptions: {
2343
+ chain: '42',
2344
+ hardfork: 'london',
2345
+ },
2346
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
2347
+ startingScanIndex: 1,
2348
+ endingScanIndex: 2,
2349
+ });
2350
+ should_1.default.exist(consolidationResult);
2351
+ const unsignedBuilConsolidation = consolidationResult;
2352
+ unsignedBuilConsolidation.should.have.property('transactions');
2353
+ unsignedBuilConsolidation.transactions.should.have.length(1);
2354
+ const output = unsignedBuilConsolidation.transactions[0];
2355
+ output.should.have.property('txRequests');
2356
+ output.txRequests[0].should.have.property('transactions');
2357
+ output.txRequests[0].transactions.should.have.length(1);
2358
+ output.txRequests[0].should.have.property('walletCoin');
2359
+ output.txRequests[0].transactions.should.have.length(1);
2360
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
2361
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
2362
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
2363
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
2364
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
2365
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
2366
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
2367
+ parsedTx.should.have.property('spendAmount');
2368
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
2369
+ });
2370
+ it('should throw an error for invalid address', async function () {
2371
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
2372
+ params.recoveryDestination = 'invalidAddress';
2373
+ // Ensure userKey and backupKey are the same
2374
+ params.userKey =
2375
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2376
+ params.backupKey =
2377
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
2378
+ await assert_1.default.rejects(async () => {
2379
+ await basecoin.recover({
2380
+ recoveryDestination: params.recoveryDestination, // Destination Address
2381
+ gasLimit: 2000, // Gas Limit
2382
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
2383
+ userKey: params.userKey, // Provide the userKey
2384
+ backupKey: params.backupKey, // Provide the backupKey
2385
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
2386
+ isTss: true,
2387
+ replayProtectionOptions: {
2388
+ chain: '42',
2389
+ hardfork: 'london',
2390
+ },
2391
+ });
2392
+ }, Error, 'Error: invalid address');
2393
+ });
2394
+ });
2395
+ });
2396
+ describe('RecoveryBlockchainExplorerQuery', () => {
2397
+ it('should override the token parameter with a custom API key', async function () {
2398
+ const coin = bitgo.coin('teth');
2399
+ const query = {
2400
+ module: 'account',
2401
+ action: 'balance',
2402
+ address: '0x1234567890123456789012345678901234567890',
2403
+ };
2404
+ const customApiKey = 'custom-api-key-for-test';
2405
+ // Mock the environment API token
2406
+ const originalApiToken = sdk_core_1.common.Environments.test.etherscanApiToken;
2407
+ sdk_core_1.common.Environments.test.etherscanApiToken = 'default-environment-api-key';
2408
+ // Mock the request.get function to capture the query parameters
2409
+ const originalGet = superagent_1.default.get;
2410
+ let capturedQuery;
2411
+ superagent_1.default.get = function (url) {
2412
+ return {
2413
+ query: function (params) {
2414
+ capturedQuery = params;
2415
+ return {
2416
+ ok: true,
2417
+ body: { result: '100000000' },
2418
+ };
2419
+ },
2420
+ };
2421
+ };
2422
+ try {
2423
+ // Call with default API key
2424
+ await coin.recoveryBlockchainExplorerQuery(query);
2425
+ capturedQuery.should.have.property('apikey', 'default-environment-api-key');
2426
+ // Call with custom API key
2427
+ await coin.recoveryBlockchainExplorerQuery(query, customApiKey);
2428
+ capturedQuery.should.have.property('apikey', customApiKey);
2429
+ }
2430
+ finally {
2431
+ // Restore original function and API token
2432
+ superagent_1.default.get = originalGet;
2433
+ sdk_core_1.common.Environments.test.etherscanApiToken = originalApiToken;
2434
+ }
2435
+ });
2436
+ });
2437
+ describe('Audit Key', () => {
2438
+ let coin;
2439
+ before(() => {
2440
+ coin = bitgo.coin('hteth');
2441
+ });
2442
+ describe('MultiSig', () => {
2443
+ const { key } = ethMultiSigBackupKey_1.ethMultiSigBackupKey;
2444
+ it('should return { isValid: true } for valid inputs', () => {
2445
+ coin.assertIsValidKey({
2446
+ encryptedPrv: key,
2447
+ walletPassphrase: 'ZQ8MhxT84m4P',
2448
+ });
2449
+ });
2450
+ it('should throw error if the walletPassphrase is incorrect', async () => {
2451
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2452
+ encryptedPrv: key,
2453
+ walletPassphrase: 'foo',
2454
+ }), { message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' });
2455
+ });
2456
+ it('should throw error if the key is altered', async () => {
2457
+ const alteredKey = key.replace(/[0-9]/g, '0');
2458
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2459
+ encryptedPrv: alteredKey,
2460
+ walletPassphrase: 'kAm[EFQ6o=SxlcLFDw%,',
2461
+ }), { message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' });
2462
+ });
2463
+ });
2464
+ describe('TSS', () => {
2465
+ const { key: keyString, commonKeychain } = ethTssBackupKey_1.ethTssBackupKey;
2466
+ const key = keyString.replace(/\s/g, '');
2467
+ const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
2468
+ const multiSigType = 'tss';
2469
+ it('should not throw for valid inputs', () => {
2470
+ coin.assertIsValidKey({
2471
+ encryptedPrv: key,
2472
+ publicKey: commonKeychain,
2473
+ walletPassphrase,
2474
+ multiSigType,
2475
+ });
2476
+ });
2477
+ it('should throw if the commonKeychain is altered', async () => {
2478
+ const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
2479
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2480
+ encryptedPrv: key,
2481
+ publicKey: alteredCommonKeychain,
2482
+ walletPassphrase,
2483
+ multiSigType,
2484
+ }), { message: 'Invalid common keychain' });
2485
+ });
2486
+ it('should throw error if the walletPassphrase is incorrect', async () => {
2487
+ const incorrectPassphrase = 'foo';
2488
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2489
+ encryptedPrv: key,
2490
+ publicKey: commonKeychain,
2491
+ walletPassphrase: incorrectPassphrase,
2492
+ multiSigType,
2493
+ }), { message: 'failed to decrypt prv: incorrect password' });
2494
+ });
2495
+ it('should throw error if the key is altered', async () => {
2496
+ const alteredKey = key.replace(/[0-9]/g, '0');
2497
+ await assert_1.default.rejects(() => coin.assertIsValidKey({
2498
+ encryptedPrv: alteredKey,
2499
+ publicKey: commonKeychain,
2500
+ walletPassphrase,
2501
+ multiSigType,
2502
+ }), { message: 'failed to decrypt prv: decrypt: ciphertext is not valid JSON' });
2503
+ });
2504
+ });
2505
+ });
2506
+ describe('getSignablePayload', function () {
2507
+ let coin;
2508
+ before(function () {
2509
+ coin = bitgo.coin('teth');
2510
+ });
2511
+ it('should return a 32-byte keccak256 hash for a Legacy transaction', async function () {
2512
+ const txBuilder = (0, getBuilder_1.getBuilder)('teth');
2513
+ txBuilder.type(sdk_core_1.TransactionType.Send);
2514
+ txBuilder.fee({ fee: '10000000000', gasLimit: '7000000' });
2515
+ txBuilder.counter(1);
2516
+ txBuilder.contract('0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8');
2517
+ const transferBuilder = txBuilder.transfer();
2518
+ transferBuilder
2519
+ .coin('teth')
2520
+ .expirationTime(Math.floor(Date.now() / 1000) + 3600)
2521
+ .amount('100000')
2522
+ .to('0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7')
2523
+ .contractSequenceId(1);
2524
+ const tx = await txBuilder.build();
2525
+ const serializedTx = tx.toBroadcastFormat();
2526
+ const payload = await coin.getSignablePayload(serializedTx);
2527
+ assert_1.default.ok(Buffer.isBuffer(payload));
2528
+ assert_1.default.strictEqual(payload.length, 32);
2529
+ });
2530
+ it('should return a 32-byte keccak256 hash for an EIP1559 transaction', async function () {
2531
+ const txBuilder = (0, getBuilder_1.getBuilder)('teth');
2532
+ txBuilder.type(sdk_core_1.TransactionType.Send);
2533
+ txBuilder.fee({
2534
+ fee: '280000000000',
2535
+ gasLimit: '7000000',
2536
+ eip1559: { maxFeePerGas: '7593123', maxPriorityFeePerGas: '150' },
2537
+ });
2538
+ txBuilder.counter(1);
2539
+ txBuilder.contract('0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8');
2540
+ const transferBuilder = txBuilder.transfer();
2541
+ transferBuilder
2542
+ .coin('teth')
2543
+ .expirationTime(Math.floor(Date.now() / 1000) + 3600)
2544
+ .amount('100000')
2545
+ .to('0xeeaf0F05f37891ab4a21208B105A0687d12c5aF7')
2546
+ .contractSequenceId(1);
2547
+ const tx = await txBuilder.build();
2548
+ const serializedTx = tx.toBroadcastFormat();
2549
+ const payload = await coin.getSignablePayload(serializedTx);
2550
+ assert_1.default.ok(Buffer.isBuffer(payload));
2551
+ assert_1.default.strictEqual(payload.length, 32);
2552
+ });
2553
+ });
2554
+ // ---------------------------------------------------------------------------
2555
+ // ERC-7984 token enablement — multisig verifyTransaction (all scenarios)
2556
+ // ---------------------------------------------------------------------------
2557
+ describe('verifyTransaction – ERC-7984 enabletoken (multisig wallet)', function () {
2558
+ // hteth Zama ACL contract (Networks.test.hoodi.zamaAclContractAddress)
2559
+ const ZAMA_ACL_ADDRESS = '0x6d3faf6f86e1ff9f3b0831dda920aba1cbd5bd68';
2560
+ // Simulated wallet base address (what the client sends as the recipient for base-address wallets)
2561
+ const WALLET_BASE_ADDRESS = '0x08e6736e876d772d2fa8f803a076cd6c9f845546';
2562
+ // Simulated forwarder address (what the client sends as recipient for forwarder wallets)
2563
+ const FORWARDER_ADDRESS = '0x1234567890123456789012345678901234567890';
2564
+ const WRONG_ADDRESS = '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
2565
+ const makePrebuild = (recipientAddress) => ({
2566
+ recipients: [{ address: recipientAddress, amount: '0' }],
2567
+ nextContractSequenceId: 0,
2568
+ gasPrice: 20000000000,
2569
+ gasLimit: 300000,
2570
+ isBatch: false,
2571
+ coin: 'hteth',
2572
+ walletId: 'fakeWalletId',
2573
+ });
2574
+ // ── Base-address wallet ──────────────────────────────────────────────────
2575
+ it('base-address, single token: txParams → walletBase, txPrebuild → ACL', async function () {
2576
+ const htethCoin = bitgo.coin('hteth');
2577
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2578
+ const result = await htethCoin.verifyTransaction({
2579
+ txParams: {
2580
+ type: 'enabletoken',
2581
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2582
+ },
2583
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2584
+ wallet,
2585
+ });
2586
+ result.should.equal(true);
2587
+ });
2588
+ it('base-address, multi-token: multiple txParams recipients (same base address), txPrebuild → ACL multicall', async function () {
2589
+ const htethCoin = bitgo.coin('hteth');
2590
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2591
+ const result = await htethCoin.verifyTransaction({
2592
+ txParams: {
2593
+ type: 'enabletoken',
2594
+ recipients: [
2595
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
2596
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
2597
+ ],
2598
+ },
2599
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2600
+ wallet,
2601
+ });
2602
+ result.should.equal(true);
2603
+ });
2604
+ // ── Forwarder wallet ─────────────────────────────────────────────────────
2605
+ it('forwarder, single token: txParams → forwarder, txPrebuild → forwarder', async function () {
2606
+ const htethCoin = bitgo.coin('hteth');
2607
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2608
+ const result = await htethCoin.verifyTransaction({
2609
+ txParams: {
2610
+ type: 'enabletoken',
2611
+ recipients: [{ address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2612
+ },
2613
+ txPrebuild: makePrebuild(FORWARDER_ADDRESS),
2614
+ wallet,
2615
+ });
2616
+ result.should.equal(true);
2617
+ });
2618
+ it('forwarder, multi-token: multiple txParams recipients (same forwarder), txPrebuild → forwarder', async function () {
2619
+ const htethCoin = bitgo.coin('hteth');
2620
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2621
+ const result = await htethCoin.verifyTransaction({
2622
+ txParams: {
2623
+ type: 'enabletoken',
2624
+ recipients: [
2625
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
2626
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
2627
+ ],
2628
+ },
2629
+ txPrebuild: makePrebuild(FORWARDER_ADDRESS),
2630
+ wallet,
2631
+ });
2632
+ result.should.equal(true);
2633
+ });
2634
+ // ── Negative cases ───────────────────────────────────────────────────────
2635
+ it('should throw when txPrebuild recipient is neither the ACL contract nor the forwarder from txParams', async function () {
2636
+ const htethCoin = bitgo.coin('hteth');
2637
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2638
+ await htethCoin
2639
+ .verifyTransaction({
2640
+ txParams: {
2641
+ type: 'enabletoken',
2642
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2643
+ },
2644
+ txPrebuild: makePrebuild(WRONG_ADDRESS),
2645
+ wallet,
2646
+ })
2647
+ .should.be.rejectedWith(/token enablement txPrebuild recipient must be/);
2648
+ });
2649
+ it('should throw when txParams recipients have different addresses', async function () {
2650
+ const htethCoin = bitgo.coin('hteth');
2651
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2652
+ await htethCoin
2653
+ .verifyTransaction({
2654
+ txParams: {
2655
+ type: 'enabletoken',
2656
+ recipients: [
2657
+ { address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' },
2658
+ { address: FORWARDER_ADDRESS, amount: '0', tokenName: 'hteth:cusdt' },
2659
+ ],
2660
+ },
2661
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2662
+ wallet,
2663
+ })
2664
+ .should.be.rejectedWith(/must all have the same address/);
2665
+ });
2666
+ it('should throw when a txParams recipient has non-zero amount', async function () {
2667
+ const htethCoin = bitgo.coin('hteth');
2668
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2669
+ await htethCoin
2670
+ .verifyTransaction({
2671
+ txParams: {
2672
+ type: 'enabletoken',
2673
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '100', tokenName: 'hteth:ctest1' }],
2674
+ },
2675
+ txPrebuild: makePrebuild(ZAMA_ACL_ADDRESS),
2676
+ wallet,
2677
+ })
2678
+ .should.be.rejectedWith(/must all have amount 0/);
2679
+ });
2680
+ it('should throw when txPrebuild recipient has non-zero amount', async function () {
2681
+ const htethCoin = bitgo.coin('hteth');
2682
+ const wallet = new sdk_core_1.Wallet(bitgo, htethCoin, { coinSpecific: { baseAddress: WALLET_BASE_ADDRESS } });
2683
+ await htethCoin
2684
+ .verifyTransaction({
2685
+ txParams: {
2686
+ type: 'enabletoken',
2687
+ recipients: [{ address: WALLET_BASE_ADDRESS, amount: '0', tokenName: 'hteth:ctest1' }],
2688
+ },
2689
+ txPrebuild: {
2690
+ recipients: [{ address: ZAMA_ACL_ADDRESS, amount: '500' }],
2691
+ nextContractSequenceId: 0,
2692
+ coin: 'hteth',
2693
+ walletId: 'fakeWalletId',
2694
+ },
2695
+ wallet,
2696
+ })
2697
+ .should.be.rejectedWith(/expected amount 0 in txPrebuild/);
2698
+ });
2699
+ });
2700
+ });
2701
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUErRDtBQUUvRCxnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLHFEQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsNERBQWlDO0FBQ2pDLG1EQVU4QjtBQUM5QixpREFBK0M7QUFDL0MsbUNBV21CO0FBRW5CLG9EQUE0QjtBQUM1Qiw2Q0FBMEM7QUFDMUMsMkRBQTZDO0FBQzdDLDBEQUE0QztBQUM1QyxvREFBNEI7QUFDNUIsb0VBQXlDO0FBQ3pDLDBFQUF1RTtBQUN2RSxnRUFBNkQ7QUFFN0QsY0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7QUFFeEIsUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUNmLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLG1CQUFtQixDQUFDO0lBQ3hCLElBQUksT0FBMkIsQ0FBQztJQUVoQyxNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQztJQUM5RCxNQUFNLFFBQVEsR0FBRyw0Q0FBNEMsQ0FBQztJQUM5RCxNQUFNLGtCQUFrQixHQUFHLDRDQUE0QyxDQUFDO0lBQ3hFLE1BQU0scUJBQXFCLEdBQUcsNENBQTRDLENBQUM7SUFDM0UsTUFBTSxLQUFLLEdBQ1QsOE5BQThOLENBQUM7SUFDak8sTUFBTSxPQUFPLEdBQUcsb0VBQW9FLENBQUM7SUFDckYsTUFBTSxVQUFVLEdBQ2Qsb0lBQW9JLENBQUM7SUFFdkksTUFBTSxjQUFjLEdBQUcsS0FBSyxFQUFFLElBQVksRUFBbUIsRUFBRTtRQUM3RCxNQUFNLFNBQVMsR0FBRyxJQUFBLHVCQUFVLEVBQUMsT0FBTyxDQUF1QixDQUFDO1FBQzVELFNBQVMsQ0FBQyxJQUFJLENBQUMsMEJBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxTQUFTLENBQUMsR0FBRyxD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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcblxuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7XG4gIGNvbW1vbixcbiAgZ2VuZXJhdGVSYW5kb21QYXNzd29yZCxcbiAgSW52YWxpZEFkZHJlc3NFcnJvcixcbiAgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yLFxuICBNUENTd2VlcFR4cyxcbiAgVHJhbnNhY3Rpb25UeXBlLFxuICBUeEludGVudE1pc21hdGNoUmVjaXBpZW50RXJyb3IsXG4gIFVuZXhwZWN0ZWRBZGRyZXNzRXJyb3IsXG4gIFdhbGxldCxcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7XG4gIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zLFxuICBFcmMyMFRva2VuLFxuICBIdGV0aCxcbiAgVGV0aCxcbiAgVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBUcmFuc2ZlckJ1aWxkZXIsXG4gIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zLFxuICBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLFxuICBVbnNpZ25lZFN3ZWVwVHhNUEN2MixcbiAgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnMsXG59IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBFdGhlcmV1bU5ldHdvcmsgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuL2dldEJ1aWxkZXInO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2V0aCc7XG5pbXBvcnQgKiBhcyBtb2NrRGF0YSBmcm9tICcuLi9maXh0dXJlcy9ldGgnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IEV0aGVyZXVtQWJpIGZyb20gJ2V0aGVyZXVtanMtYWJpJztcbmltcG9ydCB7IGV0aE11bHRpU2lnQmFja3VwS2V5IH0gZnJvbSAnLi9maXh0dXJlcy9ldGhNdWx0aVNpZ0JhY2t1cEtleSc7XG5pbXBvcnQgeyBldGhUc3NCYWNrdXBLZXkgfSBmcm9tICcuL2ZpeHR1cmVzL2V0aFRzc0JhY2t1cEtleSc7XG5cbm5vY2suZW5hYmxlTmV0Q29ubmVjdCgpO1xuXG5kZXNjcmliZSgnRVRIOicsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBob3BUeEJpdGdvU2lnbmF0dXJlO1xuICBsZXQgc2FuZGJveDogc2lub24uU2lub25TYW5kYm94O1xuXG4gIGNvbnN0IGFkZHJlc3MxID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gIGNvbnN0IGFkZHJlc3MyID0gJzB4N2U4NWJkYzI3YzA1MGUzOTA1ZWJmNGI4ZTYzNGQ5YWQ2ZWRkMGRlNic7XG4gIGNvbnN0IGhvcENvbnRyYWN0QWRkcmVzcyA9ICcweDQ3Y2U3Y2M4NmVmZWZlZjE5ZjhmYjUxNmIxMTczNWQxODNkYTg2MzUnO1xuICBjb25zdCBob3BEZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHg5YzdlOGNlNjgyNWJENDgyNzhCM0FiNTkyMjhFRTI2ZjhCRTc5MjViJztcbiAgY29uc3QgaG9wVHggPVxuICAgICcweGY4NmI4MDg1MDRhODE3YzhmZjgyNTJmZjk0OWM3ZThjZTY4MjViZDQ4Mjc4YjNhYjU5MjI4ZWUyNmY4YmU3OTI1Yjg3MDM4ZDdlYTRjNjgwMDA4MDFjYTAxMWJjMjJjNjY0NTcwMTMzZGZjYTRmMDhhMGI4ZDAyMzM5Y2Y0NjcwNDZkNmE0MTUyZjA0ZjM2OGQwZWFmOTllYTAxZDZkYzVjZjBjODk3YzhkNGMzZTFkZjUzZDBkMDQyNzg0YzQyNDUzNmE0Y2M1YjgwMjU1MmI3ZDY0ZmVlOGI1JztcbiAgY29uc3QgaG9wVHhpZCA9ICcweDRhZjY1MTQzYmM3N2RhMmI1MGYzNWIzZDEzY2FjYjRkYjE4ZjAyNmJmODRiYzA3NDM1NTBiYzU3YjliNTMzNTEnO1xuICBjb25zdCB1c2VyUmVxU2lnID1cbiAgICAnMHg0MDRkYjMwN2Y2MTQ3ZjBkOGNkMzM4YzM0YzEzOTA2ZWY0NmE2ZmFhN2UwZTExOWQ1MTk0ZWYwNWFlYzE2ZTZmM2Q3MTBmOWI3OTAxNDYwZjk3ZTkyNDA2NmI2MmVmZDc0NDQzYmQzNDQwMmM2ZDQwYjQ5YzIwM2E1NTlmZjJjOCc7XG5cbiAgY29uc3QgYnVpbGREZWZpVHhIZXggPSBhc3luYyAoZGF0YTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAnLCBnYXNMaW1pdDogJzEwMDAwMCcgfSk7XG4gICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgdHhCdWlsZGVyLmNvbnRyYWN0KGFkZHJlc3MxKTtcbiAgICB0eEJ1aWxkZXIuZGF0YShkYXRhKTtcbiAgICByZXR1cm4gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKS50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICB9O1xuXG4gIGNvbnN0IGRlZmlDYWxsZGF0YSA9IChzaWduYXR1cmU6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSk6IHN0cmluZyA9PiB7XG4gICAgY29uc3QgdHlwZXMgPSBzaWduYXR1cmUuc2xpY2Uoc2lnbmF0dXJlLmluZGV4T2YoJygnKSArIDEsIC0xKS5zcGxpdCgnLCcpO1xuICAgIGNvbnN0IG1ldGhvZElkID0gRXRoZXJldW1BYmkubWV0aG9kSUQoc2lnbmF0dXJlLnNwbGl0KCcoJylbMF0sIHR5cGVzKTtcbiAgICByZXR1cm4gJzB4JyArIEJ1ZmZlci5jb25jYXQoW21ldGhvZElkLCBFdGhlcmV1bUFiaS5yYXdFbmNvZGUodHlwZXMsIHZhbHVlcyldKS50b1N0cmluZygnaGV4Jyk7XG4gIH07XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiaXRnb0tleVhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0szdHBXQkhXZTMxc0xvWE5SUTlBdlJZSmdpdGtLeFE0QVRGUU13dnI3aEhOcVlSVW5TN1BzanpCN2FLMVZ4cUhMdU5Ramoxc2NrSjJKd28ycXhtc3ZlandFQ1NwRk1mQyc7XG4gICAgY29uc3QgYml0Z29LZXkgPSBiaXAzMi5mcm9tQmFzZTU4KGJpdGdvS2V5WHBydik7XG4gICAgaWYgKCFiaXRnb0tleS5wcml2YXRlS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByaXZhdGVLZXknKTtcbiAgICB9XG4gICAgY29uc3QgYml0Z29YcHViID0gYml0Z29LZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpO1xuICAgIGhvcFR4Qml0Z29TaWduYXR1cmUgPVxuICAgICAgJzB4YWEnICtcbiAgICAgIEJ1ZmZlci5mcm9tKHNlY3AyNTZrMS5lY2RzYVNpZ24oQnVmZmVyLmZyb20oaG9wVHhpZC5zbGljZSgyKSwgJ2hleCcpLCBiaXRnb0tleS5wcml2YXRlS2V5KS5zaWduYXR1cmUpLnRvU3RyaW5nKFxuICAgICAgICAnaGV4J1xuICAgICAgKTtcblxuICAgIGNvbnN0IGVudiA9ICd0ZXN0JztcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBFcmMyMFRva2VuLmNyZWF0ZVRva2VuQ29uc3RydWN0b3JzKCkuZm9yRWFjaCgoeyBuYW1lLCBjb2luQ29uc3RydWN0b3IgfSkgPT4ge1xuICAgICAgYml0Z28uc2FmZVJlZ2lzdGVyKG5hbWUsIGNvaW5Db25zdHJ1Y3Rvcik7XG4gICAgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0ZXRoJywgVGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCdodGV0aCcsIEh0ZXRoLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBjb21tb24uRW52aXJvbm1lbnRzW2Vudl0uaHNtWHB1YiA9IGJpdGdvWHB1YjtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBkZXNjcmliZSgnRUlQMTU1OScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHNpZ24gYSB0cmFuc2FjdGlvbiB3aXRoIEVJUDE1NTkgZmVlIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgY29uc3QgdXNlcktleWNoYWluID0ge1xuICAgICAgICBwcnY6ICd4cHJ2OXMyMVpyUUgxNDNLM2hla3lOajdUY2lSNFhOWWUxa01qNjhXMmlwakpHTkhFVFdQN280MkFqRG5TUGdLaGRaNHg4TkJBdmFMNzJSclhqdVhOZG1rTXFMRVJaemE3M29ZdWdHdGJMRlhHOGcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR0JqRTVRRzdwa2Y5Y1pEMzNVVUQ2SzQ2cTdFTHJidUc3RnFYZkxOR2lYWUdIZUVuR0JiNUFXUkVuazFlQTI4ZzhBclp2VVJiaHNoWFdrVHRkZEhSbzU0Zmd5VnZMZGInLFxuICAgICAgICByYXdQdWI6ICcwMjM2MzZlNjhiN2IyMDQ1NzNhYmRhMjYxNmFmZjZiNTg0OTEwZGVjZTI1NDNmMWNjNmQ4NDJjYWFjN2Q3NDk3NGInLFxuICAgICAgICByYXdQcnY6ICc3NDM4YTUwMDEwY2U3YjFkZmQ4NmU2ODA0NmNjNzhiYTFlYmQyNDJkNmQ4NWQ5OTA0ZDNmY2MwODczNGJjMTcyJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwLCBtYXhGZWVQZXJHYXM6IDEwIH0sXG4gICAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhbW91bnQ6ICc0MicsXG4gICAgICAgICAgICAgIGFkZHJlc3M6ICcweGM5M2IxMzY0MmQ5M2I0MjE4YmI4NWY2NzMxN2Q2YjM3Mjg2ZTgwMjgnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGV4cGlyZVRpbWU6IDE2Mjc5NDkyMTQsXG4gICAgICAgICAgY29udHJhY3RTZXF1ZW5jZUlkOiAxMixcbiAgICAgICAgICBnYXNMaW1pdDogdW5kZWZpbmVkLFxuICAgICAgICAgIGdhc1ByaWNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgaG9wVHJhbnNhY3Rpb246IHVuZGVmaW5lZCxcbiAgICAgICAgICBiYWNrdXBLZXlOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICAgIHNlcXVlbmNlSWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IHVzZXJLZXljaGFpbi5wcnYsXG4gICAgICB9IGFzIGFueSk7XG5cbiAgICAgIChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLmVpcDE1NTkubWF4UHJpb3JpdHlGZWVQZXJHYXMuc2hvdWxkLmVxdWFsKDEwKTtcbiAgICAgIChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLmVpcDE1NTkubWF4RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgxMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gYSB0cmFuc2FjdGlvbiB3aXRoIEVJUDE1NTkgZmVlIHBhcmFtcyBmb3IgQ0NSJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBzaWduVHJhbnNhY3Rpb24gPSBzaW5vbi5zcHkoQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMucHJvdG90eXBlLCAnc2lnblRyYW5zYWN0aW9uJyk7XG5cbiAgICAgIGNvbnN0IHVzZXJLZXljaGFpbiA9IHtcbiAgICAgICAgcHJ2OiAneHBydjlzMjFaclFIMTQzSzNoZWt5Tmo3VGNpUjRYTlllMWtNajY4VzJpcGpKR05IRVRXUDdvNDJBakRuU1BnS2hkWjR4OE5CQXZhTDcyUnJYanVYTmRta01xTEVSWnphNzNvWXVnR3RiTEZYRzhnJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dCakU1UUc3cGtmOWNaRDMzVVVENks0NnE3RUxyYnVHN0ZxWGZMTkdpWFlHSGVFbkdCYjVBV1JFbmsxZUEyOGc4QXJadlVSYmhzaFhXa1R0ZGRIUm81NGZneVZ2TGRiJyxcbiAgICAgICAgcmF3UHViOiAnMDIzNjM2ZTY4YjdiMjA0NTczYWJkYTI2MTZhZmY2YjU4NDkxMGRlY2UyNTQzZjFjYzZkODQyY2FhYzdkNzQ5NzRiJyxcbiAgICAgICAgcmF3UHJ2OiAnNzQzOGE1MDAxMGNlN2IxZGZkODZlNjgwNDZjYzc4YmExZWJkMjQyZDZkODVkOTkwNGQzZmNjMDg3MzRiYzE3MicsXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICBnYXNMaW1pdDogJzEwMDAnLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBrZXkgPSB0ZXN0RGF0YS5LRVlQQUlSX1BSVi5nZXRLZXlzKCkucHJ2IGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IHR4QnVpbGRlci50cmFuc2ZlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcbiAgICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgICAuYW1vdW50KCcwJylcbiAgICAgICAgLnRvKCcweDE5NjQ1MDMyYzdmMTUzMzM5NWQ0NGE2Mjk0NjJlNzUxMDg0ZDNlNGMnKVxuICAgICAgICAuZXhwaXJhdGlvblRpbWUoMTU5MDA2NjcyOClcbiAgICAgICAgLmNvbnRyYWN0U2VxdWVuY2VJZCg1KVxuICAgICAgICAua2V5KGtleSk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3QoYWRkcmVzczEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgY29uc3QgaGFsZlNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhQcmlvcml0eUZlZVBlckdhczogMTAsIG1heEZlZVBlckdhczogMTAgfSxcbiAgICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFtb3VudDogJzQyJyxcbiAgICAgICAgICAgICAgYWRkcmVzczogJzB4YzkzYjEzNjQyZDkzYjQyMThiYjg1ZjY3MzE3ZDZiMzcyODZlODAyOCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZXhwaXJlVGltZTogMTYyNzk0OTIxNCxcbiAgICAgICAgICBjb250cmFjdFNlcXVlbmNlSWQ6IDEyLFxuICAgICAgICAgIGdhc0xpbWl0OiB1bmRlZmluZWQsXG4gICAgICAgICAgZ2FzUHJpY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBob3BUcmFuc2FjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgICAgIGJhY2t1cEtleU5vbmNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgc2VxdWVuY2VJZDogdW5kZWZpbmVkLFxuICAgICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgICAgdHhIZXg6IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCksXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogdXNlcktleWNoYWluLnBydixcbiAgICAgICAgaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeTogdHJ1ZSxcbiAgICAgIH0gYXMgYW55KTtcblxuICAgICAgYXNzZXJ0KChoYWxmU2lnbmVkVHJhbnNhY3Rpb24gYXMgYW55KS5oYWxmU2lnbmVkLnR4SGV4KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCgoaGFsZlNpZ25lZFRyYW5zYWN0aW9uIGFzIGFueSkuaGFsZlNpZ25lZC5laXAxNTU5Lm1heEZlZVBlckdhcywgMTApO1xuXG4gICAgICBzYW5kYm94LmFzc2VydC5jYWxsZWRPbmNlKHNpZ25UcmFuc2FjdGlvbik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBWZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBiYXRjaCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMzUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IChjb2luPy5zdGF0aWNzQ29pbj8ubmV0d29yayBhcyBFdGhlcmV1bU5ldHdvcmspLmJhdGNoZXJDb250cmFjdEFkZHJlc3MgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBFTlMgYWRkcmVzcyByZXNvbHV0aW9uIGNoYW5naW5nIHJlY2lwaWVudCBhZGRyZXNzIGluIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAnYml0Z290ZXN0d2FsbGV0LmV0aCcgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6ICcweDQwYTY2Mzk2MzgxMDQ0OWQ2ZTcyNTMzNjU3YTc0ZjExMmMzYjkwMWEnIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zLFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIGhvcCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB0aGF0IG1hdGNoZXMgdGhlIGNsaWVudCB0eFBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogMTAwMDAwMDAwMDAwMDAwMCwgYWRkcmVzczogaG9wRGVzdGluYXRpb25BZGRyZXNzIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgaG9wOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnNTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcENvbnRyYWN0QWRkcmVzcyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMjc3MzkyODE5NicsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBjbGllbnQgdHhQYXJhbXMgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbnVsbDtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCB0eFByZWJ1aWxkIHRoYXQgaXMgYm90aCBiYXRjaCBhbmQgaG9wJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzM1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICAgIGhvcFRyYW5zYWN0aW9uOiB7XG4gICAgICAgICAgdHg6IGhvcFR4LFxuICAgICAgICAgIGlkOiBob3BUeGlkLFxuICAgICAgICAgIHNpZ25hdHVyZTogaG9wVHhCaXRnb1NpZ25hdHVyZSxcbiAgICAgICAgICBwYXltZW50SWQ6ICcyNzczOTI4MTk2JyxcbiAgICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICByZWNpcGllbnQ6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBub25jZTogMCxcbiAgICAgICAgICB1c2VyUmVxU2lnOiB1c2VyUmVxU2lnLFxuICAgICAgICAgIGdhc1ByaWNlTWF4OiA1MDAwMDAwMDAwMDAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0eCBjYW5ub3QgYmUgYm90aCBhIGJhdGNoIGFuZCBob3AgdHJhbnNhY3Rpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCB3aXRoIG1vcmUgdGhhbiBvbmUgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgYHRldGggZG9lc24ndCBzdXBwb3J0IHNlbmRpbmcgdG8gbW9yZSB0aGFuIDEgZGVzdGluYXRpb24gYWRkcmVzcyB3aXRoaW4gYSBzaW5nbGUgdHJhbnNhY3Rpb24uIFRyeSBhZ2FpbiwgdXNpbmcgb25seSBhIHNpbmdsZSByZWNpcGllbnQuYFxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBob3AgdHhQcmVidWlsZCB0aGF0IGRvZXMgbm90IHNlbmQgdG8gaXRzIGhvcCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzUwMDAwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMCcsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBob3AgYWRkcmVzcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBiYXRjaCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyB0b3RhbCBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzU1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAoY29pbj8uc3RhdGljc0NvaW4/Lm5ldHdvcmsgYXMgRXRoZXJldW1OZXR3b3JrKS5iYXRjaGVyQ29udHJhY3RBZGRyZXNzIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnYmF0Y2ggdHJhbnNhY3Rpb24gYW1vdW50IGluIHR4UHJlYnVpbGQgcmVjZWl2ZWQgZnJvbSBCaXRHbyBzZXJ2ZXJzIGRvZXMgbm90IG1hdGNoIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCdcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgYmF0Y2ggdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBkb2VzIG5vdCBzZW5kIHRvIHRoZSBiYXRjaGVyIGNvbnRyYWN0IGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzM1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBob3BDb250cmFjdEFkZHJlc3MgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncmVjaXBpZW50IGFkZHJlc3Mgb2YgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCBiYXRjaGVyIGFkZHJlc3MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbm9ybWFsIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcyMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ25vcm1hbCB0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCByZWNlaXZlZCBmcm9tIEJpdEdvIHNlcnZlcnMgZG9lcyBub3QgbWF0Y2ggdHhQYXJhbXMgc3VwcGxpZWQgYnkgY2xpZW50J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBub3JtYWwgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgcmVjaXBpZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAnZGVzdGluYXRpb24gYWRkcmVzcyBpbiBub3JtYWwgdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCB0aGF0IGluIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCdcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdG9rZW4gdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGVzdCcpO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB0b2tlbjogJ3Rlc3QnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyBjb2luJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ2J0YycsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdjb2luIGluIHR4UHJlYnVpbGQgZGlkIG5vdCBtYXRjaCB0aGF0IGluIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVFNTIFRyYW5zYWN0aW9uIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBleHBlY3REZWZpUmVqZWN0aW9uID0gYXN5bmMgKHA6IFByb21pc2U8dW5rbm93bj4sIG1lc3NhZ2VQYXR0ZXJuOiBSZWdFeHApID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHA7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgZXJyLnNob3VsZC5iZS5pbnN0YW5jZU9mKFR4SW50ZW50TWlzbWF0Y2hSZWNpcGllbnRFcnJvcik7XG4gICAgICAgIChlcnIgYXMgRXJyb3IpLm1lc3NhZ2Uuc2hvdWxkLm1hdGNoKG1lc3NhZ2VQYXR0ZXJuKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHBlY3RlZCB2ZXJpZnlUcmFuc2FjdGlvbiB0byBiZSByZWplY3RlZCwgYnV0IGl0IHJlc29sdmVkJyk7XG4gICAgfTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHdoZW4gdHhQcmVidWlsZCBoYXMgY29uc29saWRhdGVJZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIHR4UGFyYW1zIHdpdGhvdXQgcmVjaXBpZW50cyAoYXMgaW4gY29uc29saWRhdGlvbiBmbG93KVxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgLy8gdHhQcmVidWlsZCB3aXRoIGNvbnNvbGlkYXRlSWQgKHNldCBieSBzZXJ2ZXIgZHVyaW5nIGNvbnNvbGlkYXRpb24gYnVpbGQpXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhhN2Q1ZDBjNjZlNzRlMjE2Yjk3MTczYmQ1NThjNmQnLFxuICAgICAgICB0eEhleDogJzB4JyxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdoZW4gdHhQYXJhbXMudHlwZSBpcyBjb25zb2xpZGF0ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnY29uc29saWRhdGUnLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiAnMHgnLFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBUU1MgdHJhbnNhY3Rpb24gd2hlbiB0eFBhcmFtcy5wcmVidWlsZFR4IGhhcyBjb25zb2xpZGF0ZUlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBwcmVidWlsZFR4OiB7XG4gICAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiAnMHgnLFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBUU1MgdHJhbnNhY3Rpb24gd2l0aG91dCByZWNpcGllbnRzLCBjb25zb2xpZGF0ZUlkLCBvciB2YWxpZCB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyB0eFBhcmFtcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdpdGggYWNjZWxlcmF0aW9uIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgdHlwZTogJ2FjY2VsZXJhdGlvbicsXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIGZpbGxOb25jZSB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6ICdmaWxsTm9uY2UnLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiAnMHgnLFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB0eFBhcmFtcyBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBUU1MgdHJhbnNhY3Rpb24gd2l0aCBkZWZpQXBwcm92ZSB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgLy8gRGVGaSBkZXBvc2l0IGZsb3cgaXMgaW50ZW50LWJhc2VkOiByZWNpcGllbnRzL2NhbGxkYXRhIGFyZSBidWlsdCBzZXJ2ZXItc2lkZVxuICAgICAgLy8gZnJvbSBkZWZpUGFyYW1zLCBzbyB0eFBhcmFtcyBoYXMgbm8gcmVjaXBpZW50cyAoc2VlIENHRC0xODE1KS5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnZGVmaUFwcHJvdmUnLFxuICAgICAgICBkZWZpUGFyYW1zOiB7IHZhdWx0SWQ6ICdodGV0aC11c2RjLXRlc3QnLCBhbW91bnQ6ICcxMCcgfSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczEsICcxMCddKSksXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIHdyYXBBcHByb3ZlIHR5cGUgYW5kIG5vIHJlY2lwaWVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFdQIGRlcml2ZXMgdGhlIHVuZGVybHlpbmcgdG9rZW4gY29udHJhY3QsIHdyYXBwZXIgc3BlbmRlciwgYW5kIGFwcHJvdmVcbiAgICAgIC8vIGNhbGxkYXRhIGZyb20gdG9rZW5OYW1lIGFuZCBhbW91bnQsIHNvIHRoZSBjbGllbnQgaW50ZW50IGhhcyBubyByZWNpcGllbnRzLlxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHR5cGU6ICd3cmFwQXBwcm92ZScsXG4gICAgICAgIHRva2VuTmFtZTogJ2h0ZXRoOmN1c2R0JyxcbiAgICAgICAgYW1vdW50OiAnMTAwMDAwMCcsXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6ICcweCcsXG4gICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuXG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgVFNTIHRyYW5zYWN0aW9uIHdpdGggZGVmaURlcG9zaXQgdHlwZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnZGVmaURlcG9zaXQnLFxuICAgICAgICBkZWZpUGFyYW1zOiB7IHZhdWx0SWQ6ICdodGV0aC11c2RjLXRlc3QnLCBhbW91bnQ6ICcxMCcsIG9wZXJhdGlvbklkOiAnZmFrZU9wZXJhdGlvbklkJyB9LFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkZWZpQ2FsbGRhdGEoJ2RlcG9zaXQodWludDI1NixhZGRyZXNzKScsIFsnMTAnLCBhZGRyZXNzMV0pKSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgRGVGaSBjYWxsZGF0YSB0aGF0IHJlZGlyZWN0cyBmdW5kcyBvciBncmFudHMgZXhjZXNzIGFwcHJvdmFsJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgIGNvbnN0IHZlcmlmeSA9IGFzeW5jICh0eXBlOiBzdHJpbmcsIGRlZmlQYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLCBkYXRhOiBzdHJpbmcpID0+XG4gICAgICAgIGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7IHR5cGUsIGRlZmlQYXJhbXMsIHdhbGxldCB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkYXRhKSwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KTtcblxuICAgICAgLy8gZGVmaUFwcHJvdmU6IGF0dGFja2VyIGFwcHJvdmUoYXR0YWNrZXIsIE1BWF9VSU5UMjU2KSBkaXNndWlzZWQgYXMgZGVmaUFwcHJvdmVcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeShcbiAgICAgICAgICAnZGVmaUFwcHJvdmUnLFxuICAgICAgICAgIHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgICAgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczIsICcxMDAwMDAwMDAwMDAwMDAwMDAwJ10pXG4gICAgICAgICksXG4gICAgICAgIC9hbW91bnQgZG9lcyBub3QgbWF0Y2gvXG4gICAgICApO1xuICAgICAgLy8gZGVmaURlcG9zaXQ6IGZ1bmRzIHJlZGlyZWN0ZWQgdG8gYXR0YWNrZXIgcmVjZWl2ZXJcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeShcbiAgICAgICAgICAnZGVmaURlcG9zaXQnLFxuICAgICAgICAgIHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgICAgZGVmaUNhbGxkYXRhKCdkZXBvc2l0KHVpbnQyNTYsYWRkcmVzcyknLCBbJzEwJywgYWRkcmVzczJdKVxuICAgICAgICApLFxuICAgICAgICAvcmVjZWl2ZXIgZG9lcyBub3QgbWF0Y2gvXG4gICAgICApO1xuICAgICAgLy8gZGVmaVdpdGhkcmF3OiByZWNlaXZlciBhbmQgb3duZXIgYm90aCBhdHRhY2tlclxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KFxuICAgICAgICAgICdkZWZpV2l0aGRyYXcnLFxuICAgICAgICAgIHsgdmF1bHRJZDogJ3ZhdWx0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgICAgZGVmaUNhbGxkYXRhKCdyZWRlZW0odWludDI1NixhZGRyZXNzLGFkZHJlc3MpJywgWyc1JywgYWRkcmVzczIsIGFkZHJlc3MyXSlcbiAgICAgICAgKSxcbiAgICAgICAgL3JlY2VpdmVyIGFuZCBvd25lci9cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBEZUZpIGNhbGxkYXRhIHdpdGggd3Jvbmcgc2VsZWN0b3IsIHdyb25nIG93bmVyIGFsb25lLCBvciB3cm9uZyBkZXBvc2l0IGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IGFkZHJlc3MxIH0gfSk7XG4gICAgICBjb25zdCB2ZXJpZnkgPSBhc3luYyAodHlwZTogc3RyaW5nLCBkZWZpUGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgZGF0YTogc3RyaW5nKSA9PlxuICAgICAgICBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogeyB0eXBlLCBkZWZpUGFyYW1zLCB3YWxsZXQgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogeyB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoZGF0YSksIGNvaW46ICdodGV0aCcsIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7fSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBkZWZpUGFyYW1zID0geyB2YXVsdElkOiAndmF1bHQnLCBhbW91bnQ6ICcxMCcgfTtcblxuICAgICAgLy8gZGVmaUFwcHJvdmUgd2l0aCBhIG5vbi1hcHByb3ZlIHNlbGVjdG9yICh0cmFuc2ZlciBkaXNndWlzZWQgYXMgYXBwcm92ZSlcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeSgnZGVmaUFwcHJvdmUnLCBkZWZpUGFyYW1zLCBkZWZpQ2FsbGRhdGEoJ3RyYW5zZmVyKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczIsICcxMCddKSksXG4gICAgICAgIC9hcHByb3ZlXFwoYWRkcmVzcyx1aW50MjU2XFwpL1xuICAgICAgKTtcbiAgICAgIC8vIGRlZmlEZXBvc2l0IHdpdGggYSBub24tZGVwb3NpdCBzZWxlY3RvclxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KCdkZWZpRGVwb3NpdCcsIGRlZmlQYXJhbXMsIGRlZmlDYWxsZGF0YSgnYXBwcm92ZShhZGRyZXNzLHVpbnQyNTYpJywgW2FkZHJlc3MxLCAnMTAnXSkpLFxuICAgICAgICAvZGVwb3NpdFxcKHVpbnQyNTYsYWRkcmVzc1xcKS9cbiAgICAgICk7XG4gICAgICAvLyBkZWZpV2l0aGRyYXcgd2l0aCBhIG5vbi1yZWRlZW0gc2VsZWN0b3JcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeSgnZGVmaVdpdGhkcmF3JywgZGVmaVBhcmFtcywgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczEsICcxMCddKSksXG4gICAgICAgIC9yZWRlZW1cXCh1aW50MjU2LGFkZHJlc3MsYWRkcmVzc1xcKS9cbiAgICAgICk7XG4gICAgICAvLyBkZWZpV2l0aGRyYXc6IHJlY2VpdmVyIG9rIGJ1dCBvd25lciBpcyBhdHRhY2tlclxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KCdkZWZpV2l0aGRyYXcnLCBkZWZpUGFyYW1zLCBkZWZpQ2FsbGRhdGEoJ3JlZGVlbSh1aW50MjU2LGFkZHJlc3MsYWRkcmVzcyknLCBbJzEwJywgYWRkcmVzczEsIGFkZHJlc3MyXSkpLFxuICAgICAgICAvcmVjZWl2ZXIgYW5kIG93bmVyL1xuICAgICAgKTtcbiAgICAgIC8vIGRlZmlXaXRoZHJhdzogcmVjZWl2ZXIgYW5kIG93bmVyIG9rIGJ1dCBzaGFyZXMgZG8gbm90IG1hdGNoIGRlZmlQYXJhbXMuYW1vdW50XG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoXG4gICAgICAgICAgJ2RlZmlXaXRoZHJhdycsXG4gICAgICAgICAgZGVmaVBhcmFtcyxcbiAgICAgICAgICBkZWZpQ2FsbGRhdGEoJ3JlZGVlbSh1aW50MjU2LGFkZHJlc3MsYWRkcmVzcyknLCBbJzk5OScsIGFkZHJlc3MxLCBhZGRyZXNzMV0pXG4gICAgICAgICksXG4gICAgICAgIC9zaGFyZXMgZG8gbm90IG1hdGNoL1xuICAgICAgKTtcbiAgICAgIC8vIGRlZmlEZXBvc2l0OiByZWNlaXZlciBvayBidXQgYW1vdW50IG1pc21hdGNoXG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoJ2RlZmlEZXBvc2l0JywgZGVmaVBhcmFtcywgZGVmaUNhbGxkYXRhKCdkZXBvc2l0KHVpbnQyNTYsYWRkcmVzcyknLCBbJzk5OScsIGFkZHJlc3MxXSkpLFxuICAgICAgICAvYW1vdW50IGRvZXMgbm90IG1hdGNoL1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBjbG9zZWQgd2hlbiBkZWZpIGludGVudCBwYXJhbWV0ZXJzIGFyZSBtaXNzaW5nIG9yIGNhbGxkYXRhIGlzIHNob3J0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgIGNvbnN0IHZlcmlmeSA9IGFzeW5jICh0eXBlOiBzdHJpbmcsIGRlZmlQYXJhbXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLCBkYXRhOiBzdHJpbmcpID0+XG4gICAgICAgIGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7IHR5cGUsIGRlZmlQYXJhbXMsIHdhbGxldCB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7IHR4SGV4OiBhd2FpdCBidWlsZERlZmlUeEhleChkYXRhKSwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9KTtcblxuICAgICAgLy8gTWlzc2luZyBkZWZpUGFyYW1zIGZvciBlYWNoIGRlZmkgdHlwZSAtPiBmYWlsIGNsb3NlZFxuICAgICAgYXdhaXQgZXhwZWN0RGVmaVJlamVjdGlvbihcbiAgICAgICAgdmVyaWZ5KCdkZWZpQXBwcm92ZScsIHVuZGVmaW5lZCwgZGVmaUNhbGxkYXRhKCdhcHByb3ZlKGFkZHJlc3MsdWludDI1NiknLCBbYWRkcmVzczEsICcxMCddKSksXG4gICAgICAgIC9taXNzaW5nIHJlcXVpcmVkIGludGVudCBwYXJhbWV0ZXJzL1xuICAgICAgKTtcbiAgICAgIGF3YWl0IGV4cGVjdERlZmlSZWplY3Rpb24oXG4gICAgICAgIHZlcmlmeSgnZGVmaURlcG9zaXQnLCB1bmRlZmluZWQsIGRlZmlDYWxsZGF0YSgnZGVwb3NpdCh1aW50MjU2LGFkZHJlc3MpJywgWycxMCcsIGFkZHJlc3MxXSkpLFxuICAgICAgICAvbWlzc2luZyByZXF1aXJlZCBpbnRlbnQgcGFyYW1ldGVycy9cbiAgICAgICk7XG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoJ2RlZmlXaXRoZHJhdycsIHVuZGVmaW5lZCwgZGVmaUNhbGxkYXRhKCdyZWRlZW0odWludDI1NixhZGRyZXNzLGFkZHJlc3MpJywgWyc1JywgYWRkcmVzczEsIGFkZHJlc3MxXSkpLFxuICAgICAgICAvbWlzc2luZyByZXF1aXJlZCBpbnRlbnQgcGFyYW1ldGVycy9cbiAgICAgICk7XG4gICAgICAvLyBTaG9ydC9lbXB0eSBjYWxsZGF0YSB3aXRoIG5vIHZhbGlkIHNlbGVjdG9yIHByZWZpeCAtPiBzZWxlY3RvciBtaXNtYXRjaCAoZmFpbCBjbG9zZWQpXG4gICAgICBhd2FpdCBleHBlY3REZWZpUmVqZWN0aW9uKFxuICAgICAgICB2ZXJpZnkoJ2RlZmlBcHByb3ZlJywgeyB2YXVsdElkOiAndmF1bHQnLCBhbW91bnQ6ICcxMCcgfSwgJzB4JyksXG4gICAgICAgIC9hcHByb3ZlXFwoYWRkcmVzcyx1aW50MjU2XFwpL1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IFRTUyB0cmFuc2FjdGlvbiB3aXRoIGRlZmlXaXRoZHJhdyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogYWRkcmVzczEgfSB9KTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICB0eXBlOiAnZGVmaVdpdGhkcmF3JyxcbiAgICAgICAgZGVmaVBhcmFtczogeyB2YXVsdElkOiAnaHRldGgtdXNkYy10ZXN0JywgYW1vdW50OiAnMTAnIH0sXG4gICAgICAgIHdhbGxldCxcbiAgICAgIH07XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogYXdhaXQgYnVpbGREZWZpVHhIZXgoZGVmaUNhbGxkYXRhKCdyZWRlZW0odWludDI1NixhZGRyZXNzLGFkZHJlc3MpJywgWycxMCcsIGFkZHJlc3MxLCBhZGRyZXNzMV0pKSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgICB2ZXJpZmljYXRpb246IHt9LFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzcyB2ZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBjb25zb2xpZGF0aW9uIHdoZW4gcmVjaXBpZW50IG1hdGNoZXMgYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcblxuICAgICAgICAvLyBCdWlsZCBhIHJlYWwgdHJhbnNhY3Rpb24gdGhhdCBzZW5kcyB0byB0aGUgYmFzZUFkZHJlc3NcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TaW5nbGVTaWdTZW5kKTtcbiAgICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAnLFxuICAgICAgICAgIGdhc0xpbWl0OiAnMjEwMDAnLFxuICAgICAgICB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICAgIHR4QnVpbGRlci5jb250cmFjdChiYXNlQWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci52YWx1ZSgnMTAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHR5cGU6ICdjb25zb2xpZGF0ZScsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgICAgdHhIZXg6IHR4SGV4LFxuICAgICAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHtcbiAgICAgICAgICBjb25zb2xpZGF0aW9uVG9CYXNlQWRkcmVzczogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH0pO1xuICAgICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGNvbnNvbGlkYXRpb24gd2hlbiByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgICAgY29uc3Qgd3JvbmdSZWNpcGllbnQgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcblxuICAgICAgICAvLyBCdWlsZCBhIHRyYW5zYWN0aW9uIHRoYXQgc2VuZHMgdG8gYSBESUZGRVJFTlQgYWRkcmVzcyAobm90IGJhc2VBZGRyZXNzKVxuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKCdodGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNpbmdsZVNpZ1NlbmQpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgICBmZWU6ICcxMCcsXG4gICAgICAgICAgZ2FzTGltaXQ6ICcyMTAwMCcsXG4gICAgICAgIH0pO1xuICAgICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KHdyb25nUmVjaXBpZW50KTtcbiAgICAgICAgdHhCdWlsZGVyLnZhbHVlKCcxMDAwMDAwMDAwMDAwMDAwMDAwJyk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgICAgdHlwZTogJ2NvbnNvbGlkYXRlJyxcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgICAgY29uc29saWRhdGVJZDogJzY4YTdkNWQwYzY2ZTc0ZTIxNmI5NzE3M2JkNTU4YzZkJyxcbiAgICAgICAgICB0eEhleDogdHhIZXgsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQ29uc29saWRhdGlvbiB0cmFuc2FjdGlvbiByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggd2FsbGV0IGJhc2UgYWRkcmVzcycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiB0eEhleCBpcyBtaXNzaW5nIGZvciBjb25zb2xpZGF0aW9uIHZlcmlmaWNhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge1xuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICAgIHR5cGU6ICdjb25zb2xpZGF0ZScsXG4gICAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGE3ZDVkMGM2NmU3NGUyMTZiOTcxNzNiZDU1OGM2ZCcsXG4gICAgICAgICAgLy8gSW50ZW50aW9uYWxseSBtaXNzaW5nIHR4SGV4XG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSxcbiAgICAgICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyB0eEhleCBpbiB0eFByZWJ1aWxkJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgRVJDMjAgdG9rZW4gY29uc29saWRhdGlvbiB3aGVuIGNhbGxkYXRhIHJlY2lwaWVudCBtYXRjaGVzIGJhc2UgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG4gICAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyZXNzID0gJzB4YTBiODY5OTFjNjIxOGIzNmMxZDE5ZDRhMmU5ZWIwY2UzNjA2ZWI0OCc7XG5cbiAgICAgICAgLy8gQnVpbGQgYW4gRVJDMjAgdHJhbnNmZXIoYWRkcmVzcywgdWludDI1NikgdHgg4oCUIG1pbWljcyB3aGF0IHRoZSBzZXJ2ZXIgcmV0dXJuc1xuICAgICAgICAvLyBmb3IgYSB2NiBUU1Mgd2FsbGV0IHRva2VuIGNvbnNvbGlkYXRpb246IHR4SnNvbi50byA9IHRva2VuIGNvbnRyYWN0LFxuICAgICAgICAvLyBhY3R1YWwgcmVjaXBpZW50IGlzIGVuY29kZWQgaW4gdGhlIDB4YTkwNTljYmIgY2FsbGRhdGFcbiAgICAgICAgY29uc3QgbWV0aG9kSWQgPSBFdGhlcmV1bUFiaS5tZXRob2RJRCgndHJhbnNmZXInLCBbJ2FkZHJlc3MnLCAndWludDI1NiddKTtcbiAgICAgICAgY29uc3QgZW5jb2RlZFBhcmFtcyA9IEV0aGVyZXVtQWJpLnJhd0VuY29kZShbJ2FkZHJlc3MnLCAndWludDI1NiddLCBbYmFzZUFkZHJlc3MsICcxMDAwMDAwMCddKTtcbiAgICAgICAgY29uc3QgZXJjMjBUcmFuc2ZlckRhdGEgPSAnMHgnICsgQnVmZmVyLmNvbmNhdChbbWV0aG9kSWQsIGVuY29kZWRQYXJhbXNdKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcignaHRldGgnKSBhcyBUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGwpO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAnLCBnYXNMaW1pdDogJzYwMDAwJyB9KTtcbiAgICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICAgIHR4QnVpbGRlci5jb250cmFjdCh0b2tlbkNvbnRyYWN0QWRkcmVzcyk7XG4gICAgICAgIHR4QnVpbGRlci5kYXRhKGVyYzIwVHJhbnNmZXJEYXRhKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3MgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2NvbnNvbGlkYXRlJywgd2FsbGV0LCB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZScgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogeyBjb25zb2xpZGF0ZUlkOiAnYWJjMTIzJywgdHhIZXgsIGNvaW46ICdodGV0aCcsIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyB9IGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgdmVyaWZpY2F0aW9uOiB7IGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlIH0sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH0pO1xuICAgICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IEVSQzIwIHRva2VuIGNvbnNvbGlkYXRpb24gd2hlbiBjYWxsZGF0YSByZWNpcGllbnQgZG9lcyBub3QgbWF0Y2ggYmFzZSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHgxNzRjZmQ4MjNhZjhjZTI3ZWQwYWZlZTNmY2YzYzNiYTI1OTExNmJlJztcbiAgICAgICAgY29uc3Qgd3JvbmdSZWNpcGllbnQgPSAnMHg3ZTg1YmRjMjdjMDUwZTM5MDVlYmY0YjhlNjM0ZDlhZDZlZGQwZGU2JztcbiAgICAgICAgY29uc3QgdG9rZW5Db250cmFjdEFkZHJlc3MgPSAnMHhhMGI4Njk5MWM2MjE4YjM2YzFkMTlkNGEyZTllYjBjZTM2MDZlYjQ4JztcblxuICAgICAgICAvLyBCdWlsZCBhbiBFUkMyMCB0cmFuc2ZlciB3aGVyZSBjYWxsZGF0YSByZWNpcGllbnQgaXMgYSBXUk9ORyBhZGRyZXNzXG4gICAgICAgIGNvbnN0IG1ldGhvZElkID0gRXRoZXJldW1BYmkubWV0aG9kSUQoJ3RyYW5zZmVyJywgWydhZGRyZXNzJywgJ3VpbnQyNTYnXSk7XG4gICAgICAgIGNvbnN0IGVuY29kZWRQYXJhbXMgPSBFdGhlcmV1bUFiaS5yYXdFbmNvZGUoWydhZGRyZXNzJywgJ3VpbnQyNTYnXSwgW3dyb25nUmVjaXBpZW50LCAnMTAwMDAwMDAnXSk7XG4gICAgICAgIGNvbnN0IGVyYzIwVHJhbnNmZXJEYXRhID0gJzB4JyArIEJ1ZmZlci5jb25jYXQoW21ldGhvZElkLCBlbmNvZGVkUGFyYW1zXSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsKTtcbiAgICAgICAgdHhCdWlsZGVyLmZlZSh7IGZlZTogJzEwJywgZ2FzTGltaXQ6ICc2MDAwMCcgfSk7XG4gICAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3QodG9rZW5Db250cmFjdEFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIuZGF0YShlcmMyMFRyYW5zZmVyRGF0YSk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIGNvbnN0IHR4SGV4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7XG4gICAgICAgICAgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgICAgdHhQYXJhbXM6IHsgdHlwZTogJ2NvbnNvbGlkYXRlJywgd2FsbGV0LCB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZScgfSBhcyBhbnksXG4gICAgICAgICAgICB0eFByZWJ1aWxkOiB7IGNvbnNvbGlkYXRlSWQ6ICdhYmMxMjMnLCB0eEhleCwgY29pbjogJ2h0ZXRoJywgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnIH0gYXMgYW55LFxuICAgICAgICAgICAgd2FsbGV0LFxuICAgICAgICAgICAgdmVyaWZpY2F0aW9uOiB7IGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlIH0sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHJlY2lwaWVudCBkb2VzIG5vdCBtYXRjaCB3YWxsZXQgYmFzZSBhZGRyZXNzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIHdhbGxldCBpcyBtaXNzaW5nIGJhc2VBZGRyZXNzIGZvciBjb25zb2xpZGF0aW9uIHZlcmlmaWNhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4MTc0Y2ZkODIzYWY4Y2UyN2VkMGFmZWUzZmNmM2MzYmEyNTkxMTZiZSc7XG5cbiAgICAgICAgLy8gQnVpbGQgYSByZWFsIHRyYW5zYWN0aW9uXG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgICB0eEJ1aWxkZXIudHlwZShUcmFuc2FjdGlvblR5cGUuU2luZ2xlU2lnU2VuZCk7XG4gICAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICAgIGZlZTogJzEwJyxcbiAgICAgICAgICBnYXNMaW1pdDogJzIxMDAwJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3QoYmFzZUFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIudmFsdWUoJzEwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3QgdHhIZXggPSB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICAgIC8vIFdhbGxldCB3aXRob3V0IGJhc2VBZGRyZXNzXG4gICAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHtcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgICB0eXBlOiAnY29uc29saWRhdGUnLFxuICAgICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjhhN2Q1ZDBjNjZlNzRlMjE2Yjk3MTczYmQ1NThjNmQnLFxuICAgICAgICAgIHR4SGV4OiB0eEhleCxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7XG4gICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgY29pblxuICAgICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgICB0eFBhcmFtczogdHhQYXJhbXMgYXMgYW55LFxuICAgICAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgICAgICB3YWxsZXQsXG4gICAgICAgICAgICB2ZXJpZmljYXRpb24sXG4gICAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdVbmFibGUgdG8gZGV0ZXJtaW5lIGJhc2UgYWRkcmVzcyBmb3IgY29uc29saWRhdGlvbicpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBZGRyZXNzIFZlcmlmaWNhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBkZXNjcmliZSgnaXNXYWxsZXRBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gYWRkcmVzcyBnZW5lcmF0ZWQgdXNpbmcgZm9yd2FyZGVyIHZlcnNpb24gMScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYxZDNjOWZjZThmNWFhNjkxNTY5YTk5ZWInLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dWYjNQZkN6d2lFWDk0QUIxbkpRdHpWbXNhNVNyaU5yZktaWkFjQXZSZ3hoMUF1Z202czh5b0Q4Z1NrcTJGZFo4WUNkVlhVZ0xqZjlReHZkWUFKSzVVdGhBbXBRc2hVJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYwYjc0ZTczYjFmNDQwZWE0YWNlZGE4N2UnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRjQ2cFJIZGEzc1pidVB6emE5QTlNaXFBVTlKUm9kOGh1WXR5VjROWTJvZUpYc2lzN3IyNkwxdm1MbnRmOUJjWkplMW00Q1FOU3ZZV2Z3cGUxaFNwbzZKNHg2WUYxZU4nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OGI5ZWM1ODdkMGJhMWM3NDQwZGU1NTEwNjhjMzZhNycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0d6VG41ZXlOR0RrYjE4UjQzbkg3OUhva1lMYzVQWFpNMTlWOFVyYnVMZFZSYUNRTXM0RWVDQWpucW1vWVhxZnl1c1RVNDZXb1pNRHlMcG1Uem9VWDY2WkJ3R0ZqdDFhJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHg2MDY5YTRiYWYyMzYwYmY2N2E2ZDAyYTdmYzQzZDhmMzkxMDAxNmFlJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZTEyNTNiY2NlN2Q4N2RiNTIyZmJjZWVjNmU1NWM5Zjc4YzM3NmQ5ZicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHg3JyxcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDcsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFuIGFkZHJlc3MgZ2VuZXJhdGVkIHVzaW5nIGZvcndhcmRlciB2ZXJzaW9uIDInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWU4YzdiM2M4YWFhNzkxMTE4ZDljZTYxNmQzYjIxJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHckN4Q1gzOXpiM1R2WWpUcWZVR3dFVVpIam5yYVJGbTFXZU13OWdmQ0Qxd3djMndVRG1CQloyVGtjY0pNd2Y1ZUJUamE4cjN6NkhNeG9UWkdXNm52eW9KTVFGc2VjdicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWU4YzdiMTk2N2ZkNmQ5ODY3YTIyYTFhNDEzMWEwJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dLaGRlQzRucjF0YThkMjd4VGh0ZkZGSGdieFdNclZiNTk1bWVNUzhpM2ZCTXJUejhFZFFNV0JLSEhLenhhcEdnaGVvTXltVnZSY1FtYUdEeWtSVEJidFhxYml1OXBzJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHelRuNWV5TkdEa2IxOFI0M25INzlIb2tZTGM1UFhaTTE5VjhVcmJ1TGRWUmFDUU1zNEVlQ0FqbnFtb1lYcWZ5dXNUVTQ2V29aTUR5THBtVHpvVVg2NlpCd0dGanQxYScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZjYzNmNlZGRmZmU0MWQxMDY1ODY4NzVjMGU1NmRjOGZlYjYyNjhmNycsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgc2FsdDogJzB4MTcnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICBpbmRleDogMjMsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyBhcyBhbnkpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgd2FsbGV0IHZlcnNpb24gNSBmb3J3YXJkZXIgdmVyc2lvbiA0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiAnNjkxZTI0MmQ5M2Y4ZDdhZDA3MDU4ODc0NDk3NjNjOTYnLFxuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWUyNDJkZjhiNjMyM2Q0YjA4ZGYzNjY4NjRhZjY2JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDJjOGE0OTZiMTZhYmZlMjU2NzUyMGEyNzllMjE1NDY0MmZjM2MwZTA4ZTYyOTc3NWNiNGQ4NDVjMGM1ZmJmNTVhYjdiYTE1M2U4ODZkZTY1NzQ4ZWQxOGY0ZmY4ZjVjZWUyMjQyZTY4NzM5OWVhMzI5N2ExZjU1MjRmZGVmZDU2YycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWUyNDJjMDU5NWI0Y2ZlZTZmOTU3YzFkNjQ1OGY3JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhkNjNiNWUyYjhkMWI0ZmJhMzYyNTQ2MDUwODkwMGJmMmEwNDk5YTRkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHg3NScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHdhbGxldCB2ZXJzaW9uIDYgZm9yd2FyZGVyIHZlcnNpb24gNScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZDU2NzM1ZTVlYjYxYjA2ZTM1M2ZlNzYzOScsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgYWRkcmVzczogJzB4YTMzZjA5NzVmNTNjZGNmY2MwY2I1NjRkMjVmYjViZTAzYjA2NTFjZicsXG4gICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNSxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gYWN0dWFsIGFkZHJlc3MgZGlmZmVycyBmcm9tIGV4cGVjdGVkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHgyODkwNDU5MWY3MzU5OTRmMDUwODA0ZmRhM2I2MWI4MTNiMTZlMDRjJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgdW5rbm93biBhcyBWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBjb2luU3BlY2lmaWMgZmllbGQgaXMgbm90IGFuIG9iamVjdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSksXG4gICAgICAgICAgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgdGhlIGRlcml2ZWQgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhlMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4YnZmJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYgYmFzZSBhZGRyZXNzIGlzIHVuZGVmaW5lZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zIGFzIGFueSksIEludmFsaWRBZGRyZXNzRXJyb3IpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGlmIGJhc2UgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZTBiNTZlZWFlMWIyODM5MThjYWNhMDJhMTRhZGEyZGYxN2E5OGJ2ZicsXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ01QQyB3YWxsZXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICAgJzAzZjljMmZiMmU1YThiNzhhNDRmNWQxZTRmOTA2ZjhlM2Q3YTBlNmI1YzRkM2UyZjFhMGI5YzhkN2U2ZjVhNGIzYzJkMWUwZjllOGQ3YzZiNWE0JyArXG4gICAgICAgICAgJzkzODI3MTYwNTk0ODU3NDYzNzI4MTkwYTBiMGMwZDBlMGYxMDExMTIxMzE0MTUxNjE3MTgxOTFhMWIxYzFkMWUxZic7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7IHB1YjogJ3VzZXJfcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgICB7IHB1YjogJ2JhY2t1cF9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYml0Z29fcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgXTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBhbiBNUEMgd2FsbGV0IGFkZHJlc3Mgd2l0aCBmb3J3YXJkZXIgdmVyc2lvbiAzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDAxMTUzZjNhZGZlNDU0YTcyNTg5Y2E5ZWY3NGYwMTNjMTllNTQ5NjEnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYW4gTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggZm9yd2FyZGVyIHZlcnNpb24gNScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHgwMTE1M2YzYWRmZTQ1NGE3MjU4OWNhOWVmNzRmMDEzYzE5ZTU0OTYxJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IE1QQyB3YWxsZXQgYWRkcmVzcyB3aXRoIHdyb25nIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDMsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgTVBDIHdhbGxldCBhZGRyZXNzIHdpdGggaW52YWxpZCBhZGRyZXNzIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHhpbnZhbGlkJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgaWYga2V5Y2hhaW5zIGFyZSBtaXNzaW5nIGZvciBNUEMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDllN2NlOGMyNGQ5Zjc2YTgxNGUyMzYzM2U2MWJlN2NiOGU2ZTJkNWUnLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMgYXMgYW55KSwgRXJyb3IpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBpZiBjb21tb25LZXljaGFpbiBpcyBtaXNzaW5nIGZvciBNUEMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgICAgIGNvbnN0IGludmFsaWRLZXljaGFpbnMgPSBbeyBwdWI6ICd1c2VyX3B1YicgfSwgeyBwdWI6ICdiYWNrdXBfcHViJyB9LCB7IHB1YjogJ2JpdGdvX3B1YicgfV07XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnMHg5ZTdjZThjMjRkOWY3NmE4MTRlMjM2MzNlNjFiZTdjYjhlNmUyZDVlJyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWluczogaW52YWxpZEtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMyxcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVHNzVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLCBFcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdkZXJpdmVBZGRyZXNzIChNUEMpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBTYW1lIHZlY3RvciBhcyB0aGUgTVBDIGlzV2FsbGV0QWRkcmVzcyB0ZXN0cyBhYm92ZTpcbiAgICAgICAgLy8gY29tbW9uS2V5Y2hhaW4gQCBpbmRleCAwIC0+IDB4MDExNTNmM2FkZmU0NTRhNzI1ODljYTllZjc0ZjAxM2MxOWU1NDk2MVxuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9XG4gICAgICAgICAgJzAzZjljMmZiMmU1YThiNzhhNDRmNWQxZTRmOTA2ZjhlM2Q3YTBlNmI1YzRkM2UyZjFhMGI5YzhkN2U2ZjVhNGIzYzJkMWUwZjllOGQ3YzZiNWE0JyArXG4gICAgICAgICAgJzkzODI3MTYwNTk0ODU3NDYzNzI4MTkwYTBiMGMwZDBlMGYxMDExMTIxMzE0MTUxNjE3MTgxOTFhMWIxYzFkMWUxZic7XG4gICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICB7IHB1YjogJ3VzZXJfcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgICB7IHB1YjogJ2JhY2t1cF9wdWInLCBjb21tb25LZXljaGFpbiB9LFxuICAgICAgICAgIHsgcHViOiAnYml0Z29fcHViJywgY29tbW9uS2V5Y2hhaW4gfSxcbiAgICAgICAgXTtcblxuICAgICAgICBpdCgnc2hvdWxkIGRlcml2ZSB0aGUgZXhwZWN0ZWQgTVBDIGFkZHJlc3MgZm9yIGEgY29tbW9uS2V5Y2hhaW4gYXQgaW5kZXggMCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi5kZXJpdmVBZGRyZXNzKHsga2V5Y2hhaW5zLCBpbmRleDogMCwgd2FsbGV0VmVyc2lvbjogMyB9KTtcbiAgICAgICAgICByZXN1bHQuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzB4MDExNTNmM2FkZmU0NTRhNzI1ODljYTllZjc0ZjAxM2MxOWU1NDk2MScpO1xuICAgICAgICAgIHJlc3VsdC5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5kZXJpdmF0aW9uUGF0aCwgJ20vMCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgncm91bmQtdHJpcHMgd2l0aCBpc1dhbGxldEFkZHJlc3MgKGRlcml2ZWQgYWRkcmVzcyB2ZXJpZmllcyBhcyB0cnVlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICAgICAgY29uc3QgZGVyaXZlZCA9IGF3YWl0IGNvaW4uZGVyaXZlQWRkcmVzcyh7IGtleWNoYWlucywgaW5kZXg6IDMsIHdhbGxldFZlcnNpb246IDYgfSk7XG4gICAgICAgICAgY29uc3QgdmVyaWZpZWQgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyh7XG4gICAgICAgICAgICBhZGRyZXNzOiBkZXJpdmVkLmFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgZm9yd2FyZGVyVmVyc2lvbjogNSB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDMsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyk7XG4gICAgICAgICAgdmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gbmVpdGhlciBNUEMgbm9yIGZvcndhcmRlciBpbnB1dHMgYXJlIHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgICAgICAvLyB3YWxsZXRWZXJzaW9uIDEgd2l0aCBubyBjb2luU3BlY2lmaWMuZm9yd2FyZGVyVmVyc2lvbiBhbmQgbm8gYmFzZUFkZHJlc3MgaXMgYW1iaWd1b3VzXG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmRlcml2ZUFkZHJlc3MoeyBrZXljaGFpbnMsIGluZGV4OiAwLCB3YWxsZXRWZXJzaW9uOiAxIH0pLFxuICAgICAgICAgICAgL2NvdWxkIG5vdCBkZXRlcm1pbmUgYW4gRVRIIGRlcml2YXRpb24gc3RyYXRlZ3kvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBrZXljaGFpbnMgYXJlIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5kZXJpdmVBZGRyZXNzKHsga2V5Y2hhaW5zOiBbXSwgaW5kZXg6IDAsIHdhbGxldFZlcnNpb246IDMgfSksXG4gICAgICAgICAgICAva2V5Y2hhaW5zL1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdkZXJpdmVBZGRyZXNzIChmb3J3YXJkZXIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBTYW1lIHZlY3RvcnMgYXMgdGhlIGZvcndhcmRlciBpc1dhbGxldEFkZHJlc3MgdGVzdHMgYWJvdmUgKGNvaW46IGh0ZXRoKS5cbiAgICAgICAgLy8gc2FsdCA9PSBpbmRleCBmb3IgQml0R28gZm9yd2FyZGVycywgc28gZGVyaXZpbmcgYnkgaW5kZXggcmVwcm9kdWNlcyB0aGUgYWRkcmVzcy5cbiAgICAgICAgaXQoJ2Rlcml2ZXMgdGhlIGV4YWN0IHYxIGZvcndhcmRlciBhZGRyZXNzIGFuZCByb3VuZC10cmlwcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGUxMjUzYmNjZTdkODdkYjUyMmZiY2VlYzZlNTVjOWY3OGMzNzZkOWYnO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvaW4uZGVyaXZlQWRkcmVzcyh7XG4gICAgICAgICAgICBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAxIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzdWx0LmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcweDYwNjlhNGJhZjIzNjBiZjY3YTZkMDJhN2ZjNDNkOGYzOTEwMDE2YWUnKTtcblxuICAgICAgICAgIGNvbnN0IHZlcmlmaWVkID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3Moe1xuICAgICAgICAgICAgYWRkcmVzczogcmVzdWx0LmFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGluZGV4OiA3LFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBzYWx0OiAnMHg3JywgZm9yd2FyZGVyVmVyc2lvbjogMSB9LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucyk7XG4gICAgICAgICAgdmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnZGVyaXZlcyB0aGUgZXhhY3QgdjIgZm9yd2FyZGVyIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29pbi5kZXJpdmVBZGRyZXNzKHtcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkYzQ4NWRhMDc2ZWQ0YTJiMTk1ODRlOWExZmRiYjk3NGY4OWI2MGY0JyxcbiAgICAgICAgICAgIGluZGV4OiAyMyxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDIsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgZm9yd2FyZGVyVmVyc2lvbjogMiB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJlc3VsdC5hZGRyZXNzLnNob3VsZC5lcXVhbCgnMHhmNjM2Y2VkZGZmZTQxZDEwNjU4Njg3NWMwZTU2ZGM4ZmViNjI2OGY3Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdkZXJpdmVzIHRoZSBleGFjdCB2NCBmb3J3YXJkZXIgYWRkcmVzcyAod2FsbGV0IHY1LCBuZWVkcyBmZWVBZGRyZXNzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb2luLmRlcml2ZUFkZHJlc3Moe1xuICAgICAgICAgICAgYmFzZUFkZHJlc3M6ICcweGYxZTNkMzA3OThhY2RmM2ExMmZhNWJlYjVmYWQ4ZWZiMjNkNWJlMTEnLFxuICAgICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDUsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHsgZm9yd2FyZGVyVmVyc2lvbjogNCwgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXN1bHQuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzB4ZDYzYjVlMmI4ZDFiNGZiYTM2MjU0NjA1MDg5MDBiZjJhMDQ5OWE0ZCcpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyb3dzIGlmIGJhc2VBZGRyZXNzIGlzIG1pc3NpbmcgZm9yIGEgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT4gY29pbi5kZXJpdmVBZGRyZXNzKHsgaW5kZXg6IDcsIHdhbGxldFZlcnNpb246IDEsIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAxIH0gfSksXG4gICAgICAgICAgICAvYmFzZUFkZHJlc3MgaXMgcmVxdWlyZWQvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Rocm93cyBpZiBmZWVBZGRyZXNzIGlzIG1pc3NpbmcgZm9yIGEgdjQgZm9yd2FyZGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgICAgYXN5bmMgKCkgPT5cbiAgICAgICAgICAgICAgY29pbi5kZXJpdmVBZGRyZXNzKHtcbiAgICAgICAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgICAgICAgICAgaW5kZXg6IDExNyxcbiAgICAgICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiA0IH0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgL2ZlZUFkZHJlc3MgaXMgcmVxdWlyZWQvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Rocm93cyBmb3IgZm9yd2FyZGVyIHZlcnNpb24gMCAobm90IGRlcml2YWJsZSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PlxuICAgICAgICAgICAgICBjb2luLmRlcml2ZUFkZHJlc3Moe1xuICAgICAgICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhlMTI1M2JjY2U3ZDg3ZGI1MjJmYmNlZWM2ZTU1YzlmNzhjMzc2ZDlmJyxcbiAgICAgICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAxLFxuICAgICAgICAgICAgICAgIGNvaW5TcGVjaWZpYzogeyBmb3J3YXJkZXJWZXJzaW9uOiAwIH0sXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgL3ZlcnNpb24gMCBhZGRyZXNzZXMgY2Fubm90IGJlIGRlcml2ZWQvXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ0Jhc2UgQWRkcmVzcyBWZXJpZmljYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJhc2UgYWRkcmVzcyBmb3Igd2FsbGV0IHZlcnNpb24gNiAoVFNTKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZTBjNTYwOTgyODhhOWI3ZmExMDdkYjE0NCcsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjMwZjFkM2M5ZmNlOGY1YTczMGJmZjgyNmNmOScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBkNTY3MzVlNWViNjFiMDZlMzUzZmU3NjM5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JztcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHZlcmlmeSBiYXNlIGFkZHJlc3MgZm9yIHdhbGxldCB2ZXJzaW9uIDUgKFRTUyknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZTI0MmQ5M2Y4ZDdhZDA3MDU4ODc0NDk3NjNjOTYnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZTI0MmRmOGI2MzIzZDRiMDhkZjM2Njg2NGFmNjYnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlMjQyYzA1OTViNGNmZWU2Zjk1N2MxZDY0NThmNycsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMSc7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGJhc2VBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogNCxcbiAgICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zLFxuICAgICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIH0gYXMgdW5rbm93biBhcyBUc3NWZXJpZnlFdGhBZGRyZXNzT3B0aW9ucztcblxuICAgICAgICAgIGNvbnN0IGlzV2FsbGV0QWRkciA9IGF3YWl0IGNvaW4uaXNXYWxsZXRBZGRyZXNzKHBhcmFtcyk7XG4gICAgICAgICAgaXNXYWxsZXRBZGRyLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCByZWplY3QgYmFzZSBhZGRyZXNzIHZlcmlmaWNhdGlvbiB3aXRoIG5vbi16ZXJvIGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBmMWQzYzlmY2U4ZjVhNzMwYmZmODI2Y2Y5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGQ1NjczNWU1ZWI2MWIwNmUzNTNmZTc2MzknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDUsXG4gICAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiA1LCAvLyBXcm9uZyBpbmRleCAtIHNob3VsZCBiZSAwIGZvciBiYXNlIGFkZHJlc3NcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgICBhc3luYyAoKSA9PiBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpLFxuICAgICAgICAgICAgL0Jhc2UgYWRkcmVzcyB2ZXJpZmljYXRpb24gcmVxdWlyZXMgaW5kZXggMCwgYnV0IGdvdCBpbmRleCA1L1xuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgcmVqZWN0IGJhc2UgYWRkcmVzcyB2ZXJpZmljYXRpb24gd2l0aCB3cm9uZyBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3Qga2V5Y2hhaW5zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBlMGM1NjA5ODI4OGE5YjdmYTEwN2RiMTQ0JyxcbiAgICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY5MWY2MzBmMWQzYzlmY2U4ZjVhNzMwYmZmODI2Y2Y5JyxcbiAgICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzMGQ1NjczNWU1ZWI2MWIwNmUzNTNmZTc2MzknLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF07XG5cbiAgICAgICAgICBjb25zdCB3cm9uZ0FkZHJlc3MgPSAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxJztcbiAgICAgICAgICBjb25zdCBhY3R1YWxCYXNlQWRkcmVzcyA9ICcweGMwMTIwNDFkYWMxNDNhNTlmYTQ5MWRiM2EyYjY3YjY5YmQ3OGI2ODUnO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogd3JvbmdBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGFjdHVhbEJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6ICcweDAnLFxuICAgICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA1LFxuICAgICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDYsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFRzc1ZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYmFzZSBhZGRyZXNzIGZvciB3YWxsZXQgdmVyc2lvbiAyIChCSVAzMikgdXNpbmcgd2FsbGV0IGZhY3RvcnknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG5cbiAgICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnO1xuICAgICAgICAgIGNvbnN0IHdhbGxldFNhbHQgPSAnMHgyJztcblxuICAgICAgICAgIGNvbnN0IGtleWNoYWlucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFlOGM3YjNjOGFhYTc5MTExOGQ5Y2U2MTZkM2IyMScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHg5ZDE2YmI4NjdiNzkyYzVlM2JmNjM2YTAyNzVmMmRiODYwMWJkN2Q0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZThjN2IxOTY3ZmQ2ZDk4NjdhMjJhMWE0MTMxYTAnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgICAgICBldGhBZGRyZXNzOiAnMHgyZGZjZTVjZmViNWMwM2ZiZTY4MGNkMzlhYzBkMmIyNTM5OWI3ZDIyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdO1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgICAgYWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBiYXNlQWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgc2FsdDogd2FsbGV0U2FsdCxcbiAgICAgICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBrZXljaGFpbnM6IGtleWNoYWlucyxcbiAgICAgICAgICAgIGluZGV4OiAwLFxuICAgICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgICB9IGFzIHVua25vd24gYXMgVmVyaWZ5RXRoQWRkcmVzc09wdGlvbnM7XG5cbiAgICAgICAgICBjb25zdCBpc1dhbGxldEFkZHIgPSBhd2FpdCBjb2luLmlzV2FsbGV0QWRkcmVzcyhwYXJhbXMpO1xuICAgICAgICAgIGlzV2FsbGV0QWRkci5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdmVyaWZ5IGJhc2UgYWRkcmVzcyBmb3Igd2FsbGV0IHZlcnNpb24gMSAoQklQMzIpIHVzaW5nIHdhbGxldCBmYWN0b3J5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuXG4gICAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHhlMTI1M2JjY2U3ZDg3ZGI1MjJmYmNlZWM2ZTU1YzlmNzhjMzc2ZDlmJztcbiAgICAgICAgICBjb25zdCB3YWxsZXRTYWx0ID0gJzB4NSc7XG5cbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjkxZjYzOGYxZDNjOWZjZThmNWFhNjkxNTY5YTk5ZWInLFxuICAgICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICAgICAgZXRoQWRkcmVzczogJzB4ZjQ1ZGFkY2U3NTFhMzE3OTU3ZjJhMjQ3ZmYzN2NiNzY0Yjk3NjIwZCcsXG4gICAgICAgICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHVmIzUGZDendpRVg5NEFCMW5KUXR6Vm0uLi4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2OTFmNjM4ZjBiNzRlNzNiMWY0NDBlYTRhY2VkYTg3ZScsXG4gICAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweDViZGYzYWUxZDJjMmZhZGVlYjcwYTQ1ODcyYmY0ZjQyNTIzMTJiNTUnLFxuICAgICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRjQ2cFJIZGEzc1pidVB6emE5QTlNaXFBLi4uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjhiOWVjNTg3ZDBiYTFjNzQ0MGRlNTUxMDY4YzM2YTcnLFxuICAgICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgICAgIGV0aEFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR3pUbjVleU5HRGtiMThSNDNuSDc5SG9rLi4uJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcblxuICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgYmFzZUFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICAgIHNhbHQ6IHdhbGxldFNhbHQsXG4gICAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAga2V5Y2hhaW5zOiBrZXljaGFpbnMsXG4gICAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICAgIHdhbGxldFZlcnNpb246IDEsXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFZlcmlmeUV0aEFkZHJlc3NPcHRpb25zO1xuXG4gICAgICAgICAgY29uc3QgaXNXYWxsZXRBZGRyID0gYXdhaXQgY29pbi5pc1dhbGxldEFkZHJlc3MocGFyYW1zKTtcbiAgICAgICAgICBpc1dhbGxldEFkZHIuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBDcmVhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHBhc3Mgd2FsbGV0VmVyc2lvbiA2IHRvIGlzV2FsbGV0QWRkcmVzcyBkdXJpbmcgYWRkcmVzcyBjcmVhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgY29uc3QgZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXREYXRhVjYgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNixcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICByZWNlaXZlQWRkcmVzczoge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldFY2ID0gbmV3IFdhbGxldChiaXRnbywgZXRoQ29pbiwgd2FsbGV0RGF0YVY2KTtcbiAgICAgIGNvbnN0IGlzV2FsbGV0QWRkcmVzc1NweSA9IHNpbm9uLnNweShldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJyk7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gcmVxdWVzdHNcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMzNiMDJhYWM0ZjAzOGZlZjUxMTgzNTBiNzdkMzAyZWM2MjAyOTMxY2EyZTcxMjJhYWQ4ODk5NGZmZWZjYmM3MGE2MDY5ZTY2MjQzNjIzNmFiYjE2MTkxOTUyMzJjNDE1ODAyMDRjYjIwMmMyMjM1N2VkOGY1M2U2OWVhYzVjNjllJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3YCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRnNYU2hXOFIzaEpzSE5UWVRVd3pjZWpuTGtZN0tDdGFKYkRxY0drY0JGOTlCckVKU2pOWkhlSHZlaVlVcnNBZHdualVNR3dwZ21FYmlLY1pXUnVWQTlIeG5SYUEzcjMnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBhZGRyZXNzIGNyZWF0aW9uIEFQSVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0VjYuaWQoKX0vYWRkcmVzc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhjMDEyMDQxZGFjMTQzYTU5ZmE0OTFkYjNhMmI2N2I2OWJkNzhiNjg1JyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMCxcbiAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgIHdhbGxldDogZXRoV2FsbGV0VjYuaWQoKSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDQsXG4gICAgICAgICAgICBzYWx0OiAnMHgwJyxcbiAgICAgICAgICAgIGZlZUFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRWNi5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAgfSk7XG5cbiAgICAgIGlzV2FsbGV0QWRkcmVzc1NweS5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBjb25zdCBjYWxsZWRQYXJhbXMgPSBpc1dhbGxldEFkZHJlc3NTcHkuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICBjYWxsZWRQYXJhbXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFZlcnNpb24nLCA2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFzcyB3YWxsZXRWZXJzaW9uIDUgdG8gaXNXYWxsZXRBZGRyZXNzIGR1cmluZyBhZGRyZXNzIGNyZWF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBjb25zdCBldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFWNSA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhmMWUzZDMwNzk4YWNkZjNhMTJmYTViZWI1ZmFkOGVmYjIzZDViZTExJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZjFlM2QzMDc5OGFjZGYzYTEyZmE1YmViNWZhZDhlZmIyM2Q1YmUxMScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgZXRoV2FsbGV0VjUgPSBuZXcgV2FsbGV0KGJpdGdvLCBldGhDb2luLCB3YWxsZXREYXRhVjUpO1xuICAgICAgY29uc3QgaXNXYWxsZXRBZGRyZXNzU3B5ID0gc2lub24uc3B5KGV0aENvaW4sICdpc1dhbGxldEFkZHJlc3MnKTtcblxuICAgICAgLy8gTW9jayBrZXljaGFpbiByZXF1ZXN0c1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAyYzhhNDk2YjE2YWJmZTI1Njc1MjBhMjc5ZTIxNTQ2NDJmYzNjMGUwOGU2Mjk3NzVjYjRkODQ1YzBjNWZiZjU1YWI3YmExNTNlODg2ZGU2NTc0OGVkMThmNGZmOGY1Y2VlMjI0MmU2ODczOTllYTMyOTdhMWY1NTI0ZmRlZmQ1NmMnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHaFNhWGlrcHVUQzlLVTg4WHg5THJqS1N3MUpLc3ZYTmdhYnBUZGdqeTdMU292aDlaSGhjcWhBSFF1N3V0aHU3Rmd1TkdkY0M0YVhUS0s1Z3FUY1BlNFd2TFlSYkNTRycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDdgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNGc1hTaFc4UjNoSnNITlRZVFV3emNlam5Ma1k3S0N0YUpiRHFjR2tjQkY5OUJyRUpTak5aSGVIdmVpWVVyc0Fkd25qVU1Hd3BnbUViaUtjWldSdVZBOUh4blJhQTNyMycsXG4gICAgICAgIGNvbW1vbktleWNoYWluOlxuICAgICAgICAgICcwMmM4YTQ5NmIxNmFiZmUyNTY3NTIwYTI3OWUyMTU0NjQyZmMzYzBlMDhlNjI5Nzc1Y2I0ZDg0NWMwYzVmYmY1NWFiN2JhMTUzZTg4NmRlNjU3NDhlZDE4ZjRmZjhmNWNlZTIyNDJlNjg3Mzk5ZWEzMjk3YTFmNTUyNGZkZWZkNTZjJyxcbiAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGFkZHJlc3MgY3JlYXRpb24gQVBJXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi9odGV0aC93YWxsZXQvJHtldGhXYWxsZXRWNS5pZCgpfS9hZGRyZXNzYClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiAnNjM4YTQ4YzZjM2RiYTQwMDA3YTM0OTdmYTQ5YTA4MGMnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGQ2M2I1ZTJiOGQxYjRmYmEzNjI1NDYwNTA4OTAwYmYyYTA0OTlhNGQnLFxuICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgIGluZGV4OiAxMTcsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFY1LmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgc2FsdDogJzB4NzUnLFxuICAgICAgICAgICAgZmVlQWRkcmVzczogJzB4YjFlNzI1MTg2OTkwYjg2Y2E4ZWZlZDA4YTNjY2RhOWM5ZjQwMGYwOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGV0aFdhbGxldFY1LmNyZWF0ZUFkZHJlc3MoeyBjaGFpbjogMCB9KTtcblxuICAgICAgLy8gVmVyaWZ5IGlzV2FsbGV0QWRkcmVzcyB3YXMgY2FsbGVkIHdpdGggd2FsbGV0VmVyc2lvbiA1XG4gICAgICBpc1dhbGxldEFkZHJlc3NTcHkuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgY29uc3QgY2FsbGVkUGFyYW1zID0gaXNXYWxsZXRBZGRyZXNzU3B5LmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgY2FsbGVkUGFyYW1zLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRWZXJzaW9uJywgNSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3Mgd2FsbGV0VmVyc2lvbiAyIHRvIGlzV2FsbGV0QWRkcmVzcyBkdXJpbmcgYWRkcmVzcyBjcmVhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgY29uc3QgZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXREYXRhVjIgPSB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGM0ODVkYTA3NmVkNGEyYjE5NTg0ZTlhMWZkYmI5NzRmODliNjBmNCcsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMixcbiAgICAgICAgfSxcbiAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgICAgJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgICAnNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDcnLFxuICAgICAgICBdLFxuICAgICAgICByZWNlaXZlQWRkcmVzczoge1xuICAgICAgICAgIGFkZHJlc3M6ICcweGRjNDg1ZGEwNzZlZDRhMmIxOTU4NGU5YTFmZGJiOTc0Zjg5YjYwZjQnLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldFYyID0gbmV3IFdhbGxldChiaXRnbywgZXRoQ29pbiwgd2FsbGV0RGF0YVYyKTtcbiAgICAgIGNvbnN0IGlzV2FsbGV0QWRkcmVzc1NweSA9IHNpbm9uLnNweShldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJyk7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gcmVxdWVzdHNcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzJgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZDg5ZGNlODZjMicsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHckN4Q1gzOXpiM1R2WWpUcWZVR3dFVVpIam5yYVJGbTFXZU13OWdmQ0Qxd3djMndVRG1CQloyVGtjY0pNd2Y1ZUJUamE4cjN6NkhNeG9UWkdXNm52eW9KTVFGc2VjdicsXG4gICAgICAgIGV0aEFkZHJlc3M6ICcweDlkMTZiYjg2N2I3OTJjNWUzYmY2MzZhMDI3NWYyZGI4NjAxYmQ3ZDQnLFxuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dLaGRlQzRucjF0YThkMjd4VGh0ZkZGSGdieFdNclZiNTk1bWVNUzhpM2ZCTXJUejhFZFFNV0JLSEhLenhhcEdnaGVvTXltVnZSY1FtYUdEeWtSVEJidFhxYml1OXBzJyxcbiAgICAgICAgZXRoQWRkcmVzczogJzB4MmRmY2U1Y2ZlYjVjMDNmYmU2ODBjZDM5YWMwZDJiMjUzOTliN2QyMicsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICB9KTtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvNTkzNWQ1OWNmNjYwNzY0MzMxYmFmY2FkZTE4NTVmZDdgKS5yZXBseSgyMDAsIHtcbiAgICAgICAgaWQ6ICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHelRuNWV5TkdEa2IxOFI0M25INzlIb2tZTGM1UFhaTTE5VjhVcmJ1TGRWUmFDUU1zNEVlQ0FqbnFtb1lYcWZ5dXNUVTQ2V29aTUR5THBtVHpvVVg2NlpCd0dGanQxYScsXG4gICAgICAgIGV0aEFkZHJlc3M6ICcweGIxZTcyNTE4Njk5MGI4NmNhOGVmZWQwOGEzY2NkYTljOWY0MDBmMDknLFxuICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICB9KTtcblxuICAgICAgLy8gTW9jayBhZGRyZXNzIGNyZWF0aW9uIEFQSVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0LyR7ZXRoV2FsbGV0VjIuaWQoKX0vYWRkcmVzc2ApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogJzYzOGE0OGM2YzNkYmE0MDAwN2EzNDk3ZmE0OWEwODBjJyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhmNjM2Y2VkZGZmZTQxZDEwNjU4Njg3NWMwZTU2ZGM4ZmViNjI2OGY3JyxcbiAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICBpbmRleDogMjMsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFYyLmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAyLFxuICAgICAgICAgICAgc2FsdDogJzB4MTcnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBldGhXYWxsZXRWMi5jcmVhdGVBZGRyZXNzKHsgY2hhaW46IDAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBpc1dhbGxldEFkZHJlc3Mgd2FzIGNhbGxlZCB3aXRoIHdhbGxldFZlcnNpb24gMlxuICAgICAgaXNXYWxsZXRBZGRyZXNzU3B5LmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGNvbnN0IGNhbGxlZFBhcmFtcyA9IGlzV2FsbGV0QWRkcmVzc1NweS5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgIGNhbGxlZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0VmVyc2lvbicsIDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHY2IGFkZHJlc3MgY3JlYXRpb24gaWYgd2FsbGV0VmVyc2lvbiB3YXMgbm90IHBhc3NlZCAoc2ltdWxhdGVzIG9sZCBidWcpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBjb25zdCBldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldERhdGFWNiA9IHtcbiAgICAgICAgaWQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgICB9LFxuICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyJyxcbiAgICAgICAgICAnNTk4ZjYwNmNjOGU0M2FlZjA5ZmNiNzg1MjIxZDlkZDInLFxuICAgICAgICAgICc1OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkNycsXG4gICAgICAgIF0sXG4gICAgICAgIHJlY2VpdmVBZGRyZXNzOiB7XG4gICAgICAgICAgYWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgZXRoV2FsbGV0VjYgPSBuZXcgV2FsbGV0KGJpdGdvLCBldGhDb2luLCB3YWxsZXREYXRhVjYpO1xuXG4gICAgICAvLyBTdHViIGlzV2FsbGV0QWRkcmVzcyB0byBzaW11bGF0ZSB0aGUgT0xEIGJ1ZyB3aGVyZSB3YWxsZXRWZXJzaW9uIHdhcyBub3QgcGFzc2VkXG4gICAgICBjb25zdCBvcmlnaW5hbElzV2FsbGV0QWRkcmVzcyA9IGV0aENvaW4uaXNXYWxsZXRBZGRyZXNzLmJpbmQoZXRoQ29pbik7XG4gICAgICBjb25zdCBpc1dhbGxldEFkZHJlc3NTdHViID0gc2lub24uc3R1YihldGhDb2luLCAnaXNXYWxsZXRBZGRyZXNzJykuY2FsbHNGYWtlKGFzeW5jIChwYXJhbXMpID0+IHtcbiAgICAgICAgLy8gUmVtb3ZlIHdhbGxldFZlcnNpb24gdG8gc2ltdWxhdGUgdGhlIG9sZCBidWdcbiAgICAgICAgY29uc3QgcGFyYW1zV2l0aG91dFdhbGxldFZlcnNpb24gPSB7IC4uLnBhcmFtcyB9O1xuICAgICAgICBkZWxldGUgKHBhcmFtc1dpdGhvdXRXYWxsZXRWZXJzaW9uIGFzIGFueSkud2FsbGV0VmVyc2lvbjtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsSXNXYWxsZXRBZGRyZXNzKHBhcmFtc1dpdGhvdXRXYWxsZXRWZXJzaW9uKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGtleWNoYWluIHJlcXVlc3RzXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvaHRldGgva2V5LzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkODlkY2U4NmMyYCkucmVwbHkoMjAwLCB7XG4gICAgICAgIGlkOiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWQ4OWRjZTg2YzInLFxuICAgICAgICBwdWI6ICd4cHViNjYxTXlNd0FxUmJjRlhEY1dEMnZ4dWViY1QxWnBURjRWa2U2cW1NVzh5emRkd05ZcEFQanZZRUVMNWpMZnlZWFcyZnV4dEF4WThUZ2pQVUpMY2YxQzhxejlONlZnWnhBcktYNEV3QjhySDUnLFxuICAgICAgICBjb21tb25LZXljaGFpbjpcbiAgICAgICAgICAnMDMzYjAyYWFjNGYwMzhmZWY1MTE4MzUwYjc3ZDMwMmVjNjIwMjkzMWNhMmU3MTIyYWFkODg5OTRmZmVmY2JjNzBhNjA2OWU2NjI0MzYyMzZhYmIxNjE5MTk1MjMyYzQxNTgwMjA0Y2IyMDJjMjIzNTdlZDhmNTNlNjllYWM1YzY5ZScsXG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OThmNjA2Y2M4ZTQzYWVmMDlmY2I3ODUyMjFkOWRkMmApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5OGY2MDZjYzhlNDNhZWYwOWZjYjc4NTIyMWQ5ZGQyJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL2h0ZXRoL2tleS81OTM1ZDU5Y2Y2NjA3NjQzMzFiYWZjYWRlMTg1NWZkN2ApLnJlcGx5KDIwMCwge1xuICAgICAgICBpZDogJzU5MzVkNTljZjY2MDc2NDMzMWJhZmNhZGUxODU1ZmQ3JyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0ZzWFNoVzhSM2hKc0hOVFlUVXd6Y2VqbkxrWTdLQ3RhSmJEcWNHa2NCRjk5QnJFSlNqTlpIZUh2ZWlZVXJzQWR3bmpVTUd3cGdtRWJpS2NaV1J1VkE5SHhuUmFBM3IzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46XG4gICAgICAgICAgJzAzM2IwMmFhYzRmMDM4ZmVmNTExODM1MGI3N2QzMDJlYzYyMDI5MzFjYTJlNzEyMmFhZDg4OTk0ZmZlZmNiYzcwYTYwNjllNjYyNDM2MjM2YWJiMTYxOTE5NTIzMmM0MTU4MDIwNGNiMjAyYzIyMzU3ZWQ4ZjUzZTY5ZWFjNWM2OWUnLFxuICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sgYWRkcmVzcyBjcmVhdGlvbiBBUElcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL2h0ZXRoL3dhbGxldC8ke2V0aFdhbGxldFY2LmlkKCl9L2FkZHJlc3NgKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6ICc2MzhhNDhjNmMzZGJhNDAwMDdhMzQ5N2ZhNDlhMDgwYycsXG4gICAgICAgICAgYWRkcmVzczogJzB4YzAxMjA0MWRhYzE0M2E1OWZhNDkxZGIzYTJiNjdiNjliZDc4YjY4NScsXG4gICAgICAgICAgY2hhaW46IDAsXG4gICAgICAgICAgaW5kZXg6IDAsXG4gICAgICAgICAgY29pbjogJ2h0ZXRoJyxcbiAgICAgICAgICB3YWxsZXQ6IGV0aFdhbGxldFY2LmlkKCksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiA0LFxuICAgICAgICAgICAgc2FsdDogJzB4MCcsXG4gICAgICAgICAgICBmZWVBZGRyZXNzOiAnMHhiMWU3MjUxODY5OTBiODZjYThlZmVkMDhhM2NjZGE5YzlmNDAwZjA5JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgLy8gV2l0aG91dCB3YWxsZXRWZXJzaW9uLCBhZGRyZXNzIGNyZWF0aW9uIHNob3VsZCBmYWlsIGJlY2F1c2VcbiAgICAgIC8vIHRoZSBjb2RlIGRvZXNuJ3Qga25vdyB0byB1c2UgVFNTIHZlcmlmaWNhdGlvbiBmb3IgdjYgd2FsbGV0c1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gZXRoV2FsbGV0VjYuY3JlYXRlQWRkcmVzcyh7IGNoYWluOiAwIH0pLCBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKTtcblxuICAgICAgaXNXYWxsZXRBZGRyZXNzU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFVk0gQ3Jvc3MgQ2hhaW4gUmVjb3ZlcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICBpdCgnc2hvdWxkIGJ1aWxkIGEgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gZm9yIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1c2VyS2V5ID1cbiAgICAgICAgJ3tcIml2XCI6XCJWRlozanZYaHhvMVorWWFmMk10Wm5BPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJwK2ZrSHVMYS84az1cIixcImN0XCI6XCJoWUc3cHZsakxJZ0NqWlxcbicgK1xuICAgICAgICAnNTNQQmxDZGU1S1pSbWxVS0tITHRETWsrSEpmdVU0NmhXK3grQzlXc0lBTzRnRlBuVEN2RlZtUTh4N2N6Q3RjTkZ1YjVBTzJvdE9HXFxuJyArXG4gICAgICAgICdPc1g0R0UyZ1hPRW1DbDFUcFd3d05obTd5TVVqR0pVcGdXNlpaZ1hTWGREaXRTS2k0Vi9oazc4U0dTempGT0JTUFlSYTZJPVwifVxcbic7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNUFEZEUxN2ZlRDhiYWVkM0YzMmI4NEFGMDVCOEYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUgYXMgc3RyaW5nO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3Qgc3B5ID0gc2lub24uc3B5KFRyYW5zYWN0aW9uQnVpbGRlci5wcm90b3R5cGUsICdjb2luVXNlc05vblBhY2tlZEVuY29kaW5nRm9yVHhEYXRhJyk7XG4gICAgICBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiAnJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIGJpdGdvRmVlQWRkcmVzczogYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgaW50ZW5kZWRDaGFpbjogJ3RhcmJldGgnLFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQoc3B5LnJldHVybmVkKHRydWUpKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdOb24tQml0R28gUmVjb3ZlcnkgZm9yIEhvdCBXYWxsZXRzIChNUEN2MiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgICAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gICAgICBsZXQgYmFzZWNvaW46IEh0ZXRoO1xuXG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYnVpbGQgYSByZWNvdmVyeSB0cmFuc2FjdGlvbiBmb3IgTVBDdjIga2luZCBvZiBob3Qgd2FsbGV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldE5vbkJpdEdvUmVjb3ZlcnlGb3JIb3RXYWxsZXRzTVBDdjIoKS5iaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldE5vbkJpdEdvUmVjb3ZlcnlGb3JIb3RXYWxsZXRzTVBDdjIoKS5iaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpO1xuXG4gICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogcGFyYW1zLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBwYXJhbXMud2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgIGJpdGdvRmVlQWRkcmVzczogcGFyYW1zLmJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IHBhcmFtcy5iaXRnb0Rlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgICBpbnRlbmRlZENoYWluOiBwYXJhbXMuaW50ZW5kZWRDaGFpbixcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCB1c2VyIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0SW52YWxpZE5vbkJpdEdvUmVjb3ZlcnlQYXJhbXMoKTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSxcbiAgICAgICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBwYXJhbXMud2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IHBhcmFtcy5iaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogcGFyYW1zLmJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgICAgICBpbnRlbmRlZENoYWluOiBwYXJhbXMuaW50ZW5kZWRDaGFpbixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgRXJyb3IsXG4gICAgICAgICAgJ3VzZXIga2V5IGlzIGludmFsaWQnXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdCdWlsZCBVbnNpZ25lZCBTd2VlcCBmb3IgU2VsZi1DdXN0b2R5IENvbGQgV2FsbGV0cyAoTVBDdjIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICAgIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICAgICAgbGV0IGJhc2Vjb2luOiBIdGV0aDtcblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHN3ZWVwIHdpdGhvdXQgZGVyaXZhdGlvbiBzZWVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkuYWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShcbiAgICAgICAgICAgIG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KFxuICAgICAgICAgICAgICBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpO1xuICAgICAgICBjb25zdCBzd2VlcFJlc3VsdCA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQSBEYXRhXG4gICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBCIERhdGFcbiAgICAgICAgICBkZXJpdmF0aW9uU2VlZDogcGFyYW1zLmRlcml2YXRpb25TZWVkLCAvLyBLZXkgRGVyaXZhdGlvbiBTZWVkIChvcHRpb25hbClcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgIGdhc0xpbWl0OiAyMDAwMDAsIC8vIEdhcyBMaW1pdFxuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBwYXJhbXMud2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHN3ZWVwUmVzdWx0KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gc3dlZXBSZXN1bHQgYXMgVW5zaWduZWRTd2VlcFR4TVBDdjI7XG4gICAgICAgIG91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0cy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvaW4nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNpZ25lZFR4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzZXJpYWxpemVkVHhIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlSW5mbycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGFyc2VkVHgnKTtcbiAgICAgICAgY29uc3QgcGFyc2VkVHggPSBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IHNwZW5kQW1vdW50OiBzdHJpbmcgfTtcbiAgICAgICAgcGFyc2VkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NwZW5kQW1vdW50Jyk7XG4gICAgICAgIChvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IG91dHB1dHM6IGFueVtdIH0pLnNob3VsZC5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICdvdXRwdXRzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCk7XG4gICAgICAgIHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uID0gJ2ludmFsaWRBZGRyZXNzJztcblxuICAgICAgICAvLyBFbnN1cmUgdXNlcktleSBhbmQgYmFja3VwS2V5IGFyZSB0aGUgc2FtZVxuICAgICAgICBwYXJhbXMudXNlcktleSA9XG4gICAgICAgICAgJzAyMzRlYjM5YjIyZmVkNTIzZWNlN2M3OGRhMjliYTFmMWRlNWI2NGE2ZTQ4MDEzZTA5MTRkZTc5M2JjMWRmMDU3MGU3NzlkZTA0NzU4NzMyNzM0ZDk3ZTU0Yjc4MmM4YjMzNjI4MzgxMWFmNmEyYzU3YmQ4MTQzODc5OGUxYzI0NDYnO1xuICAgICAgICBwYXJhbXMuYmFja3VwS2V5ID1cbiAgICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICAgICAgZ2FzTGltaXQ6IDIwMDAsIC8vIEdhcyBMaW1pdFxuICAgICAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksIC8vIFByb3ZpZGUgdGhlIHVzZXJLZXlcbiAgICAgICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LCAvLyBQcm92aWRlIHRoZSBiYWNrdXBLZXlcbiAgICAgICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBwYXJhbXMud2FsbGV0Q29udHJhY3RBZGRyZXNzLCAvLyBQcm92aWRlIHRoZSB3YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBFcnJvcixcbiAgICAgICAgICAnRXJyb3I6IGludmFsaWQgYWRkcmVzcydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0J1aWxkIFVuc2lnbmVkIENvbnNvbGlkYXRpb24gZm9yIFNlbGYtQ3VzdG9keSBDb2xkIFdhbGxldHMgKE1QQ3YyKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQmFzZVVybCBhcyBzdHJpbmc7XG4gICAgICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgICAgIGxldCBiYXNlY29pbjogSHRldGg7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCBjb25zb2xpZGF0aW9uIGZvciB3YWxsZXQgdjUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAudGltZXMoMilcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAudGltZXMoMilcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KFxuICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoXG4gICAgICAgICAgICAgIG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLndhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCk7XG4gICAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25SZXN1bHQgPSBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBCIERhdGFcbiAgICAgICAgICBkZXJpdmF0aW9uU2VlZDogcGFyYW1zLmRlcml2YXRpb25TZWVkLCAvLyBLZXkgRGVyaXZhdGlvbiBTZWVkIChvcHRpb25hbClcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgIGdhc0xpbWl0OiAyMDAwMDAsIC8vIEdhcyBMaW1pdFxuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBwYXJhbXMud2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICAgIGlzVHNzOiB0cnVlLFxuICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvRmVlQWRkcmVzczogJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNycsXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KGNvbnNvbGlkYXRpb25SZXN1bHQpO1xuICAgICAgICBjb25zdCB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uID0gY29uc29saWRhdGlvblJlc3VsdCBhcyBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuXG4gICAgICAgIGNvbnN0IG91dHB1dCA9IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24udHJhbnNhY3Rpb25zWzBdIGFzIE1QQ1N3ZWVwVHhzO1xuICAgICAgICBvdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4UmVxdWVzdHMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29pbicpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc2lnbmVkVHgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXJzZWRUeCcpO1xuICAgICAgICBjb25zdCBwYXJzZWRUeCA9IG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgc3BlbmRBbW91bnQ6IHN0cmluZyB9O1xuICAgICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgICAgKG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgb3V0cHV0czogYW55W10gfSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgJ291dHB1dHMnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCBjb25zb2xpZGF0aW9uIGZvciB3YWxsZXQgdjYnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAudGltZXMoMilcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAudGltZXMoMilcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KFxuICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoXG4gICAgICAgICAgICAgIG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLndhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCk7XG4gICAgICAgIGNvbnN0IGNvbnNvbGlkYXRpb25SZXN1bHQgPSBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogcGFyYW1zLmNvbW1vbktleUNoYWluLCAvLyBCb3ggQSBEYXRhXG4gICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBCIERhdGFcbiAgICAgICAgICBkZXJpdmF0aW9uU2VlZDogcGFyYW1zLmRlcml2YXRpb25TZWVkLCAvLyBLZXkgRGVyaXZhdGlvbiBTZWVkIChvcHRpb25hbClcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgIGdhc0xpbWl0OiAyMDAwMDAsIC8vIEdhcyBMaW1pdFxuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sIC8vIE1heCBGZWUgUGVyIEdhcyBhbmQgTWF4IFByaW9yaXR5IEZlZSBQZXIgR2FzXG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMTIzJywgLy8gV3Jvbmcgd2FsbGV0IGFkZHJlc3Mgc28gdGhhdCB3ZSBjYW4gc2tpcCB2NSBhZGRyZXNzIGdlbmVyYXRpb25cbiAgICAgICAgICByZXBsYXlQcm90ZWN0aW9uT3B0aW9uczoge1xuICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6ICcweDMzYTQyZmFlYTNjNmU4NzAyMTM0N2U1MTcwMGI0OGFhZjQ5YWExZTcnLFxuICAgICAgICAgIHN0YXJ0aW5nU2NhbkluZGV4OiAxLFxuICAgICAgICAgIGVuZGluZ1NjYW5JbmRleDogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHNob3VsZC5leGlzdChjb25zb2xpZGF0aW9uUmVzdWx0KTtcbiAgICAgICAgY29uc3QgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbiA9IGNvbnNvbGlkYXRpb25SZXN1bHQgYXMgVW5zaWduZWRCdWlsQ29uc29saWRhdGlvbjtcbiAgICAgICAgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcblxuICAgICAgICBjb25zdCBvdXRwdXQgPSB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9uc1swXSBhcyBNUENTd2VlcFR4cztcbiAgICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvaW4nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1bnNpZ25lZFR4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzZXJpYWxpemVkVHhIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdkZXJpdmF0aW9uUGF0aCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlSW5mbycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGFyc2VkVHgnKTtcbiAgICAgICAgY29uc3QgcGFyc2VkVHggPSBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IHNwZW5kQW1vdW50OiBzdHJpbmcgfTtcbiAgICAgICAgcGFyc2VkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NwZW5kQW1vdW50Jyk7XG4gICAgICAgIChvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IG91dHB1dHM6IGFueVtdIH0pLnNob3VsZC5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICdvdXRwdXRzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIGludmFsaWQgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCk7XG4gICAgICAgIHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uID0gJ2ludmFsaWRBZGRyZXNzJztcblxuICAgICAgICAvLyBFbnN1cmUgdXNlcktleSBhbmQgYmFja3VwS2V5IGFyZSB0aGUgc2FtZVxuICAgICAgICBwYXJhbXMudXNlcktleSA9XG4gICAgICAgICAgJzAyMzRlYjM5YjIyZmVkNTIzZWNlN2M3OGRhMjliYTFmMWRlNWI2NGE2ZTQ4MDEzZTA5MTRkZTc5M2JjMWRmMDU3MGU3NzlkZTA0NzU4NzMyNzM0ZDk3ZTU0Yjc4MmM4YjMzNjI4MzgxMWFmNmEyYzU3YmQ4MTQzODc5OGUxYzI0NDYnO1xuICAgICAgICBwYXJhbXMuYmFja3VwS2V5ID1cbiAgICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sIC8vIERlc3RpbmF0aW9uIEFkZHJlc3NcbiAgICAgICAgICAgICAgZ2FzTGltaXQ6IDIwMDAsIC8vIEdhcyBMaW1pdFxuICAgICAgICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICAgICAgdXNlcktleTogcGFyYW1zLnVzZXJLZXksIC8vIFByb3ZpZGUgdGhlIHVzZXJLZXlcbiAgICAgICAgICAgICAgYmFja3VwS2V5OiBwYXJhbXMuYmFja3VwS2V5LCAvLyBQcm92aWRlIHRoZSBiYWNrdXBLZXlcbiAgICAgICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBwYXJhbXMud2FsbGV0Q29udHJhY3RBZGRyZXNzLCAvLyBQcm92aWRlIHRoZSB3YWxsZXRDb250cmFjdEFkZHJlc3NcbiAgICAgICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgY2hhaW46ICc0MicsXG4gICAgICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBFcnJvcixcbiAgICAgICAgICAnRXJyb3I6IGludmFsaWQgYWRkcmVzcydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIG92ZXJyaWRlIHRoZSB0b2tlbiBwYXJhbWV0ZXIgd2l0aCBhIGN1c3RvbSBBUEkga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICAgIG1vZHVsZTogJ2FjY291bnQnLFxuICAgICAgICBhY3Rpb246ICdiYWxhbmNlJyxcbiAgICAgICAgYWRkcmVzczogJzB4MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCcsXG4gICAgICB9O1xuICAgICAgY29uc3QgY3VzdG9tQXBpS2V5ID0gJ2N1c3RvbS1hcGkta2V5LWZvci10ZXN0JztcblxuICAgICAgLy8gTW9jayB0aGUgZW52aXJvbm1lbnQgQVBJIHRva2VuXG4gICAgICBjb25zdCBvcmlnaW5hbEFwaVRva2VuID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkFwaVRva2VuO1xuICAgICAgY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkFwaVRva2VuID0gJ2RlZmF1bHQtZW52aXJvbm1lbnQtYXBpLWtleSc7XG5cbiAgICAgIC8vIE1vY2sgdGhlIHJlcXVlc3QuZ2V0IGZ1bmN0aW9uIHRvIGNhcHR1cmUgdGhlIHF1ZXJ5IHBhcmFtZXRlcnNcbiAgICAgIGNvbnN0IG9yaWdpbmFsR2V0ID0gcmVxdWVzdC5nZXQ7XG4gICAgICBsZXQgY2FwdHVyZWRRdWVyeTtcblxuICAgICAgcmVxdWVzdC5nZXQgPSBmdW5jdGlvbiAodXJsOiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBxdWVyeTogZnVuY3Rpb24gKHBhcmFtczogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAgICAgICAgICAgY2FwdHVyZWRRdWVyeSA9IHBhcmFtcztcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgICAgICBib2R5OiB7IHJlc3VsdDogJzEwMDAwMDAwMCcgfSxcbiAgICAgICAgICAgIH0gYXMgYW55O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgYW55O1xuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQ2FsbCB3aXRoIGRlZmF1bHQgQVBJIGtleVxuICAgICAgICBhd2FpdCBjb2luLnJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnkocXVlcnkpO1xuICAgICAgICBjYXB0dXJlZFF1ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhcGlrZXknLCAnZGVmYXVsdC1lbnZpcm9ubWVudC1hcGkta2V5Jyk7XG5cbiAgICAgICAgLy8gQ2FsbCB3aXRoIGN1c3RvbSBBUEkga2V5XG4gICAgICAgIGF3YWl0IGNvaW4ucmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShxdWVyeSwgY3VzdG9tQXBpS2V5KTtcbiAgICAgICAgY2FwdHVyZWRRdWVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYXBpa2V5JywgY3VzdG9tQXBpS2V5KTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgZnVuY3Rpb24gYW5kIEFQSSB0b2tlblxuICAgICAgICByZXF1ZXN0LmdldCA9IG9yaWdpbmFsR2V0O1xuICAgICAgICBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQXBpVG9rZW4gPSBvcmlnaW5hbEFwaVRva2VuO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQXVkaXQgS2V5JywgKCkgPT4ge1xuICAgIGxldCBjb2luOiBIdGV0aDtcbiAgICBiZWZvcmUoKCkgPT4ge1xuICAgICAgY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTXVsdGlTaWcnLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IGtleSB9ID0gZXRoTXVsdGlTaWdCYWNrdXBLZXk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHsgaXNWYWxpZDogdHJ1ZSB9IGZvciB2YWxpZCBpbnB1dHMnLCAoKSA9PiB7XG4gICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ1pROE1oeFQ4NG00UCcsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIHdhbGxldFBhc3NwaHJhc2UgaXMgaW5jb3JyZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmb28nLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBkZWNyeXB0OiBjaXBoZXJ0ZXh0IGlzIG5vdCB2YWxpZCBKU09OJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUga2V5IGlzIGFsdGVyZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsdGVyZWRLZXkgPSBrZXkucmVwbGFjZSgvWzAtOV0vZywgJzAnKTtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogYWx0ZXJlZEtleSxcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2tBbVtFRlE2bz1TeGxjTEZEdyUsJyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ2ZhaWxlZCB0byBkZWNyeXB0IHBydjogZGVjcnlwdDogY2lwaGVydGV4dCBpcyBub3QgdmFsaWQgSlNPTicgfVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVFNTJywgKCkgPT4ge1xuICAgICAgY29uc3QgeyBrZXk6IGtleVN0cmluZywgY29tbW9uS2V5Y2hhaW4gfSA9IGV0aFRzc0JhY2t1cEtleTtcbiAgICAgIGNvbnN0IGtleSA9IGtleVN0cmluZy5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdrQW1bRUZRNm89U3hsY0xGRHclLCc7XG4gICAgICBjb25zdCBtdWx0aVNpZ1R5cGUgPSAndHNzJztcblxuICAgICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICBwdWJsaWNLZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZSBjb21tb25LZXljaGFpbiBpcyBhbHRlcmVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBhbHRlcmVkQ29tbW9uS2V5Y2hhaW4gPSBnZW5lcmF0ZVJhbmRvbVBhc3N3b3JkKDEwKTtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgICBwdWJsaWNLZXk6IGFsdGVyZWRDb21tb25LZXljaGFpbixcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBtZXNzYWdlOiAnSW52YWxpZCBjb21tb24ga2V5Y2hhaW4nIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHRoZSB3YWxsZXRQYXNzcGhyYXNlIGlzIGluY29ycmVjdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5jb3JyZWN0UGFzc3BocmFzZSA9ICdmb28nO1xuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICAgIHB1YmxpY0tleTogY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGluY29ycmVjdFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogJ2ZhaWxlZCB0byBkZWNyeXB0IHBydjogaW5jb3JyZWN0IHBhc3N3b3JkJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUga2V5IGlzIGFsdGVyZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsdGVyZWRLZXkgPSBrZXkucmVwbGFjZSgvWzAtOV0vZywgJzAnKTtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogYWx0ZXJlZEtleSxcbiAgICAgICAgICAgICAgcHVibGljS2V5OiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBkZWNyeXB0OiBjaXBoZXJ0ZXh0IGlzIG5vdCB2YWxpZCBKU09OJyB9XG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldFNpZ25hYmxlUGF5bG9hZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgY29pbjogVGV0aDtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBhIDMyLWJ5dGUga2VjY2FrMjU2IGhhc2ggZm9yIGEgTGVnYWN5IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcigndGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMDAwMDAwMDAwMCcsIGdhc0xpbWl0OiAnNzAwMDAwMCcgfSk7XG4gICAgICB0eEJ1aWxkZXIuY291bnRlcigxKTtcbiAgICAgIHR4QnVpbGRlci5jb250cmFjdCgnMHg4Q2U1OWMyZDE3MDI4NDRGOEVkRUQ0NTFBQTEwMzk2MWJDMzdCNGU4Jyk7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSB0eEJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgICAgLmNvaW4oJ3RldGgnKVxuICAgICAgICAuZXhwaXJhdGlvblRpbWUoTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCkgKyAzNjAwKVxuICAgICAgICAuYW1vdW50KCcxMDAwMDAnKVxuICAgICAgICAudG8oJzB4ZWVhZjBGMDVmMzc4OTFhYjRhMjEyMDhCMTA1QTA2ODdkMTJjNWFGNycpXG4gICAgICAgIC5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3Qgc2VyaWFsaXplZFR4ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGNvaW4uZ2V0U2lnbmFibGVQYXlsb2FkKHNlcmlhbGl6ZWRUeCk7XG4gICAgICBhc3NlcnQub2soQnVmZmVyLmlzQnVmZmVyKHBheWxvYWQpKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXlsb2FkLmxlbmd0aCwgMzIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSAzMi1ieXRlIGtlY2NhazI1NiBoYXNoIGZvciBhbiBFSVAxNTU5IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcigndGV0aCcpIGFzIFRyYW5zYWN0aW9uQnVpbGRlcjtcbiAgICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgICBmZWU6ICcyODAwMDAwMDAwMDAnLFxuICAgICAgICBnYXNMaW1pdDogJzcwMDAwMDAnLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogJzc1OTMxMjMnLCBtYXhQcmlvcml0eUZlZVBlckdhczogJzE1MCcgfSxcbiAgICAgIH0pO1xuICAgICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgICB0eEJ1aWxkZXIuY29udHJhY3QoJzB4OENlNTljMmQxNzAyODQ0RjhFZEVENDUxQUExMDM5NjFiQzM3QjRlOCcpO1xuICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gdHhCdWlsZGVyLnRyYW5zZmVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyXG4gICAgICAgIC5jb2luKCd0ZXRoJylcbiAgICAgICAgLmV4cGlyYXRpb25UaW1lKE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgMzYwMClcbiAgICAgICAgLmFtb3VudCgnMTAwMDAwJylcbiAgICAgICAgLnRvKCcweGVlYWYwRjA1ZjM3ODkxYWI0YTIxMjA4QjEwNUEwNjg3ZDEyYzVhRjcnKVxuICAgICAgICAuY29udHJhY3RTZXF1ZW5jZUlkKDEpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRUeCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBjb2luLmdldFNpZ25hYmxlUGF5bG9hZChzZXJpYWxpemVkVHgpO1xuICAgICAgYXNzZXJ0Lm9rKEJ1ZmZlci5pc0J1ZmZlcihwYXlsb2FkKSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGF5bG9hZC5sZW5ndGgsIDMyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEVSQy03OTg0IHRva2VuIGVuYWJsZW1lbnQg4oCUIG11bHRpc2lnIHZlcmlmeVRyYW5zYWN0aW9uIChhbGwgc2NlbmFyaW9zKVxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgZGVzY3JpYmUoJ3ZlcmlmeVRyYW5zYWN0aW9uIOKAkyBFUkMtNzk4NCBlbmFibGV0b2tlbiAobXVsdGlzaWcgd2FsbGV0KScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBodGV0aCBaYW1hIEFDTCBjb250cmFjdCAoTmV0d29ya3MudGVzdC5ob29kaS56YW1hQWNsQ29udHJhY3RBZGRyZXNzKVxuICAgIGNvbnN0IFpBTUFfQUNMX0FERFJFU1MgPSAnMHg2ZDNmYWY2Zjg2ZTFmZjlmM2IwODMxZGRhOTIwYWJhMWNiZDViZDY4JztcbiAgICAvLyBTaW11bGF0ZWQgd2FsbGV0IGJhc2UgYWRkcmVzcyAod2hhdCB0aGUgY2xpZW50IHNlbmRzIGFzIHRoZSByZWNpcGllbnQgZm9yIGJhc2UtYWRkcmVzcyB3YWxsZXRzKVxuICAgIGNvbnN0IFdBTExFVF9CQVNFX0FERFJFU1MgPSAnMHgwOGU2NzM2ZTg3NmQ3NzJkMmZhOGY4MDNhMDc2Y2Q2YzlmODQ1NTQ2JztcbiAgICAvLyBTaW11bGF0ZWQgZm9yd2FyZGVyIGFkZHJlc3MgKHdoYXQgdGhlIGNsaWVudCBzZW5kcyBhcyByZWNpcGllbnQgZm9yIGZvcndhcmRlciB3YWxsZXRzKVxuICAgIGNvbnN0IEZPUldBUkRFUl9BRERSRVNTID0gJzB4MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MCc7XG4gICAgY29uc3QgV1JPTkdfQUREUkVTUyA9ICcweGFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEnO1xuXG4gICAgY29uc3QgbWFrZVByZWJ1aWxkID0gKHJlY2lwaWVudEFkZHJlc3M6IHN0cmluZykgPT4gKHtcbiAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsIGFtb3VudDogJzAnIH1dLFxuICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgIGdhc0xpbWl0OiAzMDAwMDAsXG4gICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgIGNvaW46ICdodGV0aCcsXG4gICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgfSk7XG5cbiAgICAvLyDilIDilIAgQmFzZS1hZGRyZXNzIHdhbGxldCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAgIGl0KCdiYXNlLWFkZHJlc3MsIHNpbmdsZSB0b2tlbjogdHhQYXJhbXMg4oaSIHdhbGxldEJhc2UsIHR4UHJlYnVpbGQg4oaSIEFDTCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGh0ZXRoQ29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9XSxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChaQU1BX0FDTF9BRERSRVNTKSBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdiYXNlLWFkZHJlc3MsIG11bHRpLXRva2VuOiBtdWx0aXBsZSB0eFBhcmFtcyByZWNpcGllbnRzIChzYW1lIGJhc2UgYWRkcmVzcyksIHR4UHJlYnVpbGQg4oaSIEFDTCBtdWx0aWNhbGwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBodGV0aENvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9LFxuICAgICAgICAgICAgeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3VzZHQnIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICAgIHR4UHJlYnVpbGQ6IG1ha2VQcmVidWlsZChaQU1BX0FDTF9BRERSRVNTKSBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIC8vIOKUgOKUgCBGb3J3YXJkZXIgd2FsbGV0IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gICAgaXQoJ2ZvcndhcmRlciwgc2luZ2xlIHRva2VuOiB0eFBhcmFtcyDihpIgZm9yd2FyZGVyLCB0eFByZWJ1aWxkIOKGkiBmb3J3YXJkZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBodGV0aENvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogRk9SV0FSREVSX0FERFJFU1MsIGFtb3VudDogJzAnLCB0b2tlbk5hbWU6ICdodGV0aDpjdGVzdDEnIH1dLFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKEZPUldBUkRFUl9BRERSRVNTKSBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdmb3J3YXJkZXIsIG11bHRpLXRva2VuOiBtdWx0aXBsZSB0eFBhcmFtcyByZWNpcGllbnRzIChzYW1lIGZvcndhcmRlciksIHR4UHJlYnVpbGQg4oaSIGZvcndhcmRlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGh0ZXRoQ29pbi52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICB7IGFkZHJlc3M6IEZPUldBUkRFUl9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9LFxuICAgICAgICAgICAgeyBhZGRyZXNzOiBGT1JXQVJERVJfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN1c2R0JyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0gYXMgYW55LFxuICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoRk9SV0FSREVSX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgd2FsbGV0LFxuICAgICAgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgLy8g4pSA4pSAIE5lZ2F0aXZlIGNhc2VzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHR4UHJlYnVpbGQgcmVjaXBpZW50IGlzIG5laXRoZXIgdGhlIEFDTCBjb250cmFjdCBub3IgdGhlIGZvcndhcmRlciBmcm9tIHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgYXdhaXQgaHRldGhDb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTLCBhbW91bnQ6ICcwJywgdG9rZW5OYW1lOiAnaHRldGg6Y3Rlc3QxJyB9XSxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoV1JPTkdfQUREUkVTUykgYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL3Rva2VuIGVuYWJsZW1lbnQgdHhQcmVidWlsZCByZWNpcGllbnQgbXVzdCBiZS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHR4UGFyYW1zIHJlY2lwaWVudHMgaGF2ZSBkaWZmZXJlbnQgYWRkcmVzc2VzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaHRldGhDb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGh0ZXRoQ29pbiwgeyBjb2luU3BlY2lmaWM6IHsgYmFzZUFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MgfSB9KTtcblxuICAgICAgYXdhaXQgaHRldGhDb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHR5cGU6ICdlbmFibGV0b2tlbicsXG4gICAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICAgIHsgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfSxcbiAgICAgICAgICAgICAgeyBhZGRyZXNzOiBGT1JXQVJERVJfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN1c2R0JyB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9IGFzIGFueSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiBtYWtlUHJlYnVpbGQoWkFNQV9BQ0xfQUREUkVTUykgYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL211c3QgYWxsIGhhdmUgdGhlIHNhbWUgYWRkcmVzcy8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIGEgdHhQYXJhbXMgcmVjaXBpZW50IGhhcyBub24temVybyBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBodGV0aENvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgaHRldGhDb2luLCB7IGNvaW5TcGVjaWZpYzogeyBiYXNlQWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUyB9IH0pO1xuXG4gICAgICBhd2FpdCBodGV0aENvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgdHlwZTogJ2VuYWJsZXRva2VuJyxcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IFdBTExFVF9CQVNFX0FERFJFU1MsIGFtb3VudDogJzEwMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfV0sXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDogbWFrZVByZWJ1aWxkKFpBTUFfQUNMX0FERFJFU1MpIGFzIGFueSxcbiAgICAgICAgICB3YWxsZXQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9tdXN0IGFsbCBoYXZlIGFtb3VudCAwLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gdHhQcmVidWlsZCByZWNpcGllbnQgaGFzIG5vbi16ZXJvIGFtb3VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGh0ZXRoQ29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBodGV0aENvaW4sIHsgY29pblNwZWNpZmljOiB7IGJhc2VBZGRyZXNzOiBXQUxMRVRfQkFTRV9BRERSRVNTIH0gfSk7XG5cbiAgICAgIGF3YWl0IGh0ZXRoQ29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnZW5hYmxldG9rZW4nLFxuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogV0FMTEVUX0JBU0VfQUREUkVTUywgYW1vdW50OiAnMCcsIHRva2VuTmFtZTogJ2h0ZXRoOmN0ZXN0MScgfV0sXG4gICAgICAgICAgfSBhcyBhbnksXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogWkFNQV9BQ0xfQUREUkVTUywgYW1vdW50OiAnNTAwJyB9XSxcbiAgICAgICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgICAgICBjb2luOiAnaHRldGgnLFxuICAgICAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICAgIH0gYXMgYW55LFxuICAgICAgICAgIHdhbGxldCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL2V4cGVjdGVkIGFtb3VudCAwIGluIHR4UHJlYnVpbGQvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==