@bitgo-beta/sdk-coin-eth 4.4.1-beta.132 → 4.4.1-beta.1321

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 (142) hide show
  1. package/dist/src/erc20Token.d.ts +13 -5
  2. package/dist/src/erc20Token.d.ts.map +1 -1
  3. package/dist/src/erc20Token.js +65 -27
  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/eth.d.ts +23 -533
  8. package/dist/src/eth.d.ts.map +1 -1
  9. package/dist/src/eth.js +208 -1622
  10. package/dist/src/gteth.d.ts +0 -4
  11. package/dist/src/gteth.d.ts.map +1 -1
  12. package/dist/src/gteth.js +1 -11
  13. package/dist/src/hteth.d.ts +8 -0
  14. package/dist/src/hteth.d.ts.map +1 -0
  15. package/dist/src/hteth.js +14 -0
  16. package/dist/src/index.d.ts +2 -0
  17. package/dist/src/index.d.ts.map +1 -1
  18. package/dist/src/index.js +8 -2
  19. package/dist/src/lib/index.d.ts +5 -13
  20. package/dist/src/lib/index.d.ts.map +1 -1
  21. package/dist/src/lib/index.js +18 -30
  22. package/dist/src/lib/messages/index.d.ts +3 -0
  23. package/dist/src/lib/messages/index.d.ts.map +1 -0
  24. package/dist/src/lib/messages/index.js +6 -0
  25. package/dist/src/lib/transactionBuilder.d.ts +9 -213
  26. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  27. package/dist/src/lib/transactionBuilder.js +18 -677
  28. package/dist/src/lib/transferBuilder.d.ts +2 -50
  29. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  30. package/dist/src/lib/transferBuilder.js +3 -199
  31. package/dist/src/lib/transferBuilders/index.d.ts +2 -3
  32. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -1
  33. package/dist/src/lib/transferBuilders/index.js +6 -14
  34. package/dist/src/lib/walletUtil.d.ts +0 -25
  35. package/dist/src/lib/walletUtil.d.ts.map +1 -1
  36. package/dist/src/lib/walletUtil.js +2 -27
  37. package/dist/src/register.d.ts.map +1 -1
  38. package/dist/src/register.js +7 -1
  39. package/dist/src/teth.d.ts +0 -3
  40. package/dist/src/teth.d.ts.map +1 -1
  41. package/dist/src/teth.js +1 -8
  42. package/dist/test/fixtures/eth.d.ts +39 -0
  43. package/dist/test/fixtures/eth.d.ts.map +1 -0
  44. package/dist/test/fixtures/eth.js +262 -0
  45. package/dist/test/resources/erc1155Abi.d.ts +40 -0
  46. package/dist/test/resources/erc1155Abi.d.ts.map +1 -0
  47. package/dist/test/resources/erc1155Abi.js +329 -0
  48. package/dist/test/resources/erc721Abi.d.ts +12 -0
  49. package/dist/test/resources/erc721Abi.d.ts.map +1 -0
  50. package/dist/test/resources/erc721Abi.js +34 -0
  51. package/dist/test/resources/eth.d.ts +51 -0
  52. package/dist/test/resources/eth.d.ts.map +1 -0
  53. package/dist/test/resources/eth.js +72 -0
  54. package/dist/test/resources/nftEncodings.d.ts +4 -0
  55. package/dist/test/resources/nftEncodings.d.ts.map +1 -0
  56. package/dist/test/resources/nftEncodings.js +7 -0
  57. package/dist/test/resources/walletSimpleAbi.d.ts +12 -0
  58. package/dist/test/resources/walletSimpleAbi.d.ts.map +1 -0
  59. package/dist/test/resources/walletSimpleAbi.js +44 -0
  60. package/dist/test/unit/eth.d.ts +2 -0
  61. package/dist/test/unit/eth.d.ts.map +1 -0
  62. package/dist/test/unit/eth.js +1171 -0
  63. package/dist/test/unit/ethWallet.d.ts +2 -0
  64. package/dist/test/unit/ethWallet.d.ts.map +1 -0
  65. package/dist/test/unit/ethWallet.js +472 -0
  66. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts +4 -0
  67. package/dist/test/unit/fixtures/ethMultiSigBackupKey.d.ts.map +1 -0
  68. package/dist/test/unit/fixtures/ethMultiSigBackupKey.js +10 -0
  69. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts +5 -0
  70. package/dist/test/unit/fixtures/ethTssBackupKey.d.ts.map +1 -0
  71. package/dist/test/unit/fixtures/ethTssBackupKey.js +25 -0
  72. package/dist/test/unit/getBuilder.d.ts +3 -0
  73. package/dist/test/unit/getBuilder.d.ts.map +1 -0
  74. package/dist/test/unit/getBuilder.js +10 -0
  75. package/dist/test/unit/keyPair.d.ts +2 -0
  76. package/dist/test/unit/keyPair.d.ts.map +1 -0
  77. package/dist/test/unit/keyPair.js +175 -0
  78. package/dist/test/unit/transaction.d.ts +2 -0
  79. package/dist/test/unit/transaction.d.ts.map +1 -0
  80. package/dist/test/unit/transaction.js +96 -0
  81. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +2 -0
  82. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  83. package/dist/test/unit/transactionBuilder/addressInitialization.js +101 -0
  84. package/dist/test/unit/transactionBuilder/contractCall.d.ts +2 -0
  85. package/dist/test/unit/transactionBuilder/contractCall.d.ts.map +1 -0
  86. package/dist/test/unit/transactionBuilder/contractCall.js +101 -0
  87. package/dist/test/unit/transactionBuilder/flushCoins.d.ts +2 -0
  88. package/dist/test/unit/transactionBuilder/flushCoins.d.ts.map +1 -0
  89. package/dist/test/unit/transactionBuilder/flushCoins.js +133 -0
  90. package/dist/test/unit/transactionBuilder/flushTokens.d.ts +2 -0
  91. package/dist/test/unit/transactionBuilder/flushTokens.d.ts.map +1 -0
  92. package/dist/test/unit/transactionBuilder/flushTokens.js +281 -0
  93. package/dist/test/unit/transactionBuilder/send.d.ts +2 -0
  94. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  95. package/dist/test/unit/transactionBuilder/send.js +331 -0
  96. package/dist/test/unit/transactionBuilder/sendNFT.d.ts +2 -0
  97. package/dist/test/unit/transactionBuilder/sendNFT.d.ts.map +1 -0
  98. package/dist/test/unit/transactionBuilder/sendNFT.js +250 -0
  99. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts +2 -0
  100. package/dist/test/unit/transactionBuilder/singleSigSend.d.ts.map +1 -0
  101. package/dist/test/unit/transactionBuilder/singleSigSend.js +196 -0
  102. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  103. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  104. package/dist/test/unit/transactionBuilder/walletInitialization.js +423 -0
  105. package/dist/test/unit/transferBuilder.d.ts +2 -0
  106. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  107. package/dist/test/unit/transferBuilder.js +124 -0
  108. package/dist/test/unit/utils.d.ts +2 -0
  109. package/dist/test/unit/utils.d.ts.map +1 -0
  110. package/dist/test/unit/utils.js +74 -0
  111. package/dist/tsconfig.tsbuildinfo +1 -0
  112. package/package.json +16 -18
  113. package/.eslintignore +0 -5
  114. package/.mocharc.yml +0 -8
  115. package/CHANGELOG.md +0 -354
  116. package/dist/src/lib/contractCall.d.ts +0 -8
  117. package/dist/src/lib/contractCall.d.ts.map +0 -1
  118. package/dist/src/lib/contractCall.js +0 -17
  119. package/dist/src/lib/iface.d.ts +0 -130
  120. package/dist/src/lib/iface.d.ts.map +0 -1
  121. package/dist/src/lib/iface.js +0 -8
  122. package/dist/src/lib/keyPair.d.ts +0 -26
  123. package/dist/src/lib/keyPair.d.ts.map +0 -1
  124. package/dist/src/lib/keyPair.js +0 -66
  125. package/dist/src/lib/transaction.d.ts +0 -64
  126. package/dist/src/lib/transaction.d.ts.map +0 -1
  127. package/dist/src/lib/transaction.js +0 -137
  128. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts +0 -47
  129. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts.map +0 -1
  130. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.js +0 -113
  131. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts +0 -14
  132. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts.map +0 -1
  133. package/dist/src/lib/transferBuilders/transferBuilderERC1155.js +0 -83
  134. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts +0 -13
  135. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts.map +0 -1
  136. package/dist/src/lib/transferBuilders/transferBuilderERC721.js +0 -68
  137. package/dist/src/lib/types.d.ts +0 -39
  138. package/dist/src/lib/types.d.ts.map +0 -1
  139. package/dist/src/lib/types.js +0 -137
  140. package/dist/src/lib/utils.d.ts +0 -228
  141. package/dist/src/lib/utils.d.ts.map +0 -1
  142. package/dist/src/lib/utils.js +0 -577
@@ -0,0 +1,1171 @@
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 ethMultiSigBackupKey_1 = require("./fixtures/ethMultiSigBackupKey");
54
+ const ethTssBackupKey_1 = require("./fixtures/ethTssBackupKey");
55
+ nock_1.default.enableNetConnect();
56
+ describe('ETH:', function () {
57
+ let bitgo;
58
+ let hopTxBitgoSignature;
59
+ let sandbox;
60
+ const address1 = '0x174cfd823af8ce27ed0afee3fcf3c3ba259116be';
61
+ const address2 = '0x7e85bdc27c050e3905ebf4b8e634d9ad6edd0de6';
62
+ const hopContractAddress = '0x47ce7cc86efefef19f8fb516b11735d183da8635';
63
+ const hopDestinationAddress = '0x9c7e8ce6825bD48278B3Ab59228EE26f8BE7925b';
64
+ const hopTx = '0xf86b808504a817c8ff8252ff949c7e8ce6825bd48278b3ab59228ee26f8be7925b87038d7ea4c68000801ca011bc22c664570133dfca4f08a0b8d02339cf467046d6a4152f04f368d0eaf99ea01d6dc5cf0c897c8d4c3e1df53d0d042784c424536a4cc5b802552b7d64fee8b5';
65
+ const hopTxid = '0x4af65143bc77da2b50f35b3d13cacb4db18f026bf84bc0743550bc57b9b53351';
66
+ const userReqSig = '0x404db307f6147f0d8cd338c34c13906ef46a6faa7e0e119d5194ef05aec16e6f3d710f9b7901460f97e924066b62efd74443bd34402c6d40b49c203a559ff2c8';
67
+ before(function () {
68
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
69
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
70
+ if (!bitgoKey.privateKey) {
71
+ throw new Error('no privateKey');
72
+ }
73
+ const bitgoXpub = bitgoKey.neutered().toBase58();
74
+ hopTxBitgoSignature =
75
+ '0xaa' +
76
+ Buffer.from(secp256k1.ecdsaSign(Buffer.from(hopTxid.slice(2), 'hex'), bitgoKey.privateKey).signature).toString('hex');
77
+ const env = 'test';
78
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
79
+ src_1.Erc20Token.createTokenConstructors().forEach(({ name, coinConstructor }) => {
80
+ bitgo.safeRegister(name, coinConstructor);
81
+ });
82
+ bitgo.safeRegister('teth', src_1.Teth.createInstance);
83
+ bitgo.safeRegister('hteth', src_1.Hteth.createInstance);
84
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
85
+ bitgo.initializeTestVars();
86
+ sandbox = sinon_1.default.createSandbox();
87
+ });
88
+ after(function () {
89
+ nock_1.default.cleanAll();
90
+ sandbox.restore();
91
+ });
92
+ describe('EIP1559', function () {
93
+ it('should sign a transaction with EIP1559 fee params', async function () {
94
+ const coin = bitgo.coin('teth');
95
+ const userKeychain = {
96
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
97
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
98
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
99
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
100
+ };
101
+ const halfSignedTransaction = await coin.signTransaction({
102
+ txPrebuild: {
103
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
104
+ isBatch: false,
105
+ recipients: [
106
+ {
107
+ amount: '42',
108
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
109
+ },
110
+ ],
111
+ expireTime: 1627949214,
112
+ contractSequenceId: 12,
113
+ gasLimit: undefined,
114
+ gasPrice: undefined,
115
+ hopTransaction: undefined,
116
+ backupKeyNonce: undefined,
117
+ sequenceId: undefined,
118
+ nextContractSequenceId: 0,
119
+ },
120
+ prv: userKeychain.prv,
121
+ });
122
+ halfSignedTransaction.halfSigned.eip1559.maxPriorityFeePerGas.should.equal(10);
123
+ halfSignedTransaction.halfSigned.eip1559.maxFeePerGas.should.equal(10);
124
+ });
125
+ it('should sign a transaction with EIP1559 fee params for CCR', async function () {
126
+ const coin = bitgo.coin('hteth');
127
+ const signTransaction = sinon_1.default.spy(src_1.AbstractEthLikeNewCoins.prototype, 'signTransaction');
128
+ const userKeychain = {
129
+ prv: 'xprv9s21ZrQH143K3hekyNj7TciR4XNYe1kMj68W2ipjJGNHETWP7o42AjDnSPgKhdZ4x8NBAvaL72RrXjuXNdmkMqLERZza73oYugGtbLFXG8g',
130
+ pub: 'xpub661MyMwAqRbcGBjE5QG7pkf9cZD33UUD6K46q7ELrbuG7FqXfLNGiXYGHeEnGBb5AWREnk1eA28g8ArZvURbhshXWkTtddHRo54fgyVvLdb',
131
+ rawPub: '023636e68b7b204573abda2616aff6b584910dece2543f1cc6d842caac7d74974b',
132
+ rawPrv: '7438a50010ce7b1dfd86e68046cc78ba1ebd242d6d85d9904d3fcc08734bc172',
133
+ };
134
+ const txBuilder = (0, getBuilder_1.getBuilder)('hteth');
135
+ txBuilder.type(sdk_core_1.TransactionType.Send);
136
+ txBuilder.fee({
137
+ fee: '10',
138
+ gasLimit: '1000',
139
+ });
140
+ const key = testData.KEYPAIR_PRV.getKeys().prv;
141
+ const transferBuilder = txBuilder.transfer();
142
+ transferBuilder
143
+ .amount('0')
144
+ .to('0x19645032c7f1533395d44a629462e751084d3e4c')
145
+ .expirationTime(1590066728)
146
+ .contractSequenceId(5)
147
+ .key(key);
148
+ txBuilder.contract(address1);
149
+ const tx = await txBuilder.build();
150
+ const halfSignedTransaction = await coin.signTransaction({
151
+ txPrebuild: {
152
+ eip1559: { maxPriorityFeePerGas: 10, maxFeePerGas: 10 },
153
+ isBatch: false,
154
+ recipients: [
155
+ {
156
+ amount: '42',
157
+ address: '0xc93b13642d93b4218bb85f67317d6b37286e8028',
158
+ },
159
+ ],
160
+ expireTime: 1627949214,
161
+ contractSequenceId: 12,
162
+ gasLimit: undefined,
163
+ gasPrice: undefined,
164
+ hopTransaction: undefined,
165
+ backupKeyNonce: undefined,
166
+ sequenceId: undefined,
167
+ nextContractSequenceId: 0,
168
+ txHex: tx.toBroadcastFormat(),
169
+ },
170
+ prv: userKeychain.prv,
171
+ isEvmBasedCrossChainRecovery: true,
172
+ });
173
+ (0, assert_1.default)(halfSignedTransaction.halfSigned.txHex);
174
+ assert_1.default.strictEqual(halfSignedTransaction.halfSigned.eip1559.maxFeePerGas, 10);
175
+ sandbox.assert.calledOnce(signTransaction);
176
+ });
177
+ });
178
+ describe('Transaction Verification', function () {
179
+ it('should verify a normal txPrebuild from the bitgo server that matches the client txParams', async function () {
180
+ const coin = bitgo.coin('teth');
181
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
182
+ const txParams = {
183
+ recipients: [{ amount: '1000000000000', address: address1 }],
184
+ wallet: wallet,
185
+ walletPassphrase: 'fakeWalletPassphrase',
186
+ };
187
+ const txPrebuild = {
188
+ recipients: [{ amount: '1000000000000', address: address1 }],
189
+ nextContractSequenceId: 0,
190
+ gasPrice: 20000000000,
191
+ gasLimit: 500000,
192
+ isBatch: false,
193
+ coin: 'teth',
194
+ wallet: 'fakeWalletId',
195
+ walletContractAddress: 'fakeWalletContractAddress',
196
+ };
197
+ const verification = {};
198
+ const isTransactionVerified = await coin.verifyTransaction({
199
+ txParams,
200
+ txPrebuild: txPrebuild,
201
+ wallet,
202
+ verification,
203
+ });
204
+ isTransactionVerified.should.equal(true);
205
+ });
206
+ it('should verify a batch txPrebuild from the bitgo server that matches the client txParams', async function () {
207
+ const coin = bitgo.coin('teth');
208
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
209
+ const txParams = {
210
+ recipients: [
211
+ { amount: '1000000000000', address: address1 },
212
+ { amount: '2500000000000', address: address2 },
213
+ ],
214
+ wallet: wallet,
215
+ walletPassphrase: 'fakeWalletPassphrase',
216
+ };
217
+ const txPrebuild = {
218
+ recipients: [
219
+ { amount: '3500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
220
+ ],
221
+ nextContractSequenceId: 0,
222
+ gasPrice: 20000000000,
223
+ gasLimit: 500000,
224
+ isBatch: true,
225
+ coin: 'teth',
226
+ walletId: 'fakeWalletId',
227
+ walletContractAddress: 'fakeWalletContractAddress',
228
+ };
229
+ const verification = {};
230
+ const isTransactionVerified = await coin.verifyTransaction({
231
+ txParams,
232
+ txPrebuild: txPrebuild,
233
+ wallet,
234
+ verification,
235
+ });
236
+ isTransactionVerified.should.equal(true);
237
+ });
238
+ it('should verify ENS address resolution changing recipient address in client txParams', async function () {
239
+ const coin = bitgo.coin('teth');
240
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
241
+ const txParams = {
242
+ recipients: [{ amount: '1000000000000', address: 'bitgotestwallet.eth' }],
243
+ wallet: wallet,
244
+ walletPassphrase: 'fakeWalletPassphrase',
245
+ };
246
+ const txPrebuild = {
247
+ recipients: [{ amount: '1000000000000', address: '0x40a663963810449d6e72533657a74f112c3b901a' }],
248
+ nextContractSequenceId: 0,
249
+ gasPrice: 20000000000,
250
+ gasLimit: 500000,
251
+ isBatch: false,
252
+ coin: 'teth',
253
+ walletId: 'fakeWalletId',
254
+ walletContractAddress: 'fakeWalletContractAddress',
255
+ };
256
+ const verification = {};
257
+ const isTransactionVerified = await coin.verifyTransaction({
258
+ txParams,
259
+ txPrebuild: txPrebuild,
260
+ wallet,
261
+ verification,
262
+ });
263
+ isTransactionVerified.should.equal(true);
264
+ });
265
+ it('should verify a hop txPrebuild from the bitgo server that matches the client txParams', async function () {
266
+ const coin = bitgo.coin('teth');
267
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
268
+ const txParams = {
269
+ recipients: [{ amount: 1000000000000000, address: hopDestinationAddress }],
270
+ wallet: wallet,
271
+ walletPassphrase: 'fakeWalletPassphrase',
272
+ hop: true,
273
+ };
274
+ const txPrebuild = {
275
+ recipients: [{ amount: '5000000000000000', address: hopContractAddress }],
276
+ nextContractSequenceId: 0,
277
+ gasPrice: 20000000000,
278
+ gasLimit: 500000,
279
+ isBatch: false,
280
+ coin: 'teth',
281
+ walletId: 'fakeWalletId',
282
+ walletContractAddress: 'fakeWalletContractAddress',
283
+ hopTransaction: {
284
+ tx: hopTx,
285
+ id: hopTxid,
286
+ signature: hopTxBitgoSignature,
287
+ paymentId: '2773928196',
288
+ gasPrice: 20000000000,
289
+ gasLimit: 500000,
290
+ amount: '1000000000000000',
291
+ recipient: hopDestinationAddress,
292
+ nonce: 0,
293
+ userReqSig: userReqSig,
294
+ gasPriceMax: 500000000000,
295
+ },
296
+ };
297
+ const verification = {};
298
+ const isTransactionVerified = await coin.verifyTransaction({
299
+ txParams,
300
+ txPrebuild: txPrebuild,
301
+ wallet,
302
+ verification,
303
+ });
304
+ isTransactionVerified.should.equal(true);
305
+ });
306
+ it('should reject when client txParams are missing', async function () {
307
+ const coin = bitgo.coin('teth');
308
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
309
+ const txParams = null;
310
+ const txPrebuild = {
311
+ recipients: [{ amount: '1000000000000', address: address1 }],
312
+ nextContractSequenceId: 0,
313
+ gasPrice: 20000000000,
314
+ gasLimit: 500000,
315
+ isBatch: false,
316
+ coin: 'teth',
317
+ walletId: 'fakeWalletId',
318
+ walletContractAddress: 'fakeWalletContractAddress',
319
+ };
320
+ const verification = {};
321
+ await coin
322
+ .verifyTransaction({ txParams: txParams, txPrebuild: txPrebuild, wallet, verification })
323
+ .should.be.rejectedWith('missing params');
324
+ });
325
+ it('should reject txPrebuild that is both batch and hop', async function () {
326
+ const coin = bitgo.coin('teth');
327
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
328
+ const txParams = {
329
+ recipients: [
330
+ { amount: '1000000000000', address: address1 },
331
+ { amount: '2500000000000', address: address2 },
332
+ ],
333
+ wallet: wallet,
334
+ walletPassphrase: 'fakeWalletPassphrase',
335
+ hop: true,
336
+ };
337
+ const txPrebuild = {
338
+ recipients: [{ amount: '3500000000000', address: address1 }],
339
+ nextContractSequenceId: 0,
340
+ gasPrice: 20000000000,
341
+ gasLimit: 500000,
342
+ isBatch: true,
343
+ coin: 'teth',
344
+ walletId: 'fakeWalletId',
345
+ walletContractAddress: 'fakeWalletContractAddress',
346
+ hopTransaction: {
347
+ tx: hopTx,
348
+ id: hopTxid,
349
+ signature: hopTxBitgoSignature,
350
+ paymentId: '2773928196',
351
+ gasPrice: 20000000000,
352
+ gasLimit: 500000,
353
+ amount: '1000000000000000',
354
+ recipient: hopDestinationAddress,
355
+ nonce: 0,
356
+ userReqSig: userReqSig,
357
+ gasPriceMax: 500000000000,
358
+ },
359
+ };
360
+ const verification = {};
361
+ await coin
362
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
363
+ .should.be.rejectedWith('tx cannot be both a batch and hop transaction');
364
+ });
365
+ it('should reject a txPrebuild with more than one recipient', async function () {
366
+ const coin = bitgo.coin('teth');
367
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
368
+ const txParams = {
369
+ recipients: [
370
+ { amount: '1000000000000', address: address1 },
371
+ { amount: '2500000000000', address: address2 },
372
+ ],
373
+ wallet: wallet,
374
+ walletPassphrase: 'fakeWalletPassphrase',
375
+ };
376
+ const txPrebuild = {
377
+ recipients: [
378
+ { amount: '1000000000000', address: address1 },
379
+ { amount: '2500000000000', address: address2 },
380
+ ],
381
+ nextContractSequenceId: 0,
382
+ gasPrice: 20000000000,
383
+ gasLimit: 500000,
384
+ isBatch: true,
385
+ coin: 'teth',
386
+ walletId: 'fakeWalletId',
387
+ walletContractAddress: 'fakeWalletContractAddress',
388
+ };
389
+ const verification = {};
390
+ await coin
391
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
392
+ .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.`);
393
+ });
394
+ it('should reject a hop txPrebuild that does not send to its hop address', async function () {
395
+ const coin = bitgo.coin('teth');
396
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
397
+ const txParams = {
398
+ recipients: [{ amount: '1000000000000000', address: hopDestinationAddress }],
399
+ wallet: wallet,
400
+ walletPassphrase: 'fakeWalletPassphrase',
401
+ hop: true,
402
+ };
403
+ const txPrebuild = {
404
+ recipients: [{ amount: '5000000000000000', address: address1 }],
405
+ nextContractSequenceId: 0,
406
+ gasPrice: 20000000000,
407
+ gasLimit: 500000,
408
+ isBatch: false,
409
+ coin: 'teth',
410
+ walletId: 'fakeWalletId',
411
+ walletContractAddress: 'fakeWalletContractAddress',
412
+ hopTransaction: {
413
+ tx: hopTx,
414
+ id: hopTxid,
415
+ signature: hopTxBitgoSignature,
416
+ paymentId: '0',
417
+ gasPrice: 20000000000,
418
+ gasLimit: 500000,
419
+ amount: '1000000000000000',
420
+ recipient: hopDestinationAddress,
421
+ nonce: 0,
422
+ userReqSig: userReqSig,
423
+ gasPriceMax: 500000000000,
424
+ },
425
+ };
426
+ const verification = {};
427
+ await coin
428
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
429
+ .should.be.rejectedWith('recipient address of txPrebuild does not match hop address');
430
+ });
431
+ it('should reject a batch txPrebuild from the bitgo server with the wrong total amount', async function () {
432
+ const coin = bitgo.coin('teth');
433
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
434
+ const txParams = {
435
+ recipients: [
436
+ { amount: '1000000000000', address: address1 },
437
+ { amount: '2500000000000', address: address2 },
438
+ ],
439
+ wallet: wallet,
440
+ walletPassphrase: 'fakeWalletPassphrase',
441
+ };
442
+ const txPrebuild = {
443
+ recipients: [
444
+ { amount: '5500000000000', address: (coin?.staticsCoin?.network).batcherContractAddress },
445
+ ],
446
+ nextContractSequenceId: 0,
447
+ gasPrice: 20000000000,
448
+ gasLimit: 500000,
449
+ isBatch: true,
450
+ coin: 'teth',
451
+ walletId: 'fakeWalletId',
452
+ walletContractAddress: 'fakeWalletContractAddress',
453
+ };
454
+ const verification = {};
455
+ await coin
456
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
457
+ .should.be.rejectedWith('batch transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
458
+ });
459
+ it('should reject a batch txPrebuild from the bitgo server that does not send to the batcher contract address', async function () {
460
+ const coin = bitgo.coin('teth');
461
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
462
+ const txParams = {
463
+ recipients: [
464
+ { amount: '1000000000000', address: address1 },
465
+ { amount: '2500000000000', address: address2 },
466
+ ],
467
+ wallet: wallet,
468
+ walletPassphrase: 'fakeWalletPassphrase',
469
+ };
470
+ const txPrebuild = {
471
+ recipients: [{ amount: '3500000000000', address: hopContractAddress }],
472
+ nextContractSequenceId: 0,
473
+ gasPrice: 20000000000,
474
+ gasLimit: 500000,
475
+ isBatch: true,
476
+ coin: 'teth',
477
+ walletId: 'fakeWalletId',
478
+ walletContractAddress: 'fakeWalletContractAddress',
479
+ };
480
+ const verification = {};
481
+ await coin
482
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
483
+ .should.be.rejectedWith('recipient address of txPrebuild does not match batcher address');
484
+ });
485
+ it('should reject a normal txPrebuild from the bitgo server with the wrong amount', async function () {
486
+ const coin = bitgo.coin('teth');
487
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
488
+ const txParams = {
489
+ recipients: [{ amount: '1000000000000', address: address1 }],
490
+ wallet: wallet,
491
+ walletPassphrase: 'fakeWalletPassphrase',
492
+ };
493
+ const txPrebuild = {
494
+ recipients: [{ amount: '2000000000000', address: address1 }],
495
+ nextContractSequenceId: 0,
496
+ gasPrice: 20000000000,
497
+ gasLimit: 500000,
498
+ isBatch: false,
499
+ coin: 'teth',
500
+ walletId: 'fakeWalletId',
501
+ walletContractAddress: 'fakeWalletContractAddress',
502
+ };
503
+ const verification = {};
504
+ await coin
505
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
506
+ .should.be.rejectedWith('normal transaction amount in txPrebuild received from BitGo servers does not match txParams supplied by client');
507
+ });
508
+ it('should reject a normal txPrebuild from the bitgo server with the wrong recipient', async function () {
509
+ const coin = bitgo.coin('teth');
510
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
511
+ const txParams = {
512
+ recipients: [{ amount: '1000000000000', address: address1 }],
513
+ wallet: wallet,
514
+ walletPassphrase: 'fakeWalletPassphrase',
515
+ };
516
+ const txPrebuild = {
517
+ recipients: [{ amount: '1000000000000', address: address2 }],
518
+ nextContractSequenceId: 0,
519
+ gasPrice: 20000000000,
520
+ gasLimit: 500000,
521
+ isBatch: false,
522
+ coin: 'teth',
523
+ walletId: 'fakeWalletId',
524
+ walletContractAddress: 'fakeWalletContractAddress',
525
+ };
526
+ const verification = {};
527
+ await coin
528
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
529
+ .should.be.rejectedWith('destination address in normal txPrebuild does not match that in txParams supplied by client');
530
+ });
531
+ it('should verify a token txPrebuild from the bitgo server that matches the client txParams', async function () {
532
+ const coin = bitgo.coin('test');
533
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
534
+ const txParams = {
535
+ recipients: [{ amount: '1000000000000', address: address1 }],
536
+ wallet: wallet,
537
+ walletPassphrase: 'fakeWalletPassphrase',
538
+ };
539
+ const txPrebuild = {
540
+ recipients: [{ amount: '1000000000000', address: address1 }],
541
+ nextContractSequenceId: 0,
542
+ gasPrice: 20000000000,
543
+ gasLimit: 500000,
544
+ isBatch: false,
545
+ coin: 'teth',
546
+ token: 'test',
547
+ walletId: 'fakeWalletId',
548
+ walletContractAddress: 'fakeWalletContractAddress',
549
+ };
550
+ const verification = {};
551
+ const isTransactionVerified = await coin.verifyTransaction({
552
+ txParams,
553
+ txPrebuild: txPrebuild,
554
+ wallet,
555
+ verification,
556
+ });
557
+ isTransactionVerified.should.equal(true);
558
+ });
559
+ it('should reject a txPrebuild from the bitgo server with the wrong coin', async function () {
560
+ const coin = bitgo.coin('teth');
561
+ const wallet = new sdk_core_1.Wallet(bitgo, coin, {});
562
+ const txParams = {
563
+ recipients: [{ amount: '1000000000000', address: address1 }],
564
+ wallet: wallet,
565
+ walletPassphrase: 'fakeWalletPassphrase',
566
+ };
567
+ const txPrebuild = {
568
+ recipients: [{ amount: '1000000000000', address: address1 }],
569
+ nextContractSequenceId: 0,
570
+ gasPrice: 20000000000,
571
+ gasLimit: 500000,
572
+ isBatch: false,
573
+ coin: 'btc',
574
+ walletId: 'fakeWalletId',
575
+ walletContractAddress: 'fakeWalletContractAddress',
576
+ };
577
+ const verification = {};
578
+ await coin
579
+ .verifyTransaction({ txParams, txPrebuild: txPrebuild, wallet, verification })
580
+ .should.be.rejectedWith('coin in txPrebuild did not match that in txParams supplied by client');
581
+ });
582
+ });
583
+ describe('Address Verification', function () {
584
+ it('should verify an address generated using forwarder version 0', async function () {
585
+ const coin = bitgo.coin('teth');
586
+ const params = {
587
+ id: '6127bff4ecd84c0006cd9a0e5ccdc36f',
588
+ chain: 0,
589
+ index: 3174,
590
+ coin: 'teth',
591
+ lastNonce: 0,
592
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
593
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
594
+ coinSpecific: {
595
+ nonce: -1,
596
+ updateTime: '2021-08-26T16:23:16.563Z',
597
+ txCount: 0,
598
+ pendingChainInitialization: true,
599
+ creationFailure: [],
600
+ pendingDeployment: false,
601
+ forwarderVersion: 0,
602
+ },
603
+ };
604
+ const isAddressVerified = await coin.verifyAddress(params);
605
+ isAddressVerified.should.equal(true);
606
+ });
607
+ it('should verify an address generated using forwarder version 1', async function () {
608
+ const coin = bitgo.coin('teth');
609
+ const params = {
610
+ id: '61250217c8c02b000654b15e7af6f618',
611
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
612
+ chain: 0,
613
+ index: 3162,
614
+ coin: 'teth',
615
+ lastNonce: 0,
616
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
617
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
618
+ coinSpecific: {
619
+ nonce: -1,
620
+ updateTime: '2021-08-24T14:28:39.841Z',
621
+ txCount: 0,
622
+ pendingChainInitialization: true,
623
+ creationFailure: [],
624
+ salt: '0xc5a',
625
+ pendingDeployment: true,
626
+ forwarderVersion: 1,
627
+ },
628
+ };
629
+ const isAddressVerified = await coin.verifyAddress(params);
630
+ isAddressVerified.should.equal(true);
631
+ });
632
+ it('should reject address verification if coinSpecific field is not an object', async function () {
633
+ const coin = bitgo.coin('teth');
634
+ const params = {
635
+ id: '61250217c8c02b000654b15e7af6f618',
636
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
637
+ chain: 0,
638
+ index: 3162,
639
+ coin: 'teth',
640
+ lastNonce: 0,
641
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
642
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
643
+ };
644
+ assert_1.default.rejects(async () => coin.verifyAddress(params), sdk_core_1.InvalidAddressVerificationObjectPropertyError);
645
+ });
646
+ it('should reject address verification when an actual address is different from expected address', async function () {
647
+ const coin = bitgo.coin('teth');
648
+ const params = {
649
+ id: '61250217c8c02b000654b15e7af6f618',
650
+ address: '0x28904591f735994f050804fda3b61b813b16e04c',
651
+ chain: 0,
652
+ index: 3162,
653
+ coin: 'teth',
654
+ lastNonce: 0,
655
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
656
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
657
+ coinSpecific: {
658
+ nonce: -1,
659
+ updateTime: '2021-08-24T14:28:39.841Z',
660
+ txCount: 0,
661
+ pendingChainInitialization: true,
662
+ creationFailure: [],
663
+ salt: '0xc5a',
664
+ pendingDeployment: true,
665
+ forwarderVersion: 1,
666
+ },
667
+ };
668
+ assert_1.default.rejects(async () => coin.verifyAddress(params), sdk_core_1.UnexpectedAddressError);
669
+ });
670
+ it('should reject address verification if the derived address is in invalid format', async function () {
671
+ const coin = bitgo.coin('teth');
672
+ const params = {
673
+ id: '61250217c8c02b000654b15e7af6f618',
674
+ address: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
675
+ chain: 0,
676
+ index: 3162,
677
+ coin: 'teth',
678
+ lastNonce: 0,
679
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
680
+ baseAddress: '0xdf07117705a9f8dc4c2a78de66b7f1797dba9d4e',
681
+ coinSpecific: {
682
+ nonce: -1,
683
+ updateTime: '2021-08-24T14:28:39.841Z',
684
+ txCount: 0,
685
+ pendingChainInitialization: true,
686
+ creationFailure: [],
687
+ salt: '0xc5a',
688
+ pendingDeployment: true,
689
+ forwarderVersion: 1,
690
+ },
691
+ };
692
+ assert_1.default.rejects(async () => coin.verifyAddress(params), sdk_core_1.InvalidAddressError);
693
+ });
694
+ it('should reject address verification if base address is undefined', async function () {
695
+ const coin = bitgo.coin('teth');
696
+ const params = {
697
+ id: '61250217c8c02b000654b15e7af6f618',
698
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
699
+ chain: 0,
700
+ index: 3162,
701
+ coin: 'teth',
702
+ lastNonce: 0,
703
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
704
+ coinSpecific: {
705
+ nonce: -1,
706
+ updateTime: '2021-08-24T14:28:39.841Z',
707
+ txCount: 0,
708
+ pendingChainInitialization: true,
709
+ creationFailure: [],
710
+ salt: '0xc5a',
711
+ pendingDeployment: true,
712
+ forwarderVersion: 1,
713
+ },
714
+ };
715
+ assert_1.default.rejects(async () => coin.verifyAddress(params), sdk_core_1.InvalidAddressError);
716
+ });
717
+ it('should reject address verification if base address is in invalid format', async function () {
718
+ const coin = bitgo.coin('teth');
719
+ const params = {
720
+ id: '61250217c8c02b000654b15e7af6f618',
721
+ address: '0xb0b56eeae1b283918caca02a14ada2df17a98e6d',
722
+ chain: 0,
723
+ index: 3162,
724
+ coin: 'teth',
725
+ lastNonce: 0,
726
+ wallet: '598f606cd8fc24710d2ebadb1d9459bb',
727
+ baseAddress: '0xe0b56eeae1b283918caca02a14ada2df17a98bvf',
728
+ coinSpecific: {
729
+ nonce: -1,
730
+ updateTime: '2021-08-24T14:28:39.841Z',
731
+ txCount: 0,
732
+ pendingChainInitialization: true,
733
+ creationFailure: [],
734
+ salt: '0xc5a',
735
+ pendingDeployment: true,
736
+ forwarderVersion: 1,
737
+ },
738
+ };
739
+ assert_1.default.rejects(async () => coin.verifyAddress(params), sdk_core_1.InvalidAddressError);
740
+ });
741
+ });
742
+ describe('EVM Cross Chain Recovery', function () {
743
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
744
+ it('should build a recovery transaction for hot wallet', async function () {
745
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
746
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
747
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
748
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
749
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
750
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
751
+ const destinationAddress = '0xd5ADdE17feD8baed3F32b84AF05B8F2816f7b560';
752
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
753
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
754
+ const basecoin = bitgo.coin('hteth');
755
+ (0, nock_1.default)(baseUrl)
756
+ .get('/api')
757
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
758
+ .reply(200, mockData.getTxListResponse);
759
+ (0, nock_1.default)(baseUrl)
760
+ .get('/api')
761
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
762
+ .reply(200, mockData.getBalanceResponse);
763
+ (0, nock_1.default)(baseUrl)
764
+ .get('/api')
765
+ .query(mockData.getBalanceRequest(walletContractAddress))
766
+ .reply(200, mockData.getBalanceResponse);
767
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
768
+ const spy = sinon_1.default.spy(src_1.TransactionBuilder.prototype, 'coinUsesNonPackedEncodingForTxData');
769
+ await basecoin.recover({
770
+ userKey: userKey,
771
+ backupKey: '',
772
+ walletPassphrase: walletPassphrase,
773
+ walletContractAddress: walletContractAddress,
774
+ bitgoFeeAddress: bitgoFeeAddress,
775
+ recoveryDestination: destinationAddress,
776
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
777
+ gasLimit: 500000,
778
+ bitgoDestinationAddress: bitgoDestinationAddress,
779
+ intendedChain: 'tarbeth',
780
+ });
781
+ (0, assert_1.default)(spy.returned(true));
782
+ });
783
+ describe('Non-BitGo Recovery for Hot Wallets (MPCv2)', function () {
784
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
785
+ let bitgo;
786
+ let basecoin;
787
+ before(function () {
788
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
789
+ basecoin = bitgo.coin('hteth');
790
+ });
791
+ it('should build a recovery transaction for MPCv2 kind of hot wallets', async function () {
792
+ (0, nock_1.default)(baseUrl)
793
+ .get('/api')
794
+ .query(mockData.getTxListRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
795
+ .reply(200, mockData.getTxListResponse);
796
+ (0, nock_1.default)(baseUrl)
797
+ .get('/api')
798
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().bitgoFeeAddress))
799
+ .reply(200, mockData.getBalanceResponse);
800
+ (0, nock_1.default)(baseUrl)
801
+ .get('/api')
802
+ .query(mockData.getBalanceRequest(mockData.getNonBitGoRecoveryForHotWalletsMPCv2().walletContractAddress))
803
+ .reply(200, mockData.getBalanceResponse);
804
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
805
+ const params = mockData.getNonBitGoRecoveryForHotWalletsMPCv2();
806
+ const transaction = await basecoin.recover({
807
+ userKey: params.userKey,
808
+ backupKey: params.backupKey,
809
+ walletPassphrase: params.walletPassphrase,
810
+ walletContractAddress: params.walletContractAddress,
811
+ bitgoFeeAddress: params.bitgoFeeAddress,
812
+ recoveryDestination: params.recoveryDestination,
813
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
814
+ gasLimit: 500000,
815
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
816
+ intendedChain: params.intendedChain,
817
+ });
818
+ should_1.default.exist(transaction);
819
+ transaction.should.have.property('txHex');
820
+ });
821
+ it('should throw an error for invalid user key', async function () {
822
+ const params = mockData.getInvalidNonBitGoRecoveryParams();
823
+ await assert_1.default.rejects(async () => {
824
+ await basecoin.recover({
825
+ userKey: params.userKey,
826
+ backupKey: params.backupKey,
827
+ walletPassphrase: params.walletPassphrase,
828
+ walletContractAddress: params.walletContractAddress,
829
+ bitgoFeeAddress: params.bitgoFeeAddress,
830
+ recoveryDestination: params.recoveryDestination,
831
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
832
+ gasLimit: 500000,
833
+ bitgoDestinationAddress: params.bitgoDestinationAddress,
834
+ intendedChain: params.intendedChain,
835
+ });
836
+ }, Error, 'user key is invalid');
837
+ });
838
+ });
839
+ describe('Build Unsigned Sweep for Self-Custody Cold Wallets (MPCv2)', function () {
840
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
841
+ let bitgo;
842
+ let basecoin;
843
+ before(function () {
844
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
845
+ basecoin = bitgo.coin('hteth');
846
+ });
847
+ it('should generate an unsigned sweep without derivation seed', async function () {
848
+ (0, nock_1.default)(baseUrl)
849
+ .get('/api')
850
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
851
+ .reply(200, mockData.getTxListResponse);
852
+ (0, nock_1.default)(baseUrl)
853
+ .get('/api')
854
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
855
+ .reply(200, mockData.getBalanceResponse);
856
+ (0, nock_1.default)(baseUrl)
857
+ .get('/api')
858
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
859
+ .reply(200, mockData.getBalanceResponse);
860
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
861
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
862
+ const sweepResult = await basecoin.recover({
863
+ userKey: params.commonKeyChain, // Box A Data
864
+ backupKey: params.commonKeyChain, // Box B Data
865
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
866
+ recoveryDestination: params.recoveryDestination, // Destination Address
867
+ gasLimit: 200000, // Gas Limit
868
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
869
+ walletContractAddress: params.walletContractAddress,
870
+ isTss: true,
871
+ replayProtectionOptions: {
872
+ chain: '42',
873
+ hardfork: 'london',
874
+ },
875
+ });
876
+ should_1.default.exist(sweepResult);
877
+ const output = sweepResult;
878
+ output.should.have.property('txRequests');
879
+ output.txRequests.should.have.length(1);
880
+ output.txRequests[0].should.have.property('transactions');
881
+ output.txRequests[0].transactions.should.have.length(1);
882
+ output.txRequests[0].should.have.property('walletCoin');
883
+ output.txRequests[0].transactions.should.have.length(1);
884
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
885
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
886
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
887
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
888
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
889
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
890
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
891
+ parsedTx.should.have.property('spendAmount');
892
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
893
+ });
894
+ it('should throw an error for invalid address', async function () {
895
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
896
+ params.recoveryDestination = 'invalidAddress';
897
+ // Ensure userKey and backupKey are the same
898
+ params.userKey =
899
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
900
+ params.backupKey =
901
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
902
+ await assert_1.default.rejects(async () => {
903
+ await basecoin.recover({
904
+ recoveryDestination: params.recoveryDestination, // Destination Address
905
+ gasLimit: 2000, // Gas Limit
906
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
907
+ userKey: params.userKey, // Provide the userKey
908
+ backupKey: params.backupKey, // Provide the backupKey
909
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
910
+ isTss: true,
911
+ replayProtectionOptions: {
912
+ chain: '42',
913
+ hardfork: 'london',
914
+ },
915
+ });
916
+ }, Error, 'Error: invalid address');
917
+ });
918
+ });
919
+ describe('Build Unsigned Consolidation for Self-Custody Cold Wallets (MPCv2)', function () {
920
+ const baseUrl = sdk_core_1.common.Environments.test.etherscanBaseUrl;
921
+ let bitgo;
922
+ let basecoin;
923
+ before(function () {
924
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
925
+ basecoin = bitgo.coin('hteth');
926
+ });
927
+ it('should generate an unsigned consolidation for wallet v5', async function () {
928
+ (0, nock_1.default)(baseUrl)
929
+ .get('/api')
930
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
931
+ .times(2)
932
+ .reply(200, mockData.getTxListResponse);
933
+ (0, nock_1.default)(baseUrl)
934
+ .get('/api')
935
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
936
+ .times(2)
937
+ .reply(200, mockData.getBalanceResponse);
938
+ (0, nock_1.default)(baseUrl)
939
+ .get('/api')
940
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
941
+ .reply(200, mockData.getBalanceResponse);
942
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
943
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
944
+ const consolidationResult = await basecoin.recoverConsolidations({
945
+ backupKey: params.commonKeyChain, // Box B Data
946
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
947
+ recoveryDestination: params.recoveryDestination, // Destination Address
948
+ gasLimit: 200000, // Gas Limit
949
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
950
+ walletContractAddress: params.walletContractAddress,
951
+ isTss: true,
952
+ replayProtectionOptions: {
953
+ chain: '42',
954
+ hardfork: 'london',
955
+ },
956
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
957
+ startingScanIndex: 1,
958
+ endingScanIndex: 2,
959
+ });
960
+ should_1.default.exist(consolidationResult);
961
+ const unsignedBuilConsolidation = consolidationResult;
962
+ unsignedBuilConsolidation.should.have.property('transactions');
963
+ unsignedBuilConsolidation.transactions.should.have.length(1);
964
+ const output = unsignedBuilConsolidation.transactions[0];
965
+ output.should.have.property('txRequests');
966
+ output.txRequests[0].should.have.property('transactions');
967
+ output.txRequests[0].transactions.should.have.length(1);
968
+ output.txRequests[0].should.have.property('walletCoin');
969
+ output.txRequests[0].transactions.should.have.length(1);
970
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
971
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
972
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
973
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
974
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
975
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
976
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
977
+ parsedTx.should.have.property('spendAmount');
978
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
979
+ });
980
+ it('should generate an unsigned consolidation for wallet v6', async function () {
981
+ (0, nock_1.default)(baseUrl)
982
+ .get('/api')
983
+ .query(mockData.getTxListRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
984
+ .times(2)
985
+ .reply(200, mockData.getTxListResponse);
986
+ (0, nock_1.default)(baseUrl)
987
+ .get('/api')
988
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().address))
989
+ .times(2)
990
+ .reply(200, mockData.getBalanceResponse);
991
+ (0, nock_1.default)(baseUrl)
992
+ .get('/api')
993
+ .query(mockData.getBalanceRequest(mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2().walletContractAddress))
994
+ .reply(200, mockData.getBalanceResponse);
995
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
996
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
997
+ const consolidationResult = await basecoin.recoverConsolidations({
998
+ userKey: params.commonKeyChain, // Box A Data
999
+ backupKey: params.commonKeyChain, // Box B Data
1000
+ derivationSeed: params.derivationSeed, // Key Derivation Seed (optional)
1001
+ recoveryDestination: params.recoveryDestination, // Destination Address
1002
+ gasLimit: 200000, // Gas Limit
1003
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1004
+ isTss: true,
1005
+ walletContractAddress: '123', // Wrong wallet address so that we can skip v5 address generation
1006
+ replayProtectionOptions: {
1007
+ chain: '42',
1008
+ hardfork: 'london',
1009
+ },
1010
+ bitgoFeeAddress: '0x33a42faea3c6e87021347e51700b48aaf49aa1e7',
1011
+ startingScanIndex: 1,
1012
+ endingScanIndex: 2,
1013
+ });
1014
+ should_1.default.exist(consolidationResult);
1015
+ const unsignedBuilConsolidation = consolidationResult;
1016
+ unsignedBuilConsolidation.should.have.property('transactions');
1017
+ unsignedBuilConsolidation.transactions.should.have.length(1);
1018
+ const output = unsignedBuilConsolidation.transactions[0];
1019
+ output.should.have.property('txRequests');
1020
+ output.txRequests[0].should.have.property('transactions');
1021
+ output.txRequests[0].transactions.should.have.length(1);
1022
+ output.txRequests[0].should.have.property('walletCoin');
1023
+ output.txRequests[0].transactions.should.have.length(1);
1024
+ output.txRequests[0].transactions[0].should.have.property('unsignedTx');
1025
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
1026
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
1027
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
1028
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
1029
+ output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
1030
+ const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
1031
+ parsedTx.should.have.property('spendAmount');
1032
+ output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
1033
+ });
1034
+ it('should throw an error for invalid address', async function () {
1035
+ const params = mockData.getBuildUnsignedSweepForSelfCustodyColdWalletsMPCv2();
1036
+ params.recoveryDestination = 'invalidAddress';
1037
+ // Ensure userKey and backupKey are the same
1038
+ params.userKey =
1039
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
1040
+ params.backupKey =
1041
+ '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
1042
+ await assert_1.default.rejects(async () => {
1043
+ await basecoin.recover({
1044
+ recoveryDestination: params.recoveryDestination, // Destination Address
1045
+ gasLimit: 2000, // Gas Limit
1046
+ eip1559: { maxFeePerGas: 200, maxPriorityFeePerGas: 10000 }, // Max Fee Per Gas and Max Priority Fee Per Gas
1047
+ userKey: params.userKey, // Provide the userKey
1048
+ backupKey: params.backupKey, // Provide the backupKey
1049
+ walletContractAddress: params.walletContractAddress, // Provide the walletContractAddress
1050
+ isTss: true,
1051
+ replayProtectionOptions: {
1052
+ chain: '42',
1053
+ hardfork: 'london',
1054
+ },
1055
+ });
1056
+ }, Error, 'Error: invalid address');
1057
+ });
1058
+ });
1059
+ });
1060
+ describe('RecoveryBlockchainExplorerQuery', () => {
1061
+ it('should override the token parameter with a custom API key', async function () {
1062
+ const coin = bitgo.coin('teth');
1063
+ const query = {
1064
+ module: 'account',
1065
+ action: 'balance',
1066
+ address: '0x1234567890123456789012345678901234567890',
1067
+ };
1068
+ const customApiKey = 'custom-api-key-for-test';
1069
+ // Mock the environment API token
1070
+ const originalApiToken = sdk_core_1.common.Environments.test.etherscanApiToken;
1071
+ sdk_core_1.common.Environments.test.etherscanApiToken = 'default-environment-api-key';
1072
+ // Mock the request.get function to capture the query parameters
1073
+ const originalGet = superagent_1.default.get;
1074
+ let capturedQuery;
1075
+ superagent_1.default.get = function (url) {
1076
+ return {
1077
+ query: function (params) {
1078
+ capturedQuery = params;
1079
+ return {
1080
+ ok: true,
1081
+ body: { result: '100000000' },
1082
+ };
1083
+ },
1084
+ };
1085
+ };
1086
+ try {
1087
+ // Call with default API key
1088
+ await coin.recoveryBlockchainExplorerQuery(query);
1089
+ capturedQuery.should.have.property('apikey', 'default-environment-api-key');
1090
+ // Call with custom API key
1091
+ await coin.recoveryBlockchainExplorerQuery(query, customApiKey);
1092
+ capturedQuery.should.have.property('apikey', customApiKey);
1093
+ }
1094
+ finally {
1095
+ // Restore original function and API token
1096
+ superagent_1.default.get = originalGet;
1097
+ sdk_core_1.common.Environments.test.etherscanApiToken = originalApiToken;
1098
+ }
1099
+ });
1100
+ });
1101
+ describe('Audit Key', () => {
1102
+ let coin;
1103
+ before(() => {
1104
+ coin = bitgo.coin('hteth');
1105
+ });
1106
+ describe('MultiSig', () => {
1107
+ const { key } = ethMultiSigBackupKey_1.ethMultiSigBackupKey;
1108
+ it('should return { isValid: true } for valid inputs', () => {
1109
+ coin.assertIsValidKey({
1110
+ encryptedPrv: key,
1111
+ walletPassphrase: 'ZQ8MhxT84m4P',
1112
+ });
1113
+ });
1114
+ it('should throw error if the walletPassphrase is incorrect', () => {
1115
+ assert_1.default.throws(() => coin.assertIsValidKey({
1116
+ encryptedPrv: key,
1117
+ walletPassphrase: 'foo',
1118
+ }), { message: "failed to decrypt prv: ccm: tag doesn't match" });
1119
+ });
1120
+ it('should throw error if the key is altered', () => {
1121
+ const alteredKey = key.replace(/[0-9]/g, '0');
1122
+ assert_1.default.throws(() => coin.assertIsValidKey({
1123
+ encryptedPrv: alteredKey,
1124
+ walletPassphrase: 'kAm[EFQ6o=SxlcLFDw%,',
1125
+ }), { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
1126
+ });
1127
+ });
1128
+ describe('TSS', () => {
1129
+ const { key: keyString, commonKeychain } = ethTssBackupKey_1.ethTssBackupKey;
1130
+ const key = keyString.replace(/\s/g, '');
1131
+ const walletPassphrase = 'kAm[EFQ6o=SxlcLFDw%,';
1132
+ const multiSigType = 'tss';
1133
+ it('should not throw for valid inputs', () => {
1134
+ coin.assertIsValidKey({
1135
+ encryptedPrv: key,
1136
+ publicKey: commonKeychain,
1137
+ walletPassphrase,
1138
+ multiSigType,
1139
+ });
1140
+ });
1141
+ it('should throw if the commonKeychain is altered', () => {
1142
+ const alteredCommonKeychain = (0, sdk_core_1.generateRandomPassword)(10);
1143
+ assert_1.default.throws(() => coin.assertIsValidKey({
1144
+ encryptedPrv: key,
1145
+ publicKey: alteredCommonKeychain,
1146
+ walletPassphrase,
1147
+ multiSigType,
1148
+ }), { message: 'Invalid common keychain' });
1149
+ });
1150
+ it('should throw error if the walletPassphrase is incorrect', () => {
1151
+ const incorrectPassphrase = 'foo';
1152
+ assert_1.default.throws(() => coin.assertIsValidKey({
1153
+ encryptedPrv: key,
1154
+ publicKey: commonKeychain,
1155
+ walletPassphrase: incorrectPassphrase,
1156
+ multiSigType,
1157
+ }), { message: "failed to decrypt prv: ccm: tag doesn't match" });
1158
+ });
1159
+ it('should throw error if the key is altered', () => {
1160
+ const alteredKey = key.replace(/[0-9]/g, '0');
1161
+ assert_1.default.throws(() => coin.assertIsValidKey({
1162
+ encryptedPrv: alteredKey,
1163
+ publicKey: commonKeychain,
1164
+ walletPassphrase,
1165
+ multiSigType,
1166
+ }), { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
1167
+ });
1168
+ });
1169
+ });
1170
+ });
1171
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2V0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1EQUErRDtBQUUvRCxnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLHFEQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsNERBQWlDO0FBQ2pDLG1EQVM4QjtBQUM5QixpREFBK0M7QUFDL0MsbUNBU21CO0FBRW5CLG9EQUE0QjtBQUM1Qiw2Q0FBMEM7QUFDMUMsMkRBQTZDO0FBQzdDLDBEQUE0QztBQUM1QyxvREFBNEI7QUFDNUIsMEVBQXVFO0FBQ3ZFLGdFQUE2RDtBQUU3RCxjQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztBQUV4QixRQUFRLENBQUMsTUFBTSxFQUFFO0lBQ2YsSUFBSSxLQUFtQixDQUFDO0lBQ3hCLElBQUksbUJBQW1CLENBQUM7SUFDeEIsSUFBSSxPQUEyQixDQUFDO0lBRWhDLE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO0lBQzlELE1BQU0sUUFBUSxHQUFHLDRDQUE0QyxDQUFDO0lBQzlELE1BQU0sa0JBQWtCLEdBQUcsNENBQTRDLENBQUM7SUFDeEUsTUFBTSxxQkFBcUIsR0FBRyw0Q0FBNEMsQ0FBQztJQUMzRSxNQUFNLEtBQUssR0FDVCw4TkFBOE4sQ0FBQztJQUNqTyxNQUFNLE9BQU8sR0FBRyxvRUFBb0UsQ0FBQztJQUNyRixNQUFNLFVBQVUsR0FDZCxvSUFBb0ksQ0FBQztJQUV2SSxNQUFNLENBQUM7UUFDTCxNQUFNLFlBQVksR0FDaEIsaUhBQWlILENBQUM7UUFDcEgsTUFBTSxRQUFRLEdBQUcsaUJBQUssQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFD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Q0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEdBQUcsRUFBRTtnQkFDakUsTUFBTSxtQkFBbUIsR0FBRyxLQUFLLENBQUM7Z0JBQ2xDLGdCQUFNLENBQUMsTUFBTSxDQUNYLEdBQUcsRUFBRSxDQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztvQkFDcEIsWUFBWSxFQUFFLEdBQUc7b0JBQ2pCLFNBQVMsRUFBRSxjQUFjO29CQUN6QixnQkFBZ0IsRUFBRSxtQkFBbUI7b0JBQ3JDLFlBQVk7aUJBQ2IsQ0FBQyxFQUNKLEVBQUUsT0FBTyxFQUFFLCtDQUErQyxFQUFFLENBQzdELENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxHQUFHLEVBQUU7Z0JBQ2xELE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM5QyxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUUsQ0FDSCxJQUFJLENBQUMsZ0JBQWdCLENBQUM7b0JBQ3BCLFlBQVksRUFBRSxVQUFVO29CQUN4QixTQUFTLEVBQUUsY0FBYztvQkFDekIsZ0JBQWdCO29CQUNoQixZQUFZO2lCQUNiLENBQUMsRUFDSixFQUFFLE9BQU8sRUFBRSx5REFBeUQsRUFBRSxDQUN2RSxDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcblxuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgYmlwMzIgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0ICogYXMgc2VjcDI1NmsxIGZyb20gJ3NlY3AyNTZrMSc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7XG4gIGNvbW1vbixcbiAgZ2VuZXJhdGVSYW5kb21QYXNzd29yZCxcbiAgSW52YWxpZEFkZHJlc3NFcnJvcixcbiAgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yLFxuICBNUENTd2VlcFR4cyxcbiAgVHJhbnNhY3Rpb25UeXBlLFxuICBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yLFxuICBXYWxsZXQsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQge1xuICBBYnN0cmFjdEV0aExpa2VOZXdDb2lucyxcbiAgRXJjMjBUb2tlbixcbiAgSHRldGgsXG4gIFRldGgsXG4gIFRyYW5zYWN0aW9uQnVpbGRlcixcbiAgVHJhbnNmZXJCdWlsZGVyLFxuICBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLFxuICBVbnNpZ25lZFN3ZWVwVHhNUEN2Mixcbn0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IEV0aGVyZXVtTmV0d29yayB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgZ2V0QnVpbGRlciB9IGZyb20gJy4vZ2V0QnVpbGRlcic7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi9yZXNvdXJjZXMvZXRoJztcbmltcG9ydCAqIGFzIG1vY2tEYXRhIGZyb20gJy4uL2ZpeHR1cmVzL2V0aCc7XG5pbXBvcnQgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyBldGhNdWx0aVNpZ0JhY2t1cEtleSB9IGZyb20gJy4vZml4dHVyZXMvZXRoTXVsdGlTaWdCYWNrdXBLZXknO1xuaW1wb3J0IHsgZXRoVHNzQmFja3VwS2V5IH0gZnJvbSAnLi9maXh0dXJlcy9ldGhUc3NCYWNrdXBLZXknO1xuXG5ub2NrLmVuYWJsZU5ldENvbm5lY3QoKTtcblxuZGVzY3JpYmUoJ0VUSDonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgaG9wVHhCaXRnb1NpZ25hdHVyZTtcbiAgbGV0IHNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcblxuICBjb25zdCBhZGRyZXNzMSA9ICcweDE3NGNmZDgyM2FmOGNlMjdlZDBhZmVlM2ZjZjNjM2JhMjU5MTE2YmUnO1xuICBjb25zdCBhZGRyZXNzMiA9ICcweDdlODViZGMyN2MwNTBlMzkwNWViZjRiOGU2MzRkOWFkNmVkZDBkZTYnO1xuICBjb25zdCBob3BDb250cmFjdEFkZHJlc3MgPSAnMHg0N2NlN2NjODZlZmVmZWYxOWY4ZmI1MTZiMTE3MzVkMTgzZGE4NjM1JztcbiAgY29uc3QgaG9wRGVzdGluYXRpb25BZGRyZXNzID0gJzB4OWM3ZThjZTY4MjViRDQ4Mjc4QjNBYjU5MjI4RUUyNmY4QkU3OTI1Yic7XG4gIGNvbnN0IGhvcFR4ID1cbiAgICAnMHhmODZiODA4NTA0YTgxN2M4ZmY4MjUyZmY5NDljN2U4Y2U2ODI1YmQ0ODI3OGIzYWI1OTIyOGVlMjZmOGJlNzkyNWI4NzAzOGQ3ZWE0YzY4MDAwODAxY2EwMTFiYzIyYzY2NDU3MDEzM2RmY2E0ZjA4YTBiOGQwMjMzOWNmNDY3MDQ2ZDZhNDE1MmYwNGYzNjhkMGVhZjk5ZWEwMWQ2ZGM1Y2YwYzg5N2M4ZDRjM2UxZGY1M2QwZDA0Mjc4NGM0MjQ1MzZhNGNjNWI4MDI1NTJiN2Q2NGZlZThiNSc7XG4gIGNvbnN0IGhvcFR4aWQgPSAnMHg0YWY2NTE0M2JjNzdkYTJiNTBmMzViM2QxM2NhY2I0ZGIxOGYwMjZiZjg0YmMwNzQzNTUwYmM1N2I5YjUzMzUxJztcbiAgY29uc3QgdXNlclJlcVNpZyA9XG4gICAgJzB4NDA0ZGIzMDdmNjE0N2YwZDhjZDMzOGMzNGMxMzkwNmVmNDZhNmZhYTdlMGUxMTlkNTE5NGVmMDVhZWMxNmU2ZjNkNzEwZjliNzkwMTQ2MGY5N2U5MjQwNjZiNjJlZmQ3NDQ0M2JkMzQ0MDJjNmQ0MGI0OWMyMDNhNTU5ZmYyYzgnO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYml0Z29LZXlYcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLM3RwV0JIV2UzMXNMb1hOUlE5QXZSWUpnaXRrS3hRNEFURlFNd3ZyN2hITnFZUlVuUzdQc2p6QjdhSzFWeHFITHVOUWpqMXNja0oySndvMnF4bXN2ZWp3RUNTcEZNZkMnO1xuICAgIGNvbnN0IGJpdGdvS2V5ID0gYmlwMzIuZnJvbUJhc2U1OChiaXRnb0tleVhwcnYpO1xuICAgIGlmICghYml0Z29LZXkucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIGNvbnN0IGJpdGdvWHB1YiA9IGJpdGdvS2V5Lm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcbiAgICBob3BUeEJpdGdvU2lnbmF0dXJlID1cbiAgICAgICcweGFhJyArXG4gICAgICBCdWZmZXIuZnJvbShzZWNwMjU2azEuZWNkc2FTaWduKEJ1ZmZlci5mcm9tKGhvcFR4aWQuc2xpY2UoMiksICdoZXgnKSwgYml0Z29LZXkucHJpdmF0ZUtleSkuc2lnbmF0dXJlKS50b1N0cmluZyhcbiAgICAgICAgJ2hleCdcbiAgICAgICk7XG5cbiAgICBjb25zdCBlbnYgPSAndGVzdCc7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgRXJjMjBUb2tlbi5jcmVhdGVUb2tlbkNvbnN0cnVjdG9ycygpLmZvckVhY2goKHsgbmFtZSwgY29pbkNvbnN0cnVjdG9yIH0pID0+IHtcbiAgICAgIGJpdGdvLnNhZmVSZWdpc3RlcihuYW1lLCBjb2luQ29uc3RydWN0b3IpO1xuICAgIH0pO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcigndGV0aCcsIFRldGguY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignaHRldGgnLCBIdGV0aC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgY29tbW9uLkVudmlyb25tZW50c1tlbnZdLmhzbVhwdWIgPSBiaXRnb1hwdWI7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0VJUDE1NTknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzaWduIGEgdHJhbnNhY3Rpb24gd2l0aCBFSVAxNTU5IGZlZSBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgIGNvbnN0IHVzZXJLZXljaGFpbiA9IHtcbiAgICAgICAgcHJ2OiAneHBydjlzMjFaclFIMTQzSzNoZWt5Tmo3VGNpUjRYTlllMWtNajY4VzJpcGpKR05IRVRXUDdvNDJBakRuU1BnS2hkWjR4OE5CQXZhTDcyUnJYanVYTmRta01xTEVSWnphNzNvWXVnR3RiTEZYRzhnJyxcbiAgICAgICAgcHViOiAneHB1YjY2MU15TXdBcVJiY0dCakU1UUc3cGtmOWNaRDMzVVVENks0NnE3RUxyYnVHN0ZxWGZMTkdpWFlHSGVFbkdCYjVBV1JFbmsxZUEyOGc4QXJadlVSYmhzaFhXa1R0ZGRIUm81NGZneVZ2TGRiJyxcbiAgICAgICAgcmF3UHViOiAnMDIzNjM2ZTY4YjdiMjA0NTczYWJkYTI2MTZhZmY2YjU4NDkxMGRlY2UyNTQzZjFjYzZkODQyY2FhYzdkNzQ5NzRiJyxcbiAgICAgICAgcmF3UHJ2OiAnNzQzOGE1MDAxMGNlN2IxZGZkODZlNjgwNDZjYzc4YmExZWJkMjQyZDZkODVkOTkwNGQzZmNjMDg3MzRiYzE3MicsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBlaXAxNTU5OiB7IG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMCwgbWF4RmVlUGVyR2FzOiAxMCB9LFxuICAgICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYW1vdW50OiAnNDInLFxuICAgICAgICAgICAgICBhZGRyZXNzOiAnMHhjOTNiMTM2NDJkOTNiNDIxOGJiODVmNjczMTdkNmIzNzI4NmU4MDI4JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBleHBpcmVUaW1lOiAxNjI3OTQ5MjE0LFxuICAgICAgICAgIGNvbnRyYWN0U2VxdWVuY2VJZDogMTIsXG4gICAgICAgICAgZ2FzTGltaXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBnYXNQcmljZTogdW5kZWZpbmVkLFxuICAgICAgICAgIGhvcFRyYW5zYWN0aW9uOiB1bmRlZmluZWQsXG4gICAgICAgICAgYmFja3VwS2V5Tm9uY2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICBzZXF1ZW5jZUlkOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiB1c2VyS2V5Y2hhaW4ucHJ2LFxuICAgICAgfSBhcyBhbnkpO1xuXG4gICAgICAoaGFsZlNpZ25lZFRyYW5zYWN0aW9uIGFzIGFueSkuaGFsZlNpZ25lZC5laXAxNTU5Lm1heFByaW9yaXR5RmVlUGVyR2FzLnNob3VsZC5lcXVhbCgxMCk7XG4gICAgICAoaGFsZlNpZ25lZFRyYW5zYWN0aW9uIGFzIGFueSkuaGFsZlNpZ25lZC5laXAxNTU5Lm1heEZlZVBlckdhcy5zaG91bGQuZXF1YWwoMTApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaWduIGEgdHJhbnNhY3Rpb24gd2l0aCBFSVAxNTU5IGZlZSBwYXJhbXMgZm9yIENDUicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgY29uc3Qgc2lnblRyYW5zYWN0aW9uID0gc2lub24uc3B5KEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zLnByb3RvdHlwZSwgJ3NpZ25UcmFuc2FjdGlvbicpO1xuXG4gICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgIHBydjogJ3hwcnY5czIxWnJRSDE0M0szaGVreU5qN1RjaVI0WE5ZZTFrTWo2OFcyaXBqSkdOSEVUV1A3bzQyQWpEblNQZ0toZFo0eDhOQkF2YUw3MlJyWGp1WE5kbWtNcUxFUlp6YTczb1l1Z0d0YkxGWEc4ZycsXG4gICAgICAgIHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHQmpFNVFHN3BrZjljWkQzM1VVRDZLNDZxN0VMcmJ1RzdGcVhmTE5HaVhZR0hlRW5HQmI1QVdSRW5rMWVBMjhnOEFyWnZVUmJoc2hYV2tUdGRkSFJvNTRmZ3lWdkxkYicsXG4gICAgICAgIHJhd1B1YjogJzAyMzYzNmU2OGI3YjIwNDU3M2FiZGEyNjE2YWZmNmI1ODQ5MTBkZWNlMjU0M2YxY2M2ZDg0MmNhYWM3ZDc0OTc0YicsXG4gICAgICAgIHJhd1BydjogJzc0MzhhNTAwMTBjZTdiMWRmZDg2ZTY4MDQ2Y2M3OGJhMWViZDI0MmQ2ZDg1ZDk5MDRkM2ZjYzA4NzM0YmMxNzInLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoJ2h0ZXRoJykgYXMgVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgICAgdHhCdWlsZGVyLmZlZSh7XG4gICAgICAgIGZlZTogJzEwJyxcbiAgICAgICAgZ2FzTGltaXQ6ICcxMDAwJyxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qga2V5ID0gdGVzdERhdGEuS0VZUEFJUl9QUlYuZ2V0S2V5cygpLnBydiBhcyBzdHJpbmc7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSB0eEJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgICAgLmFtb3VudCgnMCcpXG4gICAgICAgIC50bygnMHgxOTY0NTAzMmM3ZjE1MzMzOTVkNDRhNjI5NDYyZTc1MTA4NGQzZTRjJylcbiAgICAgICAgLmV4cGlyYXRpb25UaW1lKDE1OTAwNjY3MjgpXG4gICAgICAgIC5jb250cmFjdFNlcXVlbmNlSWQoNSlcbiAgICAgICAgLmtleShrZXkpO1xuICAgICAgdHhCdWlsZGVyLmNvbnRyYWN0KGFkZHJlc3MxKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG5cbiAgICAgIGNvbnN0IGhhbGZTaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwLCBtYXhGZWVQZXJHYXM6IDEwIH0sXG4gICAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhbW91bnQ6ICc0MicsXG4gICAgICAgICAgICAgIGFkZHJlc3M6ICcweGM5M2IxMzY0MmQ5M2I0MjE4YmI4NWY2NzMxN2Q2YjM3Mjg2ZTgwMjgnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGV4cGlyZVRpbWU6IDE2Mjc5NDkyMTQsXG4gICAgICAgICAgY29udHJhY3RTZXF1ZW5jZUlkOiAxMixcbiAgICAgICAgICBnYXNMaW1pdDogdW5kZWZpbmVkLFxuICAgICAgICAgIGdhc1ByaWNlOiB1bmRlZmluZWQsXG4gICAgICAgICAgaG9wVHJhbnNhY3Rpb246IHVuZGVmaW5lZCxcbiAgICAgICAgICBiYWNrdXBLZXlOb25jZTogdW5kZWZpbmVkLFxuICAgICAgICAgIHNlcXVlbmNlSWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICAgIHR4SGV4OiB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IHVzZXJLZXljaGFpbi5wcnYsXG4gICAgICAgIGlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk6IHRydWUsXG4gICAgICB9IGFzIGFueSk7XG5cbiAgICAgIGFzc2VydCgoaGFsZlNpZ25lZFRyYW5zYWN0aW9uIGFzIGFueSkuaGFsZlNpZ25lZC50eEhleCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoKGhhbGZTaWduZWRUcmFuc2FjdGlvbiBhcyBhbnkpLmhhbGZTaWduZWQuZWlwMTU1OS5tYXhGZWVQZXJHYXMsIDEwKTtcblxuICAgICAgc2FuZGJveC5hc3NlcnQuY2FsbGVkT25jZShzaWduVHJhbnNhY3Rpb24pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgbm9ybWFsIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgYmF0Y2ggdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfSxcbiAgICAgICAgICB7IGFtb3VudDogJzI1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMiB9LFxuICAgICAgICBdLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzM1MDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAoY29pbj8uc3RhdGljc0NvaW4/Lm5ldHdvcmsgYXMgRXRoZXJldW1OZXR3b3JrKS5iYXRjaGVyQ29udHJhY3RBZGRyZXNzIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgRU5TIGFkZHJlc3MgcmVzb2x1dGlvbiBjaGFuZ2luZyByZWNpcGllbnQgYWRkcmVzcyBpbiBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogJ2JpdGdvdGVzdHdhbGxldC5ldGgnIH1dLFxuICAgICAgICB3YWxsZXQ6IHdhbGxldCxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ2Zha2VXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiAnMHg0MGE2NjM5NjM4MTA0NDlkNmU3MjUzMzY1N2E3NGYxMTJjM2I5MDFhJyB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFBhcmFtcyxcbiAgICAgICAgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksXG4gICAgICAgIHdhbGxldCxcbiAgICAgICAgdmVyaWZpY2F0aW9uLFxuICAgICAgfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSBob3AgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgdGhhdCBtYXRjaGVzIHRoZSBjbGllbnQgdHhQYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6IDEwMDAwMDAwMDAwMDAwMDAsIGFkZHJlc3M6IGhvcERlc3RpbmF0aW9uQWRkcmVzcyB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICAgIGhvcDogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzUwMDAwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBob3BDb250cmFjdEFkZHJlc3MgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgaG9wVHJhbnNhY3Rpb246IHtcbiAgICAgICAgICB0eDogaG9wVHgsXG4gICAgICAgICAgaWQ6IGhvcFR4aWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBob3BUeEJpdGdvU2lnbmF0dXJlLFxuICAgICAgICAgIHBheW1lbnRJZDogJzI3NzM5MjgxOTYnLFxuICAgICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIHJlY2lwaWVudDogaG9wRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIG5vbmNlOiAwLFxuICAgICAgICAgIHVzZXJSZXFTaWc6IHVzZXJSZXFTaWcsXG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDUwMDAwMDAwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IHdoZW4gY2xpZW50IHR4UGFyYW1zIGFyZSBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG51bGw7XG5cbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiBmYWxzZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXM6IHR4UGFyYW1zIGFzIGFueSwgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHBhcmFtcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgdHhQcmVidWlsZCB0aGF0IGlzIGJvdGggYmF0Y2ggYW5kIGhvcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBob3A6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICczNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogdHJ1ZSxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgICBob3BUcmFuc2FjdGlvbjoge1xuICAgICAgICAgIHR4OiBob3BUeCxcbiAgICAgICAgICBpZDogaG9wVHhpZCxcbiAgICAgICAgICBzaWduYXR1cmU6IGhvcFR4Qml0Z29TaWduYXR1cmUsXG4gICAgICAgICAgcGF5bWVudElkOiAnMjc3MzkyODE5NicsXG4gICAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgYW1vdW50OiAnMTAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgcmVjaXBpZW50OiBob3BEZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgbm9uY2U6IDAsXG4gICAgICAgICAgdXNlclJlcVNpZzogdXNlclJlcVNpZyxcbiAgICAgICAgICBnYXNQcmljZU1heDogNTAwMDAwMDAwMDAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndHggY2Fubm90IGJlIGJvdGggYSBiYXRjaCBhbmQgaG9wIHRyYW5zYWN0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIHR4UHJlYnVpbGQgd2l0aCBtb3JlIHRoYW4gb25lIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9LFxuICAgICAgICAgIHsgYW1vdW50OiAnMjUwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MyIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV4dENvbnRyYWN0U2VxdWVuY2VJZDogMCxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBpc0JhdGNoOiB0cnVlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgIGB0ZXRoIGRvZXNuJ3Qgc3VwcG9ydCBzZW5kaW5nIHRvIG1vcmUgdGhhbiAxIGRlc3RpbmF0aW9uIGFkZHJlc3Mgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiBUcnkgYWdhaW4sIHVzaW5nIG9ubHkgYSBzaW5nbGUgcmVjaXBpZW50LmBcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgaG9wIHR4UHJlYnVpbGQgdGhhdCBkb2VzIG5vdCBzZW5kIHRvIGl0cyBob3AgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBob3BEZXN0aW5hdGlvbkFkZHJlc3MgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICBob3A6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICc1MDAwMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgICAgaG9wVHJhbnNhY3Rpb246IHtcbiAgICAgICAgICB0eDogaG9wVHgsXG4gICAgICAgICAgaWQ6IGhvcFR4aWQsXG4gICAgICAgICAgc2lnbmF0dXJlOiBob3BUeEJpdGdvU2lnbmF0dXJlLFxuICAgICAgICAgIHBheW1lbnRJZDogJzAnLFxuICAgICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIHJlY2lwaWVudDogaG9wRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIG5vbmNlOiAwLFxuICAgICAgICAgIHVzZXJSZXFTaWc6IHVzZXJSZXFTaWcsXG4gICAgICAgICAgZ2FzUHJpY2VNYXg6IDUwMDAwMDAwMDAwMCxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3JlY2lwaWVudCBhZGRyZXNzIG9mIHR4UHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggaG9wIGFkZHJlc3MnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgYmF0Y2ggdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgdG90YWwgYW1vdW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgeyBhbW91bnQ6ICc1NTAwMDAwMDAwMDAwJywgYWRkcmVzczogKGNvaW4/LnN0YXRpY3NDb2luPy5uZXR3b3JrIGFzIEV0aGVyZXVtTmV0d29yaykuYmF0Y2hlckNvbnRyYWN0QWRkcmVzcyB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ2JhdGNoIHRyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIHJlY2VpdmVkIGZyb20gQml0R28gc2VydmVycyBkb2VzIG5vdCBtYXRjaCB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIGJhdGNoIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgZG9lcyBub3Qgc2VuZCB0byB0aGUgYmF0Y2hlciBjb250cmFjdCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuICAgICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgY29pbiwge30pO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHsgYW1vdW50OiAnMTAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH0sXG4gICAgICAgICAgeyBhbW91bnQ6ICcyNTAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICczNTAwMDAwMDAwMDAwJywgYWRkcmVzczogaG9wQ29udHJhY3RBZGRyZXNzIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IHRydWUsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3JlY2lwaWVudCBhZGRyZXNzIG9mIHR4UHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggYmF0Y2hlciBhZGRyZXNzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhIG5vcm1hbCB0eFByZWJ1aWxkIGZyb20gdGhlIGJpdGdvIHNlcnZlciB3aXRoIHRoZSB3cm9uZyBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBjb2luLCB7fSk7XG5cbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIHdhbGxldDogd2FsbGV0LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZmFrZVdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW3sgYW1vdW50OiAnMjAwMDAwMDAwMDAwMCcsIGFkZHJlc3M6IGFkZHJlc3MxIH1dLFxuICAgICAgICBuZXh0Q29udHJhY3RTZXF1ZW5jZUlkOiAwLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGlzQmF0Y2g6IGZhbHNlLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIHdhbGxldElkOiAnZmFrZVdhbGxldElkJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnZmFrZVdhbGxldENvbnRyYWN0QWRkcmVzcycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcblxuICAgICAgYXdhaXQgY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZDogdHhQcmVidWlsZCBhcyBhbnksIHdhbGxldCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdub3JtYWwgdHJhbnNhY3Rpb24gYW1vdW50IGluIHR4UHJlYnVpbGQgcmVjZWl2ZWQgZnJvbSBCaXRHbyBzZXJ2ZXJzIGRvZXMgbm90IG1hdGNoIHR4UGFyYW1zIHN1cHBsaWVkIGJ5IGNsaWVudCdcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbm9ybWFsIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHdpdGggdGhlIHdyb25nIHJlY2lwaWVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczIgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkOiB0eFByZWJ1aWxkIGFzIGFueSwgd2FsbGV0LCB2ZXJpZmljYXRpb24gfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ2Rlc3RpbmF0aW9uIGFkZHJlc3MgaW4gbm9ybWFsIHR4UHJlYnVpbGQgZG9lcyBub3QgbWF0Y2ggdGhhdCBpbiB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHRva2VuIHR4UHJlYnVpbGQgZnJvbSB0aGUgYml0Z28gc2VydmVyIHRoYXQgbWF0Y2hlcyB0aGUgY2xpZW50IHR4UGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3Rlc3QnKTtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgdG9rZW46ICd0ZXN0JyxcbiAgICAgICAgd2FsbGV0SWQ6ICdmYWtlV2FsbGV0SWQnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICdmYWtlV2FsbGV0Q29udHJhY3RBZGRyZXNzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQYXJhbXMsXG4gICAgICAgIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LFxuICAgICAgICB3YWxsZXQsXG4gICAgICAgIHZlcmlmaWNhdGlvbixcbiAgICAgIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgdHhQcmVidWlsZCBmcm9tIHRoZSBiaXRnbyBzZXJ2ZXIgd2l0aCB0aGUgd3JvbmcgY29pbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcbiAgICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGNvaW4sIHt9KTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFt7IGFtb3VudDogJzEwMDAwMDAwMDAwMDAnLCBhZGRyZXNzOiBhZGRyZXNzMSB9XSxcbiAgICAgICAgd2FsbGV0OiB3YWxsZXQsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmYWtlV2FsbGV0UGFzc3BocmFzZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbeyBhbW91bnQ6ICcxMDAwMDAwMDAwMDAwJywgYWRkcmVzczogYWRkcmVzczEgfV0sXG4gICAgICAgIG5leHRDb250cmFjdFNlcXVlbmNlSWQ6IDAsXG4gICAgICAgIGdhc1ByaWNlOiAyMDAwMDAwMDAwMCxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgaXNCYXRjaDogZmFsc2UsXG4gICAgICAgIGNvaW46ICdidGMnLFxuICAgICAgICB3YWxsZXRJZDogJ2Zha2VXYWxsZXRJZCcsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogJ2Zha2VXYWxsZXRDb250cmFjdEFkZHJlc3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGF3YWl0IGNvaW5cbiAgICAgICAgLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQ6IHR4UHJlYnVpbGQgYXMgYW55LCB3YWxsZXQsIHZlcmlmaWNhdGlvbiB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnY29pbiBpbiB0eFByZWJ1aWxkIGRpZCBub3QgbWF0Y2ggdGhhdCBpbiB0eFBhcmFtcyBzdXBwbGllZCBieSBjbGllbnQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZHJlc3MgVmVyaWZpY2F0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGFuIGFkZHJlc3MgZ2VuZXJhdGVkIHVzaW5nIGZvcndhcmRlciB2ZXJzaW9uIDAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgaWQ6ICc2MTI3YmZmNGVjZDg0YzAwMDZjZDlhMGU1Y2NkYzM2ZicsXG4gICAgICAgIGNoYWluOiAwLFxuICAgICAgICBpbmRleDogMzE3NCxcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICBsYXN0Tm9uY2U6IDAsXG4gICAgICAgIHdhbGxldDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgYmFzZUFkZHJlc3M6ICcweGRmMDcxMTc3MDVhOWY4ZGM0YzJhNzhkZTY2YjdmMTc5N2RiYTlkNGUnLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMDgtMjZUMTY6MjM6MTYuNTYzWicsXG4gICAgICAgICAgdHhDb3VudDogMCxcbiAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogdHJ1ZSxcbiAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgIHBlbmRpbmdEZXBsb3ltZW50OiBmYWxzZSxcbiAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAwLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaXNBZGRyZXNzVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeUFkZHJlc3MocGFyYW1zIGFzIGFueSk7XG4gICAgICBpc0FkZHJlc3NWZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhbiBhZGRyZXNzIGdlbmVyYXRlZCB1c2luZyBmb3J3YXJkZXIgdmVyc2lvbiAxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGlkOiAnNjEyNTAyMTdjOGMwMmIwMDA2NTRiMTVlN2FmNmY2MTgnLFxuICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgY2hhaW46IDAsXG4gICAgICAgIGluZGV4OiAzMTYyLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIGxhc3ROb25jZTogMCxcbiAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIG5vbmNlOiAtMSxcbiAgICAgICAgICB1cGRhdGVUaW1lOiAnMjAyMS0wOC0yNFQxNDoyODozOS44NDFaJyxcbiAgICAgICAgICB0eENvdW50OiAwLFxuICAgICAgICAgIHBlbmRpbmdDaGFpbkluaXRpYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICAgIGNyZWF0aW9uRmFpbHVyZTogW10sXG4gICAgICAgICAgc2FsdDogJzB4YzVhJyxcbiAgICAgICAgICBwZW5kaW5nRGVwbG95bWVudDogdHJ1ZSxcbiAgICAgICAgICBmb3J3YXJkZXJWZXJzaW9uOiAxLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgaXNBZGRyZXNzVmVyaWZpZWQgPSBhd2FpdCBjb2luLnZlcmlmeUFkZHJlc3MocGFyYW1zKTtcbiAgICAgIGlzQWRkcmVzc1ZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFkZHJlc3MgdmVyaWZpY2F0aW9uIGlmIGNvaW5TcGVjaWZpYyBmaWVsZCBpcyBub3QgYW4gb2JqZWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGlkOiAnNjEyNTAyMTdjOGMwMmIwMDA2NTRiMTVlN2FmNmY2MTgnLFxuICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgY2hhaW46IDAsXG4gICAgICAgIGluZGV4OiAzMTYyLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIGxhc3ROb25jZTogMCxcbiAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBiYXNlQWRkcmVzczogJzB4ZGYwNzExNzcwNWE5ZjhkYzRjMmE3OGRlNjZiN2YxNzk3ZGJhOWQ0ZScsXG4gICAgICB9O1xuXG4gICAgICBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLnZlcmlmeUFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NWZXJpZmljYXRpb25PYmplY3RQcm9wZXJ0eUVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFkZHJlc3MgdmVyaWZpY2F0aW9uIHdoZW4gYW4gYWN0dWFsIGFkZHJlc3MgaXMgZGlmZmVyZW50IGZyb20gZXhwZWN0ZWQgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBpZDogJzYxMjUwMjE3YzhjMDJiMDAwNjU0YjE1ZTdhZjZmNjE4JyxcbiAgICAgICAgYWRkcmVzczogJzB4Mjg5MDQ1OTFmNzM1OTk0ZjA1MDgwNGZkYTNiNjFiODEzYjE2ZTA0YycsXG4gICAgICAgIGNoYWluOiAwLFxuICAgICAgICBpbmRleDogMzE2MixcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICBsYXN0Tm9uY2U6IDAsXG4gICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMDgtMjRUMTQ6Mjg6MzkuODQxWicsXG4gICAgICAgICAgdHhDb3VudDogMCxcbiAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogdHJ1ZSxcbiAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgcGVuZGluZ0RlcGxveW1lbnQ6IHRydWUsXG4gICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4udmVyaWZ5QWRkcmVzcyhwYXJhbXMpLCBVbmV4cGVjdGVkQWRkcmVzc0Vycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFkZHJlc3MgdmVyaWZpY2F0aW9uIGlmIHRoZSBkZXJpdmVkIGFkZHJlc3MgaXMgaW4gaW52YWxpZCBmb3JtYXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgaWQ6ICc2MTI1MDIxN2M4YzAyYjAwMDY1NGIxNWU3YWY2ZjYxOCcsXG4gICAgICAgIGFkZHJlc3M6ICcweGUwYjU2ZWVhZTFiMjgzOTE4Y2FjYTAyYTE0YWRhMmRmMTdhOThidmYnLFxuICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgaW5kZXg6IDMxNjIsXG4gICAgICAgIGNvaW46ICd0ZXRoJyxcbiAgICAgICAgbGFzdE5vbmNlOiAwLFxuICAgICAgICB3YWxsZXQ6ICc1OThmNjA2Y2Q4ZmMyNDcxMGQyZWJhZGIxZDk0NTliYicsXG4gICAgICAgIGJhc2VBZGRyZXNzOiAnMHhkZjA3MTE3NzA1YTlmOGRjNGMyYTc4ZGU2NmI3ZjE3OTdkYmE5ZDRlJyxcbiAgICAgICAgY29pblNwZWNpZmljOiB7XG4gICAgICAgICAgbm9uY2U6IC0xLFxuICAgICAgICAgIHVwZGF0ZVRpbWU6ICcyMDIxLTA4LTI0VDE0OjI4OjM5Ljg0MVonLFxuICAgICAgICAgIHR4Q291bnQ6IDAsXG4gICAgICAgICAgcGVuZGluZ0NoYWluSW5pdGlhbGl6YXRpb246IHRydWUsXG4gICAgICAgICAgY3JlYXRpb25GYWlsdXJlOiBbXSxcbiAgICAgICAgICBzYWx0OiAnMHhjNWEnLFxuICAgICAgICAgIHBlbmRpbmdEZXBsb3ltZW50OiB0cnVlLFxuICAgICAgICAgIGZvcndhcmRlclZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBjb2luLnZlcmlmeUFkZHJlc3MocGFyYW1zKSwgSW52YWxpZEFkZHJlc3NFcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBhZGRyZXNzIHZlcmlmaWNhdGlvbiBpZiBiYXNlIGFkZHJlc3MgaXMgdW5kZWZpbmVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9IGJpdGdvLmNvaW4oJ3RldGgnKSBhcyBUZXRoO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGlkOiAnNjEyNTAyMTdjOGMwMmIwMDA2NTRiMTVlN2FmNmY2MTgnLFxuICAgICAgICBhZGRyZXNzOiAnMHhiMGI1NmVlYWUxYjI4MzkxOGNhY2EwMmExNGFkYTJkZjE3YTk4ZTZkJyxcbiAgICAgICAgY2hhaW46IDAsXG4gICAgICAgIGluZGV4OiAzMTYyLFxuICAgICAgICBjb2luOiAndGV0aCcsXG4gICAgICAgIGxhc3ROb25jZTogMCxcbiAgICAgICAgd2FsbGV0OiAnNTk4ZjYwNmNkOGZjMjQ3MTBkMmViYWRiMWQ5NDU5YmInLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMDgtMjRUMTQ6Mjg6MzkuODQxWicsXG4gICAgICAgICAgdHhDb3VudDogMCxcbiAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogdHJ1ZSxcbiAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgcGVuZGluZ0RlcGxveW1lbnQ6IHRydWUsXG4gICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4udmVyaWZ5QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFkZHJlc3MgdmVyaWZpY2F0aW9uIGlmIGJhc2UgYWRkcmVzcyBpcyBpbiBpbnZhbGlkIGZvcm1hdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvaW4gPSBiaXRnby5jb2luKCd0ZXRoJykgYXMgVGV0aDtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBpZDogJzYxMjUwMjE3YzhjMDJiMDAwNjU0YjE1ZTdhZjZmNjE4JyxcbiAgICAgICAgYWRkcmVzczogJzB4YjBiNTZlZWFlMWIyODM5MThjYWNhMDJhMTRhZGEyZGYxN2E5OGU2ZCcsXG4gICAgICAgIGNoYWluOiAwLFxuICAgICAgICBpbmRleDogMzE2MixcbiAgICAgICAgY29pbjogJ3RldGgnLFxuICAgICAgICBsYXN0Tm9uY2U6IDAsXG4gICAgICAgIHdhbGxldDogJzU5OGY2MDZjZDhmYzI0NzEwZDJlYmFkYjFkOTQ1OWJiJyxcbiAgICAgICAgYmFzZUFkZHJlc3M6ICcweGUwYjU2ZWVhZTFiMjgzOTE4Y2FjYTAyYTE0YWRhMmRmMTdhOThidmYnLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICBub25jZTogLTEsXG4gICAgICAgICAgdXBkYXRlVGltZTogJzIwMjEtMDgtMjRUMTQ6Mjg6MzkuODQxWicsXG4gICAgICAgICAgdHhDb3VudDogMCxcbiAgICAgICAgICBwZW5kaW5nQ2hhaW5Jbml0aWFsaXphdGlvbjogdHJ1ZSxcbiAgICAgICAgICBjcmVhdGlvbkZhaWx1cmU6IFtdLFxuICAgICAgICAgIHNhbHQ6ICcweGM1YScsXG4gICAgICAgICAgcGVuZGluZ0RlcGxveW1lbnQ6IHRydWUsXG4gICAgICAgICAgZm9yd2FyZGVyVmVyc2lvbjogMSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGNvaW4udmVyaWZ5QWRkcmVzcyhwYXJhbXMpLCBJbnZhbGlkQWRkcmVzc0Vycm9yKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0VWTSBDcm9zcyBDaGFpbiBSZWNvdmVyeScsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgIGl0KCdzaG91bGQgYnVpbGQgYSByZWNvdmVyeSB0cmFuc2FjdGlvbiBmb3IgaG90IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHVzZXJLZXkgPVxuICAgICAgICAne1wiaXZcIjpcIlZGWjNqdlhoeG8xWitZYWYyTXRabkE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInArZmtIdUxhLzhrPVwiLFwiY3RcIjpcImhZRzdwdmxqTElnQ2paXFxuJyArXG4gICAgICAgICc1M1BCbENkZTVLWlJtbFVLS0hMdERNaytISmZ1VTQ2aFcreCtDOVdzSUFPNGdGUG5UQ3ZGVm1ROHg3Y3pDdGNORnViNUFPMm90T0dcXG4nICtcbiAgICAgICAgJ09zWDRHRTJnWE9FbUNsMVRwV3d3TmhtN3lNVWpHSlVwZ1c2WlpnWFNYZERpdFNLaTRWL2hrNzhTR1N6akZPQlNQWVJhNkk9XCJ9XFxuJztcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1QURkRTE3ZmVEOGJhZWQzRjMyYjg0QUYwNUI4RjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KHdhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCBzcHkgPSBzaW5vbi5zcHkoVHJhbnNhY3Rpb25CdWlsZGVyLnByb3RvdHlwZSwgJ2NvaW5Vc2VzTm9uUGFja2VkRW5jb2RpbmdGb3JUeERhdGEnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBpbnRlbmRlZENoYWluOiAndGFyYmV0aCcsXG4gICAgICB9KTtcbiAgICAgIGFzc2VydChzcHkucmV0dXJuZWQodHJ1ZSkpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ05vbi1CaXRHbyBSZWNvdmVyeSBmb3IgSG90IFdhbGxldHMgKE1QQ3YyKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJhc2VVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQmFzZVVybCBhcyBzdHJpbmc7XG4gICAgICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgICAgIGxldCBiYXNlY29pbjogSHRldGg7XG5cbiAgICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgICAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJykgYXMgSHRldGg7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhIHJlY292ZXJ5IHRyYW5zYWN0aW9uIGZvciBNUEN2MiBraW5kIG9mIGhvdCB3YWxsZXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFR4TGlzdFJlcXVlc3QobW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpLmJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QobW9ja0RhdGEuZ2V0Tm9uQml0R29SZWNvdmVyeUZvckhvdFdhbGxldHNNUEN2MigpLmJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldE5vbkJpdEdvUmVjb3ZlcnlGb3JIb3RXYWxsZXRzTVBDdjIoKS53YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXROb25CaXRHb1JlY292ZXJ5Rm9ySG90V2FsbGV0c01QQ3YyKCk7XG5cbiAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogcGFyYW1zLmJhY2t1cEtleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBwYXJhbXMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBwYXJhbXMuYml0Z29GZWVBZGRyZXNzLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogcGFyYW1zLmJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICAgIGludGVuZGVkQ2hhaW46IHBhcmFtcy5pbnRlbmRlZENoYWluLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QodHJhbnNhY3Rpb24pO1xuICAgICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIHVzZXIga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRJbnZhbGlkTm9uQml0R29SZWNvdmVyeVBhcmFtcygpO1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHVzZXJLZXk6IHBhcmFtcy51c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHBhcmFtcy53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgICAgIGJpdGdvRmVlQWRkcmVzczogcGFyYW1zLmJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgICAgICAgIGJpdGdvRGVzdGluYXRpb25BZGRyZXNzOiBwYXJhbXMuYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgICAgIGludGVuZGVkQ2hhaW46IHBhcmFtcy5pbnRlbmRlZENoYWluLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBFcnJvcixcbiAgICAgICAgICAndXNlciBrZXkgaXMgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0J1aWxkIFVuc2lnbmVkIFN3ZWVwIGZvciBTZWxmLUN1c3RvZHkgQ29sZCBXYWxsZXRzIChNUEN2MiknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlVXJsID0gY29tbW9uLkVudmlyb25tZW50cy50ZXN0LmV0aGVyc2NhbkJhc2VVcmwgYXMgc3RyaW5nO1xuICAgICAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gICAgICBsZXQgYmFzZWNvaW46IEh0ZXRoO1xuXG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICAgICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpIGFzIEh0ZXRoO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgc3dlZXAgd2l0aG91dCBkZXJpdmF0aW9uIHNlZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKS5hZGRyZXNzKSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KFxuICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoXG4gICAgICAgICAgICAgIG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLndhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuXG4gICAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0gbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCk7XG4gICAgICAgIGNvbnN0IHN3ZWVwUmVzdWx0ID0gYXdhaXQgKGJhc2Vjb2luIGFzIEFic3RyYWN0RXRoTGlrZU5ld0NvaW5zKS5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBBIERhdGFcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEIgRGF0YVxuICAgICAgICAgIGRlcml2YXRpb25TZWVkOiBwYXJhbXMuZGVyaXZhdGlvblNlZWQsIC8vIEtleSBEZXJpdmF0aW9uIFNlZWQgKG9wdGlvbmFsKVxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgZ2FzTGltaXQ6IDIwMDAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3Qoc3dlZXBSZXN1bHQpO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBzd2VlcFJlc3VsdCBhcyBVbnNpZ25lZFN3ZWVwVHhNUEN2MjtcbiAgICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29pbicpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc2lnbmVkVHgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXJzZWRUeCcpO1xuICAgICAgICBjb25zdCBwYXJzZWRUeCA9IG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgc3BlbmRBbW91bnQ6IHN0cmluZyB9O1xuICAgICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgICAgKG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgb3V0cHV0czogYW55W10gfSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgJ291dHB1dHMnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gPSAnaW52YWxpZEFkZHJlc3MnO1xuXG4gICAgICAgIC8vIEVuc3VyZSB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIHRoZSBzYW1lXG4gICAgICAgIHBhcmFtcy51c2VyS2V5ID1cbiAgICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG4gICAgICAgIHBhcmFtcy5iYWNrdXBLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgICAgICBnYXNMaW1pdDogMjAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSwgLy8gUHJvdmlkZSB0aGUgdXNlcktleVxuICAgICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksIC8vIFByb3ZpZGUgdGhlIGJhY2t1cEtleVxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsIC8vIFByb3ZpZGUgdGhlIHdhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIEVycm9yLFxuICAgICAgICAgICdFcnJvcjogaW52YWxpZCBhZGRyZXNzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQnVpbGQgVW5zaWduZWQgQ29uc29saWRhdGlvbiBmb3IgU2VsZi1DdXN0b2R5IENvbGQgV2FsbGV0cyAoTVBDdjIpJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZVVybCA9IGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5CYXNlVXJsIGFzIHN0cmluZztcbiAgICAgIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICAgICAgbGV0IGJhc2Vjb2luOiBIdGV0aDtcblxuICAgICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAndGVzdCcgfSk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIGNvbnNvbGlkYXRpb24gZm9yIHdhbGxldCB2NScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkoXG4gICAgICAgICAgICBtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChcbiAgICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgY29uc3QgY29uc29saWRhdGlvblJlc3VsdCA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEIgRGF0YVxuICAgICAgICAgIGRlcml2YXRpb25TZWVkOiBwYXJhbXMuZGVyaXZhdGlvblNlZWQsIC8vIEtleSBEZXJpdmF0aW9uIFNlZWQgKG9wdGlvbmFsKVxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgZ2FzTGltaXQ6IDIwMDAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiAnNDInLFxuICAgICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYml0Z29GZWVBZGRyZXNzOiAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JyxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBzaG91bGQuZXhpc3QoY29uc29saWRhdGlvblJlc3VsdCk7XG4gICAgICAgIGNvbnN0IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24gPSBjb25zb2xpZGF0aW9uUmVzdWx0IGFzIFVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb247XG4gICAgICAgIHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnNbMF0gYXMgTVBDU3dlZXBUeHM7XG4gICAgICAgIG91dHB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhSZXF1ZXN0cycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb2luJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9ucy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2VyaWFsaXplZFR4SGV4Jyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzaWduYWJsZUhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3BhcnNlZFR4Jyk7XG4gICAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICAgIHBhcnNlZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzcGVuZEFtb3VudCcpO1xuICAgICAgICAob3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBvdXRwdXRzOiBhbnlbXSB9KS5zaG91bGQuaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAnb3V0cHV0cydcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIGNvbnNvbGlkYXRpb24gZm9yIHdhbGxldCB2NicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcblxuICAgICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KG1vY2tEYXRhLmdldEJ1aWxkVW5zaWduZWRTd2VlcEZvclNlbGZDdXN0b2R5Q29sZFdhbGxldHNNUEN2MigpLmFkZHJlc3MpKVxuICAgICAgICAgIC50aW1lcygyKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgICAucXVlcnkoXG4gICAgICAgICAgICBtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChcbiAgICAgICAgICAgICAgbW9ja0RhdGEuZ2V0QnVpbGRVbnNpZ25lZFN3ZWVwRm9yU2VsZkN1c3RvZHlDb2xkV2FsbGV0c01QQ3YyKCkud2FsbGV0Q29udHJhY3RBZGRyZXNzXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgY29uc3QgY29uc29saWRhdGlvblJlc3VsdCA9IGF3YWl0IChiYXNlY29pbiBhcyBBYnN0cmFjdEV0aExpa2VOZXdDb2lucykucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMuY29tbW9uS2V5Q2hhaW4sIC8vIEJveCBBIERhdGFcbiAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5jb21tb25LZXlDaGFpbiwgLy8gQm94IEIgRGF0YVxuICAgICAgICAgIGRlcml2YXRpb25TZWVkOiBwYXJhbXMuZGVyaXZhdGlvblNlZWQsIC8vIEtleSBEZXJpdmF0aW9uIFNlZWQgKG9wdGlvbmFsKVxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uLCAvLyBEZXN0aW5hdGlvbiBBZGRyZXNzXG4gICAgICAgICAgZ2FzTGltaXQ6IDIwMDAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSwgLy8gTWF4IEZlZSBQZXIgR2FzIGFuZCBNYXggUHJpb3JpdHkgRmVlIFBlciBHYXNcbiAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICcxMjMnLCAvLyBXcm9uZyB3YWxsZXQgYWRkcmVzcyBzbyB0aGF0IHdlIGNhbiBza2lwIHY1IGFkZHJlc3MgZ2VuZXJhdGlvblxuICAgICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvRmVlQWRkcmVzczogJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNycsXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KGNvbnNvbGlkYXRpb25SZXN1bHQpO1xuICAgICAgICBjb25zdCB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uID0gY29uc29saWRhdGlvblJlc3VsdCBhcyBVbnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uO1xuICAgICAgICB1bnNpZ25lZEJ1aWxDb25zb2xpZGF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgICAgdW5zaWduZWRCdWlsQ29uc29saWRhdGlvbi50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuXG4gICAgICAgIGNvbnN0IG91dHB1dCA9IHVuc2lnbmVkQnVpbENvbnNvbGlkYXRpb24udHJhbnNhY3Rpb25zWzBdIGFzIE1QQ1N3ZWVwVHhzO1xuICAgICAgICBvdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4UmVxdWVzdHMnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9ucycpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29pbicpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Vuc2lnbmVkVHgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc2lnbmFibGVIZXgnKTtcbiAgICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Rlcml2YXRpb25QYXRoJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXJzZWRUeCcpO1xuICAgICAgICBjb25zdCBwYXJzZWRUeCA9IG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgc3BlbmRBbW91bnQ6IHN0cmluZyB9O1xuICAgICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgICAgKG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnBhcnNlZFR4IGFzIHsgb3V0cHV0czogYW55W10gfSkuc2hvdWxkLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgJ291dHB1dHMnXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBmb3IgaW52YWxpZCBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSBtb2NrRGF0YS5nZXRCdWlsZFVuc2lnbmVkU3dlZXBGb3JTZWxmQ3VzdG9keUNvbGRXYWxsZXRzTVBDdjIoKTtcbiAgICAgICAgcGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24gPSAnaW52YWxpZEFkZHJlc3MnO1xuXG4gICAgICAgIC8vIEVuc3VyZSB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIHRoZSBzYW1lXG4gICAgICAgIHBhcmFtcy51c2VyS2V5ID1cbiAgICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG4gICAgICAgIHBhcmFtcy5iYWNrdXBLZXkgPVxuICAgICAgICAgICcwMjM0ZWIzOWIyMmZlZDUyM2VjZTdjNzhkYTI5YmExZjFkZTViNjRhNmU0ODAxM2UwOTE0ZGU3OTNiYzFkZjA1NzBlNzc5ZGUwNDc1ODczMjczNGQ5N2U1NGI3ODJjOGIzMzYyODM4MTFhZjZhMmM1N2JkODE0Mzg3OThlMWMyNDQ2JztcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCAoYmFzZWNvaW4gYXMgQWJzdHJhY3RFdGhMaWtlTmV3Q29pbnMpLnJlY292ZXIoe1xuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBwYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbiwgLy8gRGVzdGluYXRpb24gQWRkcmVzc1xuICAgICAgICAgICAgICBnYXNMaW1pdDogMjAwMCwgLy8gR2FzIExpbWl0XG4gICAgICAgICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMCB9LCAvLyBNYXggRmVlIFBlciBHYXMgYW5kIE1heCBQcmlvcml0eSBGZWUgUGVyIEdhc1xuICAgICAgICAgICAgICB1c2VyS2V5OiBwYXJhbXMudXNlcktleSwgLy8gUHJvdmlkZSB0aGUgdXNlcktleVxuICAgICAgICAgICAgICBiYWNrdXBLZXk6IHBhcmFtcy5iYWNrdXBLZXksIC8vIFByb3ZpZGUgdGhlIGJhY2t1cEtleVxuICAgICAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHBhcmFtcy53YWxsZXRDb250cmFjdEFkZHJlc3MsIC8vIFByb3ZpZGUgdGhlIHdhbGxldENvbnRyYWN0QWRkcmVzc1xuICAgICAgICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBjaGFpbjogJzQyJyxcbiAgICAgICAgICAgICAgICBoYXJkZm9yazogJ2xvbmRvbicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIEVycm9yLFxuICAgICAgICAgICdFcnJvcjogaW52YWxpZCBhZGRyZXNzJ1xuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgb3ZlcnJpZGUgdGhlIHRva2VuIHBhcmFtZXRlciB3aXRoIGEgY3VzdG9tIEFQSSBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb2luID0gYml0Z28uY29pbigndGV0aCcpIGFzIFRldGg7XG4gICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgIGFjdGlvbjogJ2JhbGFuY2UnLFxuICAgICAgICBhZGRyZXNzOiAnMHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwJyxcbiAgICAgIH07XG4gICAgICBjb25zdCBjdXN0b21BcGlLZXkgPSAnY3VzdG9tLWFwaS1rZXktZm9yLXRlc3QnO1xuXG4gICAgICAvLyBNb2NrIHRoZSBlbnZpcm9ubWVudCBBUEkgdG9rZW5cbiAgICAgIGNvbnN0IG9yaWdpbmFsQXBpVG9rZW4gPSBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQXBpVG9rZW47XG4gICAgICBjb21tb24uRW52aXJvbm1lbnRzLnRlc3QuZXRoZXJzY2FuQXBpVG9rZW4gPSAnZGVmYXVsdC1lbnZpcm9ubWVudC1hcGkta2V5JztcblxuICAgICAgLy8gTW9jayB0aGUgcmVxdWVzdC5nZXQgZnVuY3Rpb24gdG8gY2FwdHVyZSB0aGUgcXVlcnkgcGFyYW1ldGVyc1xuICAgICAgY29uc3Qgb3JpZ2luYWxHZXQgPSByZXF1ZXN0LmdldDtcbiAgICAgIGxldCBjYXB0dXJlZFF1ZXJ5O1xuXG4gICAgICByZXF1ZXN0LmdldCA9IGZ1bmN0aW9uICh1cmw6IHN0cmluZykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHF1ZXJ5OiBmdW5jdGlvbiAocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgICAgICAgICBjYXB0dXJlZFF1ZXJ5ID0gcGFyYW1zO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgICAgIGJvZHk6IHsgcmVzdWx0OiAnMTAwMDAwMDAwJyB9LFxuICAgICAgICAgICAgfSBhcyBhbnk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBhbnk7XG4gICAgICB9O1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBDYWxsIHdpdGggZGVmYXVsdCBBUEkga2V5XG4gICAgICAgIGF3YWl0IGNvaW4ucmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeShxdWVyeSk7XG4gICAgICAgIGNhcHR1cmVkUXVlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FwaWtleScsICdkZWZhdWx0LWVudmlyb25tZW50LWFwaS1rZXknKTtcblxuICAgICAgICAvLyBDYWxsIHdpdGggY3VzdG9tIEFQSSBrZXlcbiAgICAgICAgYXdhaXQgY29pbi5yZWNvdmVyeUJsb2NrY2hhaW5FeHBsb3JlclF1ZXJ5KHF1ZXJ5LCBjdXN0b21BcGlLZXkpO1xuICAgICAgICBjYXB0dXJlZFF1ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhcGlrZXknLCBjdXN0b21BcGlLZXkpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLy8gUmVzdG9yZSBvcmlnaW5hbCBmdW5jdGlvbiBhbmQgQVBJIHRva2VuXG4gICAgICAgIHJlcXVlc3QuZ2V0ID0gb3JpZ2luYWxHZXQ7XG4gICAgICAgIGNvbW1vbi5FbnZpcm9ubWVudHMudGVzdC5ldGhlcnNjYW5BcGlUb2tlbiA9IG9yaWdpbmFsQXBpVG9rZW47XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBdWRpdCBLZXknLCAoKSA9PiB7XG4gICAgbGV0IGNvaW46IEh0ZXRoO1xuICAgIGJlZm9yZSgoKSA9PiB7XG4gICAgICBjb2luID0gYml0Z28uY29pbignaHRldGgnKSBhcyBIdGV0aDtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdNdWx0aVNpZycsICgpID0+IHtcbiAgICAgIGNvbnN0IHsga2V5IH0gPSBldGhNdWx0aVNpZ0JhY2t1cEtleTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4geyBpc1ZhbGlkOiB0cnVlIH0gZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnWlE4TWh4VDg0bTRQJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnZm9vJyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIHsgbWVzc2FnZTogXCJmYWlsZWQgdG8gZGVjcnlwdCBwcnY6IGNjbTogdGFnIGRvZXNuJ3QgbWF0Y2hcIiB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUga2V5IGlzIGFsdGVyZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGFsdGVyZWRLZXkgPSBrZXkucmVwbGFjZSgvWzAtOV0vZywgJzAnKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhbHRlcmVkS2V5LFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAna0FtW0VGUTZvPVN4bGNMRkR3JSwnLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBqc29uIGRlY3J5cHQ6IGludmFsaWQgcGFyYW1ldGVycycgfVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnVFNTJywgKCkgPT4ge1xuICAgICAgY29uc3QgeyBrZXk6IGtleVN0cmluZywgY29tbW9uS2V5Y2hhaW4gfSA9IGV0aFRzc0JhY2t1cEtleTtcbiAgICAgIGNvbnN0IGtleSA9IGtleVN0cmluZy5yZXBsYWNlKC9cXHMvZywgJycpO1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdrQW1bRUZRNm89U3hsY0xGRHclLCc7XG4gICAgICBjb25zdCBtdWx0aVNpZ1R5cGUgPSAndHNzJztcblxuICAgICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICBwdWJsaWNLZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZSBjb21tb25LZXljaGFpbiBpcyBhbHRlcmVkJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBhbHRlcmVkQ29tbW9uS2V5Y2hhaW4gPSBnZW5lcmF0ZVJhbmRvbVBhc3N3b3JkKDEwKTtcbiAgICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgY29pbi5hc3NlcnRJc1ZhbGlkS2V5KHtcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXksXG4gICAgICAgICAgICAgIHB1YmxpY0tleTogYWx0ZXJlZENvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdJbnZhbGlkIGNvbW1vbiBrZXljaGFpbicgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIHdhbGxldFBhc3NwaHJhc2UgaXMgaW5jb3JyZWN0JywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbmNvcnJlY3RQYXNzcGhyYXNlID0gJ2Zvbyc7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjoga2V5LFxuICAgICAgICAgICAgICBwdWJsaWNLZXk6IGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBpbmNvcnJlY3RQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB7IG1lc3NhZ2U6IFwiZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBjY206IHRhZyBkb2Vzbid0IG1hdGNoXCIgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBhbHRlcmVkJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBhbHRlcmVkS2V5ID0ga2V5LnJlcGxhY2UoL1swLTldL2csICcwJyk7XG4gICAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogYWx0ZXJlZEtleSxcbiAgICAgICAgICAgICAgcHVibGljS2V5OiBjb21tb25LZXljaGFpbixcbiAgICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgeyBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBqc29uIGRlY3J5cHQ6IGludmFsaWQgcGFyYW1ldGVycycgfVxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=