@bitgo-beta/sdk-coin-trx 1.0.2-beta.232 → 1.0.2-beta.2321

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 (143) hide show
  1. package/dist/resources/protobuf/Contract.proto +32 -0
  2. package/dist/resources/protobuf/tron.d.ts +1478 -214
  3. package/dist/resources/protobuf/tron.js +6312 -2600
  4. package/dist/resources/protobuf/tron.proto +6 -0
  5. package/dist/src/index.js +6 -2
  6. package/dist/src/lib/accountCreateTxBuilder.d.ts +60 -0
  7. package/dist/src/lib/accountCreateTxBuilder.d.ts.map +1 -0
  8. package/dist/src/lib/accountCreateTxBuilder.js +191 -0
  9. package/dist/src/lib/constants.d.ts +4 -0
  10. package/dist/src/lib/constants.d.ts.map +1 -0
  11. package/dist/src/lib/constants.js +7 -0
  12. package/dist/src/lib/contractCallBuilder.d.ts +1 -35
  13. package/dist/src/lib/contractCallBuilder.d.ts.map +1 -1
  14. package/dist/src/lib/contractCallBuilder.js +13 -76
  15. package/dist/src/lib/delegateResourceTxBuilder.d.ts +27 -0
  16. package/dist/src/lib/delegateResourceTxBuilder.d.ts.map +1 -0
  17. package/dist/src/lib/delegateResourceTxBuilder.js +104 -0
  18. package/dist/src/lib/enum.d.ts +40 -1
  19. package/dist/src/lib/enum.d.ts.map +1 -1
  20. package/dist/src/lib/enum.js +44 -4
  21. package/dist/src/lib/freezeBalanceTxBuilder.d.ts +71 -0
  22. package/dist/src/lib/freezeBalanceTxBuilder.d.ts.map +1 -0
  23. package/dist/src/lib/freezeBalanceTxBuilder.js +217 -0
  24. package/dist/src/lib/iface.d.ts +248 -2
  25. package/dist/src/lib/iface.d.ts.map +1 -1
  26. package/dist/src/lib/iface.js +1 -1
  27. package/dist/src/lib/index.js +23 -9
  28. package/dist/src/lib/keyPair.d.ts +0 -1
  29. package/dist/src/lib/keyPair.d.ts.map +1 -1
  30. package/dist/src/lib/keyPair.js +31 -18
  31. package/dist/src/lib/resourceManagementTxBuilder.d.ts +72 -0
  32. package/dist/src/lib/resourceManagementTxBuilder.d.ts.map +1 -0
  33. package/dist/src/lib/resourceManagementTxBuilder.js +150 -0
  34. package/dist/src/lib/tokenTransferBuilder.d.ts +1 -1
  35. package/dist/src/lib/tokenTransferBuilder.d.ts.map +1 -1
  36. package/dist/src/lib/tokenTransferBuilder.js +5 -3
  37. package/dist/src/lib/transaction.d.ts +3 -0
  38. package/dist/src/lib/transaction.d.ts.map +1 -1
  39. package/dist/src/lib/transaction.js +115 -6
  40. package/dist/src/lib/transactionBuilder.d.ts +53 -6
  41. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  42. package/dist/src/lib/transactionBuilder.js +121 -22
  43. package/dist/src/lib/undelegateResourceTxBuilder.d.ts +27 -0
  44. package/dist/src/lib/undelegateResourceTxBuilder.d.ts.map +1 -0
  45. package/dist/src/lib/undelegateResourceTxBuilder.js +104 -0
  46. package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts +65 -0
  47. package/dist/src/lib/unfreezeBalanceTxBuilder.d.ts.map +1 -0
  48. package/dist/src/lib/unfreezeBalanceTxBuilder.js +210 -0
  49. package/dist/src/lib/utils.d.ts +115 -8
  50. package/dist/src/lib/utils.d.ts.map +1 -1
  51. package/dist/src/lib/utils.js +534 -55
  52. package/dist/src/lib/voteWitnessTxBuilder.d.ts +62 -0
  53. package/dist/src/lib/voteWitnessTxBuilder.d.ts.map +1 -0
  54. package/dist/src/lib/voteWitnessTxBuilder.js +219 -0
  55. package/dist/src/lib/withdrawBuilder.d.ts +49 -0
  56. package/dist/src/lib/withdrawBuilder.d.ts.map +1 -0
  57. package/dist/src/lib/withdrawBuilder.js +167 -0
  58. package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts +49 -0
  59. package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.d.ts.map +1 -0
  60. package/dist/src/lib/withdrawExpireUnfreezeTxBuilder.js +167 -0
  61. package/dist/src/lib/wrappedBuilder.d.ts +67 -1
  62. package/dist/src/lib/wrappedBuilder.d.ts.map +1 -1
  63. package/dist/src/lib/wrappedBuilder.js +114 -4
  64. package/dist/src/trx.d.ts +146 -8
  65. package/dist/src/trx.d.ts.map +1 -1
  66. package/dist/src/trx.js +705 -160
  67. package/dist/src/trxToken.d.ts +2 -2
  68. package/dist/src/trxToken.d.ts.map +1 -1
  69. package/dist/src/trxToken.js +22 -7
  70. package/dist/test/fixtures.d.ts +40 -0
  71. package/dist/test/fixtures.d.ts.map +1 -0
  72. package/dist/test/fixtures.js +46 -0
  73. package/dist/test/resources.d.ts +614 -0
  74. package/dist/test/resources.d.ts.map +1 -0
  75. package/dist/test/resources.js +782 -0
  76. package/dist/test/unit/index.d.ts +2 -0
  77. package/dist/test/unit/index.d.ts.map +1 -0
  78. package/dist/test/unit/index.js +19 -0
  79. package/dist/test/unit/keyPair.d.ts +2 -0
  80. package/dist/test/unit/keyPair.d.ts.map +1 -0
  81. package/dist/test/unit/keyPair.js +163 -0
  82. package/dist/test/unit/transaction.d.ts +2 -0
  83. package/dist/test/unit/transaction.d.ts.map +1 -0
  84. package/dist/test/unit/transaction.js +38 -0
  85. package/dist/test/unit/transactionBuilder/accountCreateTxBuilder.d.ts +2 -0
  86. package/dist/test/unit/transactionBuilder/accountCreateTxBuilder.d.ts.map +1 -0
  87. package/dist/test/unit/transactionBuilder/accountCreateTxBuilder.js +248 -0
  88. package/dist/test/unit/transactionBuilder/contractCallBuilder.d.ts +2 -0
  89. package/dist/test/unit/transactionBuilder/contractCallBuilder.d.ts.map +1 -0
  90. package/dist/test/unit/transactionBuilder/contractCallBuilder.js +315 -0
  91. package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.d.ts +2 -0
  92. package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.d.ts.map +1 -0
  93. package/dist/test/unit/transactionBuilder/delegateResourceTxBuilder.js +339 -0
  94. package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.d.ts +2 -0
  95. package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.d.ts.map +1 -0
  96. package/dist/test/unit/transactionBuilder/freezeBalanceTxBuilder.js +365 -0
  97. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts +2 -0
  98. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
  99. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +87 -0
  100. package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.d.ts +2 -0
  101. package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.d.ts.map +1 -0
  102. package/dist/test/unit/transactionBuilder/undelegateResourceTxBuilder.js +339 -0
  103. package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.d.ts +2 -0
  104. package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.d.ts.map +1 -0
  105. package/dist/test/unit/transactionBuilder/unfreezeBalanceTxBuilder.js +336 -0
  106. package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.d.ts +2 -0
  107. package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.d.ts.map +1 -0
  108. package/dist/test/unit/transactionBuilder/voteWitnessTxBuilder.js +277 -0
  109. package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.d.ts +2 -0
  110. package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.d.ts.map +1 -0
  111. package/dist/test/unit/transactionBuilder/withdrawBalanceBuilder.js +213 -0
  112. package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.d.ts +2 -0
  113. package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.d.ts.map +1 -0
  114. package/dist/test/unit/transactionBuilder/withdrawExpireUnfreezeTxBuilder.js +213 -0
  115. package/dist/test/unit/transactionBuilder/wrappedBuilder.d.ts +2 -0
  116. package/dist/test/unit/transactionBuilder/wrappedBuilder.d.ts.map +1 -0
  117. package/dist/test/unit/transactionBuilder/wrappedBuilder.js +68 -0
  118. package/dist/test/unit/transactionBuilder.d.ts +2 -0
  119. package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
  120. package/dist/test/unit/transactionBuilder.js +178 -0
  121. package/dist/test/unit/trx.d.ts +2 -0
  122. package/dist/test/unit/trx.d.ts.map +1 -0
  123. package/dist/test/unit/trx.js +843 -0
  124. package/dist/test/unit/trxToken.d.ts +2 -0
  125. package/dist/test/unit/trxToken.d.ts.map +1 -0
  126. package/dist/test/unit/trxToken.js +152 -0
  127. package/dist/test/unit/util.d.ts +2 -0
  128. package/dist/test/unit/util.d.ts.map +1 -0
  129. package/dist/test/unit/util.js +156 -0
  130. package/dist/test/unit/verifyTransaction.d.ts +2 -0
  131. package/dist/test/unit/verifyTransaction.d.ts.map +1 -0
  132. package/dist/test/unit/verifyTransaction.js +695 -0
  133. package/dist/tsconfig.tsbuildinfo +1 -0
  134. package/package.json +22 -16
  135. package/.eslintignore +0 -5
  136. package/.mocharc.yml +0 -8
  137. package/CHANGELOG.md +0 -118
  138. package/resources/README.md +0 -31
  139. package/resources/protobuf/Contract.proto +0 -256
  140. package/resources/protobuf/Discover.proto +0 -44
  141. package/resources/protobuf/tron.d.ts +0 -11205
  142. package/resources/protobuf/tron.js +0 -33480
  143. package/resources/protobuf/tron.proto +0 -677
@@ -0,0 +1,695 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const crypto_1 = require("crypto");
8
+ const node_test_1 = require("node:test");
9
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
10
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
11
+ const src_1 = require("../../src");
12
+ const lib_1 = require("../../src/lib");
13
+ const resources_1 = require("../resources");
14
+ (0, node_test_1.describe)('TRON Verify Transaction:', function () {
15
+ const bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'test' });
16
+ bitgo.initializeTestVars();
17
+ bitgo.safeRegister('trx', src_1.Trx.createInstance);
18
+ bitgo.safeRegister('ttrx', src_1.Ttrx.createInstance);
19
+ let basecoin;
20
+ (0, node_test_1.before)(function () {
21
+ basecoin = bitgo.coin('ttrx');
22
+ });
23
+ (0, node_test_1.describe)('Parameter Validation', () => {
24
+ (0, node_test_1.it)('should throw error when txParams is missing', async function () {
25
+ const params = {
26
+ txPrebuild: {
27
+ txHex: JSON.stringify({
28
+ ...resources_1.UnsignedBuildTransaction,
29
+ raw_data: {
30
+ ...resources_1.UnsignedBuildTransaction.raw_data,
31
+ expiration: Date.now() + 3600000,
32
+ timestamp: Date.now(),
33
+ },
34
+ }),
35
+ },
36
+ wallet: {},
37
+ };
38
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
39
+ message: 'missing txParams',
40
+ });
41
+ });
42
+ (0, node_test_1.it)('should throw error when wallet or txPrebuild is missing', async function () {
43
+ const params = {
44
+ txParams: {
45
+ recipients: [{ address: 'TQFxDSoXy2yXRE5HtKwAwrNRXGxYxkeSGk', amount: '1000000' }],
46
+ },
47
+ };
48
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
49
+ message: 'missing txPrebuild',
50
+ });
51
+ });
52
+ (0, node_test_1.it)('should throw error when txPrebuild.txHex is missing', async function () {
53
+ const params = {
54
+ txParams: {
55
+ recipients: [{ address: 'TQFxDSoXy2yXRE5HtKwAwrNRXGxYxkeSGk', amount: '1000000' }],
56
+ },
57
+ txPrebuild: {},
58
+ wallet: {},
59
+ };
60
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
61
+ message: 'missing txHex in txPrebuild',
62
+ });
63
+ });
64
+ });
65
+ (0, node_test_1.describe)('Contract Type Validation', () => {
66
+ (0, node_test_1.describe)('TransferContract', () => {
67
+ (0, node_test_1.it)('should validate valid TransferContract', async function () {
68
+ const timestamp = Date.now();
69
+ const transferContract = {
70
+ parameter: {
71
+ value: {
72
+ amount: 1000000,
73
+ owner_address: '4173a5993cd182ae152adad8203163f780c65a8aa5',
74
+ to_address: '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882',
75
+ },
76
+ type_url: 'type.googleapis.com/protocol.TransferContract',
77
+ },
78
+ type: 'TransferContract',
79
+ };
80
+ const rawData = {
81
+ contract: [transferContract],
82
+ ref_block_bytes: 'c8cf',
83
+ ref_block_hash: '89177fd84c5d9196',
84
+ expiration: timestamp + 3600000,
85
+ timestamp: timestamp,
86
+ fee_limit: 150000000,
87
+ };
88
+ // Transform rawData to match the expected parameter structure
89
+ const transformedRawData = {
90
+ contract: rawData.contract,
91
+ refBlockBytes: rawData.ref_block_bytes,
92
+ refBlockHash: rawData.ref_block_hash,
93
+ expiration: rawData.expiration,
94
+ timestamp: rawData.timestamp,
95
+ feeLimit: rawData.fee_limit,
96
+ };
97
+ // Generate raw_data_hex using the utility function
98
+ const rawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
99
+ // Calculate txID as SHA256 hash of raw_data_hex
100
+ const txID = (0, crypto_1.createHash)('sha256').update(Buffer.from(rawDataHex, 'hex')).digest('hex');
101
+ const params = {
102
+ txParams: {
103
+ recipients: [
104
+ {
105
+ address: lib_1.Utils.getBase58AddressFromHex('41d6cd6a2c0ff35a319e6abb5b9503ba0278679882'),
106
+ amount: '1000000',
107
+ },
108
+ ],
109
+ },
110
+ txPrebuild: {
111
+ txHex: JSON.stringify({
112
+ txID,
113
+ raw_data: rawData,
114
+ raw_data_hex: rawDataHex,
115
+ }),
116
+ },
117
+ wallet: {},
118
+ };
119
+ const result = await basecoin.verifyTransaction(params);
120
+ node_assert_1.default.strictEqual(result, true);
121
+ });
122
+ (0, node_test_1.it)('should validate TransferContract when recipient is 0x-prefixed hex (COINS-1575)', async function () {
123
+ const timestamp = Date.now();
124
+ const toAddressHex = '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882';
125
+ const transferContract = {
126
+ parameter: {
127
+ value: {
128
+ amount: 1000000,
129
+ owner_address: '4173a5993cd182ae152adad8203163f780c65a8aa5',
130
+ to_address: toAddressHex,
131
+ },
132
+ type_url: 'type.googleapis.com/protocol.TransferContract',
133
+ },
134
+ type: 'TransferContract',
135
+ };
136
+ const rawData = {
137
+ contract: [transferContract],
138
+ ref_block_bytes: 'c8cf',
139
+ ref_block_hash: '89177fd84c5d9196',
140
+ expiration: timestamp + 3600000,
141
+ timestamp: timestamp,
142
+ fee_limit: 150000000,
143
+ };
144
+ const transformedRawData = {
145
+ contract: rawData.contract,
146
+ refBlockBytes: rawData.ref_block_bytes,
147
+ refBlockHash: rawData.ref_block_hash,
148
+ expiration: rawData.expiration,
149
+ timestamp: rawData.timestamp,
150
+ feeLimit: rawData.fee_limit,
151
+ };
152
+ const rawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
153
+ const txID = (0, crypto_1.createHash)('sha256').update(Buffer.from(rawDataHex, 'hex')).digest('hex');
154
+ const params = {
155
+ txParams: {
156
+ recipients: [
157
+ {
158
+ address: '0x' + toAddressHex.slice(2),
159
+ amount: '1000000',
160
+ },
161
+ ],
162
+ },
163
+ txPrebuild: {
164
+ txHex: JSON.stringify({
165
+ txID,
166
+ raw_data: rawData,
167
+ raw_data_hex: rawDataHex,
168
+ }),
169
+ },
170
+ wallet: {},
171
+ };
172
+ const result = await basecoin.verifyTransaction(params);
173
+ node_assert_1.default.strictEqual(result, true);
174
+ });
175
+ (0, node_test_1.it)('should fail with missing owner address', async function () {
176
+ const timestamp = Date.now();
177
+ const txID = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
178
+ const transferContract = {
179
+ parameter: {
180
+ value: {
181
+ amount: 1000000,
182
+ to_address: '41c25420255c2c5a2dd54ef69f92ef261e6bd4216a',
183
+ },
184
+ type_url: 'type.googleapis.com/protocol.TransferContract',
185
+ },
186
+ type: 'TransferContract',
187
+ };
188
+ const rawData = {
189
+ txID,
190
+ contract: [transferContract],
191
+ ref_block_bytes: 'c8cf',
192
+ ref_block_hash: '89177fd84c5d9196',
193
+ expiration: timestamp + 3600000,
194
+ timestamp: timestamp,
195
+ fee_limit: 150000000,
196
+ };
197
+ const transformedRawData = {
198
+ contract: rawData.contract,
199
+ refBlockBytes: rawData.ref_block_bytes,
200
+ refBlockHash: rawData.ref_block_hash,
201
+ expiration: rawData.expiration,
202
+ timestamp: rawData.timestamp,
203
+ feeLimit: rawData.fee_limit,
204
+ };
205
+ const expectedRawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
206
+ const params = {
207
+ txParams: {
208
+ recipients: [{ address: 'TLWh67P93KgtnZNCtGnEHM1H33Nhq2uvvN', amount: '1000000' }],
209
+ },
210
+ txPrebuild: {
211
+ txHex: JSON.stringify({
212
+ txID,
213
+ raw_data: rawData,
214
+ raw_data_hex: expectedRawDataHex,
215
+ }),
216
+ },
217
+ wallet: {},
218
+ };
219
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
220
+ message: 'Transaction has not have a valid id',
221
+ });
222
+ });
223
+ (0, node_test_1.it)('should fail with missing destination address', async function () {
224
+ const timestamp = Date.now();
225
+ const txID = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
226
+ const transferContract = {
227
+ parameter: {
228
+ value: {
229
+ amount: 1000000,
230
+ owner_address: '4173a5993cd182ae152adad8203163f780c65a8aa5',
231
+ },
232
+ type_url: 'type.googleapis.com/protocol.TransferContract',
233
+ },
234
+ type: 'TransferContract',
235
+ };
236
+ const rawData = {
237
+ txID,
238
+ contract: [transferContract],
239
+ ref_block_bytes: 'c8cf',
240
+ ref_block_hash: '89177fd84c5d9196',
241
+ expiration: timestamp + 3600000,
242
+ timestamp: timestamp,
243
+ fee_limit: 150000000,
244
+ };
245
+ const transformedRawData = {
246
+ contract: rawData.contract,
247
+ refBlockBytes: rawData.ref_block_bytes,
248
+ refBlockHash: rawData.ref_block_hash,
249
+ expiration: rawData.expiration,
250
+ timestamp: rawData.timestamp,
251
+ feeLimit: rawData.fee_limit,
252
+ };
253
+ const expectedRawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
254
+ const params = {
255
+ txParams: {
256
+ recipients: [{ address: 'TLWh67P93KgtnZNCtGnEHM1H33Nhq2uvvN', amount: '1000000' }],
257
+ },
258
+ txPrebuild: {
259
+ txHex: JSON.stringify({
260
+ txID,
261
+ raw_data: rawData,
262
+ raw_data_hex: expectedRawDataHex,
263
+ }),
264
+ },
265
+ wallet: {},
266
+ };
267
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
268
+ message: 'Transaction has not have a valid id',
269
+ });
270
+ });
271
+ (0, node_test_1.it)('should fail with missing amount', async function () {
272
+ const timestamp = Date.now();
273
+ const transferContract = {
274
+ parameter: {
275
+ value: {
276
+ owner_address: '4173a5993cd182ae152adad8203163f780c65a8aa5',
277
+ to_address: '41c25420255c2c5a2dd54ef69f92ef261e6bd4216a',
278
+ },
279
+ type_url: 'type.googleapis.com/protocol.TransferContract',
280
+ },
281
+ type: 'TransferContract',
282
+ };
283
+ const rawData = {
284
+ contract: [transferContract],
285
+ ref_block_bytes: 'c8cf',
286
+ ref_block_hash: '89177fd84c5d9196',
287
+ expiration: timestamp + 3600000,
288
+ timestamp: timestamp,
289
+ fee_limit: 150000000,
290
+ };
291
+ const transformedRawData = {
292
+ contract: rawData.contract,
293
+ refBlockBytes: rawData.ref_block_bytes,
294
+ refBlockHash: rawData.ref_block_hash,
295
+ expiration: rawData.expiration,
296
+ timestamp: rawData.timestamp,
297
+ feeLimit: rawData.fee_limit,
298
+ };
299
+ const expectedRawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
300
+ const params = {
301
+ txParams: {
302
+ recipients: [{ address: 'TLWh67P93KgtnZNCtGnEHM1H33Nhq2uvvN', amount: '1000000' }],
303
+ },
304
+ txPrebuild: {
305
+ txHex: JSON.stringify({
306
+ raw_data: rawData,
307
+ raw_data_hex: expectedRawDataHex,
308
+ }),
309
+ },
310
+ wallet: {},
311
+ };
312
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
313
+ message: 'Amount does not exist in this transfer contract.',
314
+ });
315
+ });
316
+ (0, node_test_1.it)('should fail due to amount missmatch', async function () {
317
+ const timestamp = Date.now();
318
+ const transferContract = {
319
+ parameter: {
320
+ value: {
321
+ amount: 2000000,
322
+ owner_address: '4173a5993cd182ae152adad8203163f780c65a8aa5',
323
+ to_address: '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882',
324
+ },
325
+ type_url: 'type.googleapis.com/protocol.TransferContract',
326
+ },
327
+ type: 'TransferContract',
328
+ };
329
+ const rawData = {
330
+ contract: [transferContract],
331
+ ref_block_bytes: 'c8cf',
332
+ ref_block_hash: '89177fd84c5d9196',
333
+ expiration: timestamp + 3600000,
334
+ timestamp: timestamp,
335
+ fee_limit: 150000000,
336
+ };
337
+ // Transform rawData to match the expected parameter structure
338
+ const transformedRawData = {
339
+ contract: rawData.contract,
340
+ refBlockBytes: rawData.ref_block_bytes,
341
+ refBlockHash: rawData.ref_block_hash,
342
+ expiration: rawData.expiration,
343
+ timestamp: rawData.timestamp,
344
+ feeLimit: rawData.fee_limit,
345
+ };
346
+ // Generate raw_data_hex using the utility function
347
+ const rawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
348
+ // Calculate txID as SHA256 hash of raw_data_hex
349
+ const txID = (0, crypto_1.createHash)('sha256').update(Buffer.from(rawDataHex, 'hex')).digest('hex');
350
+ const params = {
351
+ txParams: {
352
+ recipients: [
353
+ {
354
+ address: '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882',
355
+ amount: '1000000',
356
+ },
357
+ ],
358
+ },
359
+ txPrebuild: {
360
+ txHex: JSON.stringify({
361
+ txID,
362
+ raw_data: rawData,
363
+ raw_data_hex: rawDataHex,
364
+ }),
365
+ },
366
+ wallet: {},
367
+ };
368
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
369
+ message: 'transaction amount in txPrebuild does not match the value given by client',
370
+ });
371
+ });
372
+ (0, node_test_1.it)('should fail due to destination address missmatch', async function () {
373
+ const timestamp = Date.now();
374
+ const transferContract = {
375
+ parameter: {
376
+ value: {
377
+ amount: 1000000,
378
+ owner_address: '4173a5993cd182ae152adad8203163f780c65a8aa5',
379
+ to_address: '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882',
380
+ },
381
+ type_url: 'type.googleapis.com/protocol.TransferContract',
382
+ },
383
+ type: 'TransferContract',
384
+ };
385
+ const rawData = {
386
+ contract: [transferContract],
387
+ ref_block_bytes: 'c8cf',
388
+ ref_block_hash: '89177fd84c5d9196',
389
+ expiration: timestamp + 3600000,
390
+ timestamp: timestamp,
391
+ fee_limit: 150000000,
392
+ };
393
+ // Transform rawData to match the expected parameter structure
394
+ const transformedRawData = {
395
+ contract: rawData.contract,
396
+ refBlockBytes: rawData.ref_block_bytes,
397
+ refBlockHash: rawData.ref_block_hash,
398
+ expiration: rawData.expiration,
399
+ timestamp: rawData.timestamp,
400
+ feeLimit: rawData.fee_limit,
401
+ };
402
+ // Generate raw_data_hex using the utility function
403
+ const rawDataHex = lib_1.Utils.generateRawDataHex(transformedRawData);
404
+ // Calculate txID as SHA256 hash of raw_data_hex
405
+ const txID = (0, crypto_1.createHash)('sha256').update(Buffer.from(rawDataHex, 'hex')).digest('hex');
406
+ const params = {
407
+ txParams: {
408
+ recipients: [
409
+ {
410
+ address: '41d6cd6a2c0ff35a319e6abb5b9503ba0278679883',
411
+ amount: '1000000',
412
+ },
413
+ ],
414
+ },
415
+ txPrebuild: {
416
+ txHex: JSON.stringify({
417
+ txID,
418
+ raw_data: rawData,
419
+ raw_data_hex: rawDataHex,
420
+ }),
421
+ },
422
+ wallet: {},
423
+ };
424
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
425
+ message: 'destination address does not match with the recipient address',
426
+ });
427
+ });
428
+ });
429
+ });
430
+ (0, node_test_1.describe)('TSS Wallet Verification', () => {
431
+ /**
432
+ * Helper to build a raw_data_hex (protobuf) for a TransferContract.
433
+ * For TSS, txPrebuild.txHex is the raw_data_hex directly (not a JSON string).
434
+ */
435
+ function buildTssTransferTxHex(params) {
436
+ const timestamp = params.timestamp || Date.now();
437
+ const transferContract = {
438
+ parameter: {
439
+ value: {
440
+ amount: params.amount,
441
+ owner_address: params.ownerAddress,
442
+ to_address: params.toAddress,
443
+ },
444
+ type_url: 'type.googleapis.com/protocol.TransferContract',
445
+ },
446
+ type: 'TransferContract',
447
+ };
448
+ const transformedRawData = {
449
+ contract: [transferContract],
450
+ refBlockBytes: 'c8cf',
451
+ refBlockHash: '89177fd84c5d9196',
452
+ expiration: params.expiration || timestamp + 3600000,
453
+ timestamp: timestamp,
454
+ };
455
+ return lib_1.Utils.generateRawDataHex(transformedRawData);
456
+ }
457
+ (0, node_test_1.describe)('TransferContract', () => {
458
+ (0, node_test_1.it)('should validate a valid TSS TransferContract', async function () {
459
+ const ownerHex = '4173a5993cd182ae152adad8203163f780c65a8aa5';
460
+ const toHex = '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882';
461
+ const amount = 1000000;
462
+ const rawDataHex = buildTssTransferTxHex({ ownerAddress: ownerHex, toAddress: toHex, amount });
463
+ const params = {
464
+ txParams: {
465
+ recipients: [
466
+ {
467
+ // TSS path: recipients use base58 addresses
468
+ address: lib_1.Utils.getBase58AddressFromHex(toHex),
469
+ amount: amount.toString(),
470
+ },
471
+ ],
472
+ },
473
+ txPrebuild: {
474
+ // TSS path: txHex is the raw protobuf hex, not a JSON string
475
+ txHex: rawDataHex,
476
+ },
477
+ wallet: {},
478
+ walletType: 'tss',
479
+ };
480
+ const result = await basecoin.verifyTransaction(params);
481
+ node_assert_1.default.strictEqual(result, true);
482
+ });
483
+ (0, node_test_1.it)('should fail TSS verification when amount does not match', async function () {
484
+ const ownerHex = '4173a5993cd182ae152adad8203163f780c65a8aa5';
485
+ const toHex = '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882';
486
+ const rawDataHex = buildTssTransferTxHex({ ownerAddress: ownerHex, toAddress: toHex, amount: 2000000 });
487
+ const params = {
488
+ txParams: {
489
+ recipients: [
490
+ {
491
+ address: lib_1.Utils.getBase58AddressFromHex(toHex),
492
+ amount: '1000000', // mismatch: txHex has 2000000
493
+ },
494
+ ],
495
+ },
496
+ txPrebuild: {
497
+ txHex: rawDataHex,
498
+ },
499
+ wallet: {},
500
+ walletType: 'tss',
501
+ };
502
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
503
+ message: 'transaction amount in txPrebuild does not match the value given by client',
504
+ });
505
+ });
506
+ (0, node_test_1.it)('should fail TSS verification when destination address does not match', async function () {
507
+ const ownerHex = '4173a5993cd182ae152adad8203163f780c65a8aa5';
508
+ const toHex = '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882';
509
+ const rawDataHex = buildTssTransferTxHex({ ownerAddress: ownerHex, toAddress: toHex, amount: 1000000 });
510
+ const params = {
511
+ txParams: {
512
+ recipients: [
513
+ {
514
+ // Different address than what's in the transaction
515
+ address: 'TTsGwnTLQ4eryFJpDvJSfuGQxPXRCjXvZz',
516
+ amount: '1000000',
517
+ },
518
+ ],
519
+ },
520
+ txPrebuild: {
521
+ txHex: rawDataHex,
522
+ },
523
+ wallet: {},
524
+ walletType: 'tss',
525
+ };
526
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
527
+ message: 'destination address does not match with the recipient address',
528
+ });
529
+ });
530
+ });
531
+ (0, node_test_1.it)('should return true for non-Transfer, non-TriggerSmartContract types in TSS', async function () {
532
+ // AccountPermissionUpdate and other native TRX contracts (freeze, vote, etc.) pass through
533
+ // without recipient validation in the TSS path.
534
+ const rawDataHex = resources_1.UnsignedAccountPermissionUpdateContractTx.raw_data_hex;
535
+ const params = {
536
+ txParams: {
537
+ recipients: [],
538
+ },
539
+ txPrebuild: {
540
+ txHex: rawDataHex,
541
+ },
542
+ wallet: {},
543
+ walletType: 'tss',
544
+ };
545
+ const result = await basecoin.verifyTransaction(params);
546
+ node_assert_1.default.strictEqual(result, true);
547
+ });
548
+ (0, node_test_1.describe)('TriggerSmartContract (TRC20) routed through native Trx', () => {
549
+ // CECHO-2248: token wallets are sometimes constructed with the native coin instance
550
+ // (e.g. bitgo.coin('trx').wallets().get() on a trx:<token> wallet), so a TRC20
551
+ // TriggerSmartContract prebuild can reach the native Trx verifier. It must validate
552
+ // recipient and amount (same as TrxToken.verifyTransaction) instead of throwing.
553
+ const trc20RawDataHex = '0a02578b22086113bb9ac351432b4088eae7a6de305aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541c51fbeea78910b15b1d3e8a9b62914ca94d1a4ac12154142a1e39aefa49290f2b3f9ed688d7cecf86cd6e02244a9059cbb0000000000000000000000008483618ca85c35a9b923d98bebca718f5a1db2790000000000000000000000000000000000000000000000000000000005f5e10070888d8ca5de309001c0c39307';
554
+ // Recipient address decoded from the ABI data in the protobuf above (41 prefix → base58)
555
+ const trc20RecipientHex = '418483618ca85c35a9b923d98bebca718f5a1db279';
556
+ const trc20RecipientBase58 = lib_1.Utils.getBase58AddressFromHex(trc20RecipientHex);
557
+ const trc20Amount = '100000000';
558
+ (0, node_test_1.it)('should validate a matching TRC20 transfer instead of throwing', async function () {
559
+ const params = {
560
+ txParams: {
561
+ recipients: [{ address: trc20RecipientBase58, amount: trc20Amount }],
562
+ },
563
+ txPrebuild: {
564
+ txHex: trc20RawDataHex,
565
+ },
566
+ wallet: {},
567
+ walletType: 'tss',
568
+ };
569
+ const result = await basecoin.verifyTransaction(params);
570
+ node_assert_1.default.strictEqual(result, true);
571
+ });
572
+ (0, node_test_1.it)('should fail when TRC20 amount does not match', async function () {
573
+ const params = {
574
+ txParams: {
575
+ recipients: [{ address: trc20RecipientBase58, amount: '999' }],
576
+ },
577
+ txPrebuild: {
578
+ txHex: trc20RawDataHex,
579
+ },
580
+ wallet: {},
581
+ walletType: 'tss',
582
+ };
583
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
584
+ message: 'transaction amount in txPrebuild does not match the value given by client',
585
+ });
586
+ });
587
+ (0, node_test_1.it)('should fail when TRC20 destination does not match', async function () {
588
+ const params = {
589
+ txParams: {
590
+ recipients: [{ address: 'TLWh67P93KgtnZNCtGnEHM1H33Nhq2uvvN', amount: trc20Amount }],
591
+ },
592
+ txPrebuild: {
593
+ txHex: trc20RawDataHex,
594
+ },
595
+ wallet: {},
596
+ walletType: 'tss',
597
+ };
598
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
599
+ message: 'destination address does not match with the recipient address',
600
+ });
601
+ });
602
+ (0, node_test_1.it)('should return true when no recipients are provided (consolidation path)', async function () {
603
+ const params = {
604
+ txParams: {
605
+ recipients: [],
606
+ },
607
+ txPrebuild: {
608
+ txHex: trc20RawDataHex,
609
+ },
610
+ wallet: {},
611
+ walletType: 'tss',
612
+ };
613
+ const result = await basecoin.verifyTransaction(params);
614
+ node_assert_1.default.strictEqual(result, true);
615
+ });
616
+ });
617
+ (0, node_test_1.it)('should throw error when txHex is missing for TSS wallet', async function () {
618
+ const params = {
619
+ txParams: {
620
+ recipients: [{ address: 'TQFxDSoXy2yXRE5HtKwAwrNRXGxYxkeSGk', amount: '1000000' }],
621
+ },
622
+ txPrebuild: {},
623
+ wallet: {},
624
+ walletType: 'tss',
625
+ };
626
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
627
+ message: 'missing txHex in txPrebuild',
628
+ });
629
+ });
630
+ (0, node_test_1.describe)('serializedTxHex (JSON string) path', () => {
631
+ // prebuildAndSignTransaction passes txHex as serializedTxHex — a full JSON string
632
+ // containing { txID, raw_data, raw_data_hex }. The TSS branch must handle this format
633
+ // by extracting raw_data_hex before protobuf decoding.
634
+ (0, node_test_1.it)('should validate TSS TransferContract when txHex is a JSON string (serializedTxHex)', async function () {
635
+ const ownerHex = '4173a5993cd182ae152adad8203163f780c65a8aa5';
636
+ const toHex = '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882';
637
+ const amount = 1000000;
638
+ const rawDataHex = buildTssTransferTxHex({ ownerAddress: ownerHex, toAddress: toHex, amount });
639
+ const txID = (0, crypto_1.createHash)('sha256').update(Buffer.from(rawDataHex, 'hex')).digest('hex');
640
+ // Simulate the serializedTxHex format from BitGo API (JSON string with txID + raw_data_hex)
641
+ const serializedTxHex = JSON.stringify({
642
+ txID,
643
+ raw_data_hex: rawDataHex,
644
+ raw_data: {},
645
+ });
646
+ const params = {
647
+ txParams: {
648
+ recipients: [
649
+ {
650
+ address: lib_1.Utils.getBase58AddressFromHex(toHex),
651
+ amount: amount.toString(),
652
+ },
653
+ ],
654
+ },
655
+ txPrebuild: {
656
+ txHex: serializedTxHex,
657
+ },
658
+ wallet: {},
659
+ walletType: 'tss',
660
+ };
661
+ const result = await basecoin.verifyTransaction(params);
662
+ node_assert_1.default.strictEqual(result, true);
663
+ });
664
+ (0, node_test_1.it)('should fail when amount mismatches with JSON txHex', async function () {
665
+ const ownerHex = '4173a5993cd182ae152adad8203163f780c65a8aa5';
666
+ const toHex = '41d6cd6a2c0ff35a319e6abb5b9503ba0278679882';
667
+ const rawDataHex = buildTssTransferTxHex({ ownerAddress: ownerHex, toAddress: toHex, amount: 2000000 });
668
+ const serializedTxHex = JSON.stringify({
669
+ txID: (0, crypto_1.createHash)('sha256').update(Buffer.from(rawDataHex, 'hex')).digest('hex'),
670
+ raw_data_hex: rawDataHex,
671
+ raw_data: {},
672
+ });
673
+ const params = {
674
+ txParams: {
675
+ recipients: [
676
+ {
677
+ address: lib_1.Utils.getBase58AddressFromHex(toHex),
678
+ amount: '1000000', // mismatch
679
+ },
680
+ ],
681
+ },
682
+ txPrebuild: {
683
+ txHex: serializedTxHex,
684
+ },
685
+ wallet: {},
686
+ walletType: 'tss',
687
+ };
688
+ await node_assert_1.default.rejects(basecoin.verifyTransaction(params), {
689
+ message: 'transaction amount in txPrebuild does not match the value given by client',
690
+ });
691
+ });
692
+ });
693
+ });
694
+ });
695
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyaWZ5VHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdmVyaWZ5VHJhbnNhY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4REFBaUM7QUFDakMsbUNBQW9DO0FBQ3BDLHlDQUFpRDtBQUNqRCxpREFBK0M7QUFDL0MsbURBQStEO0FBQy9ELG1DQUFzQztBQUN0Qyx1Q0FBc0M7QUFDdEMsNENBQW1HO0FBRW5HLElBQUEsb0JBQVEsRUFBQywwQkFBMEIsRUFBRTtJQUNuQyxNQUFNLEtBQUssR0FBaUIsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzFFLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzNCLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFNBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUM5QyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxVQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7SUFFaEQsSUFBSSxRQUFRLENBQUM7SUFFYixJQUFBLGtCQUFNLEVBQUM7UUFDTCxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUMsQ0FBQztJQUVILElBQUEsb0JBQVEsRUFBQyxzQkFBc0IsRUFBRSxHQUFHLEVBQUU7UUFDcEMsSUFBQSxjQUFFLEVBQUMsNkNBQTZDLEVBQUUsS0FBSztZQUNyRCxNQUFNLE1BQU0sR0FBRztnQkFDYixVQUFVLEVBQUU7b0JBQ1YsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7d0JBQ3BCLEdBQUcsb0NBQXdCO3dCQUMzQixRQUFRLEVBQUU7NEJBQ1IsR0FBRyxvQ0FBd0IsQ0FBQyxRQUFROzRCQUNwQyxVQUFVLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLE9BQU87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TyxFQUFFLENBQUMsQ0FBQztnQkFDeEcsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztvQkFDckMsSUFBSSxFQUFFLElBQUEsbUJBQVUsRUFBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO29CQUMvRSxZQUFZLEVBQUUsVUFBVTtvQkFDeEIsUUFBUSxFQUFFLEVBQUU7aUJBQ2IsQ0FBQyxDQUFDO2dCQUVILE1BQU0sTUFBTSxHQUFHO29CQUNiLFFBQVEsRUFBRTt3QkFDUixVQUFVLEVBQUU7NEJBQ1Y7Z0NBQ0UsT0FBTyxFQUFFLFdBQUssQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUM7Z0NBQzdDLE1BQU0sRUFBRSxTQUFTLEVBQUUsV0FBVzs2QkFDL0I7eUJBQ0Y7cUJBQ0Y7b0JBQ0QsVUFBVSxFQUFFO3dCQUNWLEtBQUssRUFBRSxlQUFlO3FCQUN2QjtvQkFDRCxNQUFNLEVBQUUsRUFBRTtvQkFDVixVQUFVLEVBQUUsS0FBSztpQkFDbEIsQ0FBQztnQkFFRixNQUFNLHFCQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsRUFBRTtvQkFDdkQsT0FBTyxFQUFFLDJFQUEyRTtpQkFDckYsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ25vZGU6YXNzZXJ0JztcbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgZGVzY3JpYmUsIGl0LCBiZWZvcmUgfSBmcm9tICdub2RlOnRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7IFRlc3RCaXRHb0FQSSwgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgVHJ4LCBUdHJ4IH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi4vLi4vc3JjL2xpYic7XG5pbXBvcnQgeyBVbnNpZ25lZEJ1aWxkVHJhbnNhY3Rpb24sIFVuc2lnbmVkQWNjb3VudFBlcm1pc3Npb25VcGRhdGVDb250cmFjdFR4IH0gZnJvbSAnLi4vcmVzb3VyY2VzJztcblxuZGVzY3JpYmUoJ1RST04gVmVyaWZ5IFRyYW5zYWN0aW9uOicsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgYml0Z286IFRlc3RCaXRHb0FQSSA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gIGJpdGdvLnNhZmVSZWdpc3RlcigndHJ4JywgVHJ4LmNyZWF0ZUluc3RhbmNlKTtcbiAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0dHJ4JywgVHRyeC5jcmVhdGVJbnN0YW5jZSk7XG5cbiAgbGV0IGJhc2Vjb2luO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0dHJ4Jyk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdQYXJhbWV0ZXIgVmFsaWRhdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gdHhQYXJhbXMgaXMgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAuLi5VbnNpZ25lZEJ1aWxkVHJhbnNhY3Rpb24sXG4gICAgICAgICAgICByYXdfZGF0YToge1xuICAgICAgICAgICAgICAuLi5VbnNpZ25lZEJ1aWxkVHJhbnNhY3Rpb24ucmF3X2RhdGEsXG4gICAgICAgICAgICAgIGV4cGlyYXRpb246IERhdGUubm93KCkgKyAzNjAwMDAwLFxuICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICB9LFxuICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICBtZXNzYWdlOiAnbWlzc2luZyB0eFBhcmFtcycsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiB3YWxsZXQgb3IgdHhQcmVidWlsZCBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6ICdUUUZ4RFNvWHkyeVhSRTVIdEt3QXdyTlJYR3hZeGtlU0drJywgYW1vdW50OiAnMTAwMDAwMCcgfV0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXMpLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdtaXNzaW5nIHR4UHJlYnVpbGQnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gdHhQcmVidWlsZC50eEhleCBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6ICdUUUZ4RFNvWHkyeVhSRTVIdEt3QXdyTlJYR3hZeGtlU0drJywgYW1vdW50OiAnMTAwMDAwMCcgfV0sXG4gICAgICAgIH0sXG4gICAgICAgIHR4UHJlYnVpbGQ6IHt9LFxuICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICBtZXNzYWdlOiAnbWlzc2luZyB0eEhleCBpbiB0eFByZWJ1aWxkJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ29udHJhY3QgVHlwZSBWYWxpZGF0aW9uJywgKCkgPT4ge1xuICAgIGRlc2NyaWJlKCdUcmFuc2ZlckNvbnRyYWN0JywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSB2YWxpZCBUcmFuc2ZlckNvbnRyYWN0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgICAgICBjb25zdCB0cmFuc2ZlckNvbnRyYWN0ID0ge1xuICAgICAgICAgIHBhcmFtZXRlcjoge1xuICAgICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgICAgYW1vdW50OiAxMDAwMDAwLFxuICAgICAgICAgICAgICBvd25lcl9hZGRyZXNzOiAnNDE3M2E1OTkzY2QxODJhZTE1MmFkYWQ4MjAzMTYzZjc4MGM2NWE4YWE1JyxcbiAgICAgICAgICAgICAgdG9fYWRkcmVzczogJzQxZDZjZDZhMmMwZmYzNWEzMTllNmFiYjViOTUwM2JhMDI3ODY3OTg4MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHlwZV91cmw6ICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJhd0RhdGEgPSB7XG4gICAgICAgICAgY29udHJhY3Q6IFt0cmFuc2ZlckNvbnRyYWN0XSxcbiAgICAgICAgICByZWZfYmxvY2tfYnl0ZXM6ICdjOGNmJyxcbiAgICAgICAgICByZWZfYmxvY2tfaGFzaDogJzg5MTc3ZmQ4NGM1ZDkxOTYnLFxuICAgICAgICAgIGV4cGlyYXRpb246IHRpbWVzdGFtcCArIDM2MDAwMDAsXG4gICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsXG4gICAgICAgICAgZmVlX2xpbWl0OiAxNTAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gVHJhbnNmb3JtIHJhd0RhdGEgdG8gbWF0Y2ggdGhlIGV4cGVjdGVkIHBhcmFtZXRlciBzdHJ1Y3R1cmVcbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRSYXdEYXRhID0ge1xuICAgICAgICAgIGNvbnRyYWN0OiByYXdEYXRhLmNvbnRyYWN0IGFzIGFueSxcbiAgICAgICAgICByZWZCbG9ja0J5dGVzOiByYXdEYXRhLnJlZl9ibG9ja19ieXRlcyxcbiAgICAgICAgICByZWZCbG9ja0hhc2g6IHJhd0RhdGEucmVmX2Jsb2NrX2hhc2gsXG4gICAgICAgICAgZXhwaXJhdGlvbjogcmF3RGF0YS5leHBpcmF0aW9uLFxuICAgICAgICAgIHRpbWVzdGFtcDogcmF3RGF0YS50aW1lc3RhbXAsXG4gICAgICAgICAgZmVlTGltaXQ6IHJhd0RhdGEuZmVlX2xpbWl0LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEdlbmVyYXRlIHJhd19kYXRhX2hleCB1c2luZyB0aGUgdXRpbGl0eSBmdW5jdGlvblxuICAgICAgICBjb25zdCByYXdEYXRhSGV4ID0gVXRpbHMuZ2VuZXJhdGVSYXdEYXRhSGV4KHRyYW5zZm9ybWVkUmF3RGF0YSk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHR4SUQgYXMgU0hBMjU2IGhhc2ggb2YgcmF3X2RhdGFfaGV4XG4gICAgICAgIGNvbnN0IHR4SUQgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoQnVmZmVyLmZyb20ocmF3RGF0YUhleCwgJ2hleCcpKS5kaWdlc3QoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWRkcmVzczogVXRpbHMuZ2V0QmFzZTU4QWRkcmVzc0Zyb21IZXgoJzQxZDZjZDZhMmMwZmYzNWEzMTllNmFiYjViOTUwM2JhMDI3ODY3OTg4MicpLFxuICAgICAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgIHR4SUQsXG4gICAgICAgICAgICAgIHJhd19kYXRhOiByYXdEYXRhLFxuICAgICAgICAgICAgICByYXdfZGF0YV9oZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBUcmFuc2ZlckNvbnRyYWN0IHdoZW4gcmVjaXBpZW50IGlzIDB4LXByZWZpeGVkIGhleCAoQ09JTlMtMTU3NSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHRvQWRkcmVzc0hleCA9ICc0MWQ2Y2Q2YTJjMGZmMzVhMzE5ZTZhYmI1Yjk1MDNiYTAyNzg2Nzk4ODInO1xuICAgICAgICBjb25zdCB0cmFuc2ZlckNvbnRyYWN0ID0ge1xuICAgICAgICAgIHBhcmFtZXRlcjoge1xuICAgICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgICAgYW1vdW50OiAxMDAwMDAwLFxuICAgICAgICAgICAgICBvd25lcl9hZGRyZXNzOiAnNDE3M2E1OTkzY2QxODJhZTE1MmFkYWQ4MjAzMTYzZjc4MGM2NWE4YWE1JyxcbiAgICAgICAgICAgICAgdG9fYWRkcmVzczogdG9BZGRyZXNzSGV4LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGVfdXJsOiAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5UcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGU6ICdUcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByYXdEYXRhID0ge1xuICAgICAgICAgIGNvbnRyYWN0OiBbdHJhbnNmZXJDb250cmFjdF0sXG4gICAgICAgICAgcmVmX2Jsb2NrX2J5dGVzOiAnYzhjZicsXG4gICAgICAgICAgcmVmX2Jsb2NrX2hhc2g6ICc4OTE3N2ZkODRjNWQ5MTk2JyxcbiAgICAgICAgICBleHBpcmF0aW9uOiB0aW1lc3RhbXAgKyAzNjAwMDAwLFxuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIGZlZV9saW1pdDogMTUwMDAwMDAwLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkUmF3RGF0YSA9IHtcbiAgICAgICAgICBjb250cmFjdDogcmF3RGF0YS5jb250cmFjdCBhcyBhbnksXG4gICAgICAgICAgcmVmQmxvY2tCeXRlczogcmF3RGF0YS5yZWZfYmxvY2tfYnl0ZXMsXG4gICAgICAgICAgcmVmQmxvY2tIYXNoOiByYXdEYXRhLnJlZl9ibG9ja19oYXNoLFxuICAgICAgICAgIGV4cGlyYXRpb246IHJhd0RhdGEuZXhwaXJhdGlvbixcbiAgICAgICAgICB0aW1lc3RhbXA6IHJhd0RhdGEudGltZXN0YW1wLFxuICAgICAgICAgIGZlZUxpbWl0OiByYXdEYXRhLmZlZV9saW1pdCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByYXdEYXRhSGV4ID0gVXRpbHMuZ2VuZXJhdGVSYXdEYXRhSGV4KHRyYW5zZm9ybWVkUmF3RGF0YSk7XG4gICAgICAgIGNvbnN0IHR4SUQgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoQnVmZmVyLmZyb20ocmF3RGF0YUhleCwgJ2hleCcpKS5kaWdlc3QoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWRkcmVzczogJzB4JyArIHRvQWRkcmVzc0hleC5zbGljZSgyKSxcbiAgICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgICB0eElELFxuICAgICAgICAgICAgICByYXdfZGF0YTogcmF3RGF0YSxcbiAgICAgICAgICAgICAgcmF3X2RhdGFfaGV4OiByYXdEYXRhSGV4LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB3aXRoIG1pc3Npbmcgb3duZXIgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgdHhJRCA9ICcwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmJztcbiAgICAgICAgY29uc3QgdHJhbnNmZXJDb250cmFjdCA9IHtcbiAgICAgICAgICBwYXJhbWV0ZXI6IHtcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgIGFtb3VudDogMTAwMDAwMCxcbiAgICAgICAgICAgICAgdG9fYWRkcmVzczogJzQxYzI1NDIwMjU1YzJjNWEyZGQ1NGVmNjlmOTJlZjI2MWU2YmQ0MjE2YScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHlwZV91cmw6ICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJhd0RhdGEgPSB7XG4gICAgICAgICAgdHhJRCxcbiAgICAgICAgICBjb250cmFjdDogW3RyYW5zZmVyQ29udHJhY3RdLFxuICAgICAgICAgIHJlZl9ibG9ja19ieXRlczogJ2M4Y2YnLFxuICAgICAgICAgIHJlZl9ibG9ja19oYXNoOiAnODkxNzdmZDg0YzVkOTE5NicsXG4gICAgICAgICAgZXhwaXJhdGlvbjogdGltZXN0YW1wICsgMzYwMDAwMCxcbiAgICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcCxcbiAgICAgICAgICBmZWVfbGltaXQ6IDE1MDAwMDAwMCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZFJhd0RhdGEgPSB7XG4gICAgICAgICAgY29udHJhY3Q6IHJhd0RhdGEuY29udHJhY3QgYXMgYW55LFxuICAgICAgICAgIHJlZkJsb2NrQnl0ZXM6IHJhd0RhdGEucmVmX2Jsb2NrX2J5dGVzLFxuICAgICAgICAgIHJlZkJsb2NrSGFzaDogcmF3RGF0YS5yZWZfYmxvY2tfaGFzaCxcbiAgICAgICAgICBleHBpcmF0aW9uOiByYXdEYXRhLmV4cGlyYXRpb24sXG4gICAgICAgICAgdGltZXN0YW1wOiByYXdEYXRhLnRpbWVzdGFtcCxcbiAgICAgICAgICBmZWVMaW1pdDogcmF3RGF0YS5mZWVfbGltaXQsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZXhwZWN0ZWRSYXdEYXRhSGV4ID0gVXRpbHMuZ2VuZXJhdGVSYXdEYXRhSGV4KHRyYW5zZm9ybWVkUmF3RGF0YSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzOiBbeyBhZGRyZXNzOiAnVExXaDY3UDkzS2d0blpOQ3RHbkVITTFIMzNOaHEydXZ2TicsIGFtb3VudDogJzEwMDAwMDAnIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgdHhJRCxcbiAgICAgICAgICAgICAgcmF3X2RhdGE6IHJhd0RhdGEsXG4gICAgICAgICAgICAgIHJhd19kYXRhX2hleDogZXhwZWN0ZWRSYXdEYXRhSGV4LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtcyksIHtcbiAgICAgICAgICBtZXNzYWdlOiAnVHJhbnNhY3Rpb24gaGFzIG5vdCBoYXZlIGEgdmFsaWQgaWQnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgd2l0aCBtaXNzaW5nIGRlc3RpbmF0aW9uIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHR4SUQgPSAnMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZic7XG4gICAgICAgIGNvbnN0IHRyYW5zZmVyQ29udHJhY3QgPSB7XG4gICAgICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICBhbW91bnQ6IDEwMDAwMDAsXG4gICAgICAgICAgICAgIG93bmVyX2FkZHJlc3M6ICc0MTczYTU5OTNjZDE4MmFlMTUyYWRhZDgyMDMxNjNmNzgwYzY1YThhYTUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGVfdXJsOiAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5UcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGU6ICdUcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByYXdEYXRhID0ge1xuICAgICAgICAgIHR4SUQsXG4gICAgICAgICAgY29udHJhY3Q6IFt0cmFuc2ZlckNvbnRyYWN0XSxcbiAgICAgICAgICByZWZfYmxvY2tfYnl0ZXM6ICdjOGNmJyxcbiAgICAgICAgICByZWZfYmxvY2tfaGFzaDogJzg5MTc3ZmQ4NGM1ZDkxOTYnLFxuICAgICAgICAgIGV4cGlyYXRpb246IHRpbWVzdGFtcCArIDM2MDAwMDAsXG4gICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsXG4gICAgICAgICAgZmVlX2xpbWl0OiAxNTAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRSYXdEYXRhID0ge1xuICAgICAgICAgIGNvbnRyYWN0OiByYXdEYXRhLmNvbnRyYWN0IGFzIGFueSxcbiAgICAgICAgICByZWZCbG9ja0J5dGVzOiByYXdEYXRhLnJlZl9ibG9ja19ieXRlcyxcbiAgICAgICAgICByZWZCbG9ja0hhc2g6IHJhd0RhdGEucmVmX2Jsb2NrX2hhc2gsXG4gICAgICAgICAgZXhwaXJhdGlvbjogcmF3RGF0YS5leHBpcmF0aW9uLFxuICAgICAgICAgIHRpbWVzdGFtcDogcmF3RGF0YS50aW1lc3RhbXAsXG4gICAgICAgICAgZmVlTGltaXQ6IHJhd0RhdGEuZmVlX2xpbWl0LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGV4cGVjdGVkUmF3RGF0YUhleCA9IFV0aWxzLmdlbmVyYXRlUmF3RGF0YUhleCh0cmFuc2Zvcm1lZFJhd0RhdGEpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogJ1RMV2g2N1A5M0tndG5aTkN0R25FSE0xSDMzTmhxMnV2dk4nLCBhbW91bnQ6ICcxMDAwMDAwJyB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgIHR4SUQsXG4gICAgICAgICAgICAgIHJhd19kYXRhOiByYXdEYXRhLFxuICAgICAgICAgICAgICByYXdfZGF0YV9oZXg6IGV4cGVjdGVkUmF3RGF0YUhleCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXMpLCB7XG4gICAgICAgICAgbWVzc2FnZTogJ1RyYW5zYWN0aW9uIGhhcyBub3QgaGF2ZSBhIHZhbGlkIGlkJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdpdGggbWlzc2luZyBhbW91bnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHRyYW5zZmVyQ29udHJhY3QgPSB7XG4gICAgICAgICAgcGFyYW1ldGVyOiB7XG4gICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICBvd25lcl9hZGRyZXNzOiAnNDE3M2E1OTkzY2QxODJhZTE1MmFkYWQ4MjAzMTYzZjc4MGM2NWE4YWE1JyxcbiAgICAgICAgICAgICAgdG9fYWRkcmVzczogJzQxYzI1NDIwMjU1YzJjNWEyZGQ1NGVmNjlmOTJlZjI2MWU2YmQ0MjE2YScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHlwZV91cmw6ICd0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHlwZTogJ1RyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJhd0RhdGEgPSB7XG4gICAgICAgICAgY29udHJhY3Q6IFt0cmFuc2ZlckNvbnRyYWN0XSxcbiAgICAgICAgICByZWZfYmxvY2tfYnl0ZXM6ICdjOGNmJyxcbiAgICAgICAgICByZWZfYmxvY2tfaGFzaDogJzg5MTc3ZmQ4NGM1ZDkxOTYnLFxuICAgICAgICAgIGV4cGlyYXRpb246IHRpbWVzdGFtcCArIDM2MDAwMDAsXG4gICAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsXG4gICAgICAgICAgZmVlX2xpbWl0OiAxNTAwMDAwMDAsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRSYXdEYXRhID0ge1xuICAgICAgICAgIGNvbnRyYWN0OiByYXdEYXRhLmNvbnRyYWN0IGFzIGFueSxcbiAgICAgICAgICByZWZCbG9ja0J5dGVzOiByYXdEYXRhLnJlZl9ibG9ja19ieXRlcyxcbiAgICAgICAgICByZWZCbG9ja0hhc2g6IHJhd0RhdGEucmVmX2Jsb2NrX2hhc2gsXG4gICAgICAgICAgZXhwaXJhdGlvbjogcmF3RGF0YS5leHBpcmF0aW9uLFxuICAgICAgICAgIHRpbWVzdGFtcDogcmF3RGF0YS50aW1lc3RhbXAsXG4gICAgICAgICAgZmVlTGltaXQ6IHJhd0RhdGEuZmVlX2xpbWl0LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGV4cGVjdGVkUmF3RGF0YUhleCA9IFV0aWxzLmdlbmVyYXRlUmF3RGF0YUhleCh0cmFuc2Zvcm1lZFJhd0RhdGEpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogJ1RMV2g2N1A5M0tndG5aTkN0R25FSE0xSDMzTmhxMnV2dk4nLCBhbW91bnQ6ICcxMDAwMDAwJyB9XSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgIHJhd19kYXRhOiByYXdEYXRhLFxuICAgICAgICAgICAgICByYXdfZGF0YV9oZXg6IGV4cGVjdGVkUmF3RGF0YUhleCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXMpLCB7XG4gICAgICAgICAgbWVzc2FnZTogJ0Ftb3VudCBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIHRyYW5zZmVyIGNvbnRyYWN0LicsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBkdWUgdG8gYW1vdW50IG1pc3NtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgdHJhbnNmZXJDb250cmFjdCA9IHtcbiAgICAgICAgICBwYXJhbWV0ZXI6IHtcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgIGFtb3VudDogMjAwMDAwMCxcbiAgICAgICAgICAgICAgb3duZXJfYWRkcmVzczogJzQxNzNhNTk5M2NkMTgyYWUxNTJhZGFkODIwMzE2M2Y3ODBjNjVhOGFhNScsXG4gICAgICAgICAgICAgIHRvX2FkZHJlc3M6ICc0MWQ2Y2Q2YTJjMGZmMzVhMzE5ZTZhYmI1Yjk1MDNiYTAyNzg2Nzk4ODInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGVfdXJsOiAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5UcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGU6ICdUcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByYXdEYXRhID0ge1xuICAgICAgICAgIGNvbnRyYWN0OiBbdHJhbnNmZXJDb250cmFjdF0sXG4gICAgICAgICAgcmVmX2Jsb2NrX2J5dGVzOiAnYzhjZicsXG4gICAgICAgICAgcmVmX2Jsb2NrX2hhc2g6ICc4OTE3N2ZkODRjNWQ5MTk2JyxcbiAgICAgICAgICBleHBpcmF0aW9uOiB0aW1lc3RhbXAgKyAzNjAwMDAwLFxuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIGZlZV9saW1pdDogMTUwMDAwMDAwLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRyYW5zZm9ybSByYXdEYXRhIHRvIG1hdGNoIHRoZSBleHBlY3RlZCBwYXJhbWV0ZXIgc3RydWN0dXJlXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkUmF3RGF0YSA9IHtcbiAgICAgICAgICBjb250cmFjdDogcmF3RGF0YS5jb250cmFjdCBhcyBhbnksXG4gICAgICAgICAgcmVmQmxvY2tCeXRlczogcmF3RGF0YS5yZWZfYmxvY2tfYnl0ZXMsXG4gICAgICAgICAgcmVmQmxvY2tIYXNoOiByYXdEYXRhLnJlZl9ibG9ja19oYXNoLFxuICAgICAgICAgIGV4cGlyYXRpb246IHJhd0RhdGEuZXhwaXJhdGlvbixcbiAgICAgICAgICB0aW1lc3RhbXA6IHJhd0RhdGEudGltZXN0YW1wLFxuICAgICAgICAgIGZlZUxpbWl0OiByYXdEYXRhLmZlZV9saW1pdCxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZW5lcmF0ZSByYXdfZGF0YV9oZXggdXNpbmcgdGhlIHV0aWxpdHkgZnVuY3Rpb25cbiAgICAgICAgY29uc3QgcmF3RGF0YUhleCA9IFV0aWxzLmdlbmVyYXRlUmF3RGF0YUhleCh0cmFuc2Zvcm1lZFJhd0RhdGEpO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0eElEIGFzIFNIQTI1NiBoYXNoIG9mIHJhd19kYXRhX2hleFxuICAgICAgICBjb25zdCB0eElEID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKEJ1ZmZlci5mcm9tKHJhd0RhdGFIZXgsICdoZXgnKSkuZGlnZXN0KCdoZXgnKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFkZHJlc3M6ICc0MWQ2Y2Q2YTJjMGZmMzVhMzE5ZTZhYmI1Yjk1MDNiYTAyNzg2Nzk4ODInLFxuICAgICAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgIHR4SUQsXG4gICAgICAgICAgICAgIHJhd19kYXRhOiByYXdEYXRhLFxuICAgICAgICAgICAgICByYXdfZGF0YV9oZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICAgIG1lc3NhZ2U6ICd0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCB0aGUgdmFsdWUgZ2l2ZW4gYnkgY2xpZW50JyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGR1ZSB0byBkZXN0aW5hdGlvbiBhZGRyZXNzIG1pc3NtYXRjaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICAgICAgY29uc3QgdHJhbnNmZXJDb250cmFjdCA9IHtcbiAgICAgICAgICBwYXJhbWV0ZXI6IHtcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgIGFtb3VudDogMTAwMDAwMCxcbiAgICAgICAgICAgICAgb3duZXJfYWRkcmVzczogJzQxNzNhNTk5M2NkMTgyYWUxNTJhZGFkODIwMzE2M2Y3ODBjNjVhOGFhNScsXG4gICAgICAgICAgICAgIHRvX2FkZHJlc3M6ICc0MWQ2Y2Q2YTJjMGZmMzVhMzE5ZTZhYmI1Yjk1MDNiYTAyNzg2Nzk4ODInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGVfdXJsOiAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5UcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGU6ICdUcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByYXdEYXRhID0ge1xuICAgICAgICAgIGNvbnRyYWN0OiBbdHJhbnNmZXJDb250cmFjdF0sXG4gICAgICAgICAgcmVmX2Jsb2NrX2J5dGVzOiAnYzhjZicsXG4gICAgICAgICAgcmVmX2Jsb2NrX2hhc2g6ICc4OTE3N2ZkODRjNWQ5MTk2JyxcbiAgICAgICAgICBleHBpcmF0aW9uOiB0aW1lc3RhbXAgKyAzNjAwMDAwLFxuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIGZlZV9saW1pdDogMTUwMDAwMDAwLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFRyYW5zZm9ybSByYXdEYXRhIHRvIG1hdGNoIHRoZSBleHBlY3RlZCBwYXJhbWV0ZXIgc3RydWN0dXJlXG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkUmF3RGF0YSA9IHtcbiAgICAgICAgICBjb250cmFjdDogcmF3RGF0YS5jb250cmFjdCBhcyBhbnksXG4gICAgICAgICAgcmVmQmxvY2tCeXRlczogcmF3RGF0YS5yZWZfYmxvY2tfYnl0ZXMsXG4gICAgICAgICAgcmVmQmxvY2tIYXNoOiByYXdEYXRhLnJlZl9ibG9ja19oYXNoLFxuICAgICAgICAgIGV4cGlyYXRpb246IHJhd0RhdGEuZXhwaXJhdGlvbixcbiAgICAgICAgICB0aW1lc3RhbXA6IHJhd0RhdGEudGltZXN0YW1wLFxuICAgICAgICAgIGZlZUxpbWl0OiByYXdEYXRhLmZlZV9saW1pdCxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZW5lcmF0ZSByYXdfZGF0YV9oZXggdXNpbmcgdGhlIHV0aWxpdHkgZnVuY3Rpb25cbiAgICAgICAgY29uc3QgcmF3RGF0YUhleCA9IFV0aWxzLmdlbmVyYXRlUmF3RGF0YUhleCh0cmFuc2Zvcm1lZFJhd0RhdGEpO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0eElEIGFzIFNIQTI1NiBoYXNoIG9mIHJhd19kYXRhX2hleFxuICAgICAgICBjb25zdCB0eElEID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKEJ1ZmZlci5mcm9tKHJhd0RhdGFIZXgsICdoZXgnKSkuZGlnZXN0KCdoZXgnKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFkZHJlc3M6ICc0MWQ2Y2Q2YTJjMGZmMzVhMzE5ZTZhYmI1Yjk1MDNiYTAyNzg2Nzk4ODMnLFxuICAgICAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgIHR4SUQsXG4gICAgICAgICAgICAgIHJhd19kYXRhOiByYXdEYXRhLFxuICAgICAgICAgICAgICByYXdfZGF0YV9oZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICAgIG1lc3NhZ2U6ICdkZXN0aW5hdGlvbiBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIHJlY2lwaWVudCBhZGRyZXNzJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RTUyBXYWxsZXQgVmVyaWZpY2F0aW9uJywgKCkgPT4ge1xuICAgIC8qKlxuICAgICAqIEhlbHBlciB0byBidWlsZCBhIHJhd19kYXRhX2hleCAocHJvdG9idWYpIGZvciBhIFRyYW5zZmVyQ29udHJhY3QuXG4gICAgICogRm9yIFRTUywgdHhQcmVidWlsZC50eEhleCBpcyB0aGUgcmF3X2RhdGFfaGV4IGRpcmVjdGx5IChub3QgYSBKU09OIHN0cmluZykuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYnVpbGRUc3NUcmFuc2ZlclR4SGV4KHBhcmFtczoge1xuICAgICAgb3duZXJBZGRyZXNzOiBzdHJpbmc7XG4gICAgICB0b0FkZHJlc3M6IHN0cmluZztcbiAgICAgIGFtb3VudDogbnVtYmVyO1xuICAgICAgdGltZXN0YW1wPzogbnVtYmVyO1xuICAgICAgZXhwaXJhdGlvbj86IG51bWJlcjtcbiAgICB9KTogc3RyaW5nIHtcbiAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IHBhcmFtcy50aW1lc3RhbXAgfHwgRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyQ29udHJhY3QgPSB7XG4gICAgICAgIHBhcmFtZXRlcjoge1xuICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICBhbW91bnQ6IHBhcmFtcy5hbW91bnQsXG4gICAgICAgICAgICBvd25lcl9hZGRyZXNzOiBwYXJhbXMub3duZXJBZGRyZXNzLFxuICAgICAgICAgICAgdG9fYWRkcmVzczogcGFyYW1zLnRvQWRkcmVzcyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR5cGVfdXJsOiAndHlwZS5nb29nbGVhcGlzLmNvbS9wcm90b2NvbC5UcmFuc2ZlckNvbnRyYWN0JyxcbiAgICAgICAgfSxcbiAgICAgICAgdHlwZTogJ1RyYW5zZmVyQ29udHJhY3QnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHJhbnNmb3JtZWRSYXdEYXRhID0ge1xuICAgICAgICBjb250cmFjdDogW3RyYW5zZmVyQ29udHJhY3RdIGFzIGFueSxcbiAgICAgICAgcmVmQmxvY2tCeXRlczogJ2M4Y2YnLFxuICAgICAgICByZWZCbG9ja0hhc2g6ICc4OTE3N2ZkODRjNWQ5MTk2JyxcbiAgICAgICAgZXhwaXJhdGlvbjogcGFyYW1zLmV4cGlyYXRpb24gfHwgdGltZXN0YW1wICsgMzYwMDAwMCxcbiAgICAgICAgdGltZXN0YW1wOiB0aW1lc3RhbXAsXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gVXRpbHMuZ2VuZXJhdGVSYXdEYXRhSGV4KHRyYW5zZm9ybWVkUmF3RGF0YSk7XG4gICAgfVxuXG4gICAgZGVzY3JpYmUoJ1RyYW5zZmVyQ29udHJhY3QnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGEgdmFsaWQgVFNTIFRyYW5zZmVyQ29udHJhY3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG93bmVySGV4ID0gJzQxNzNhNTk5M2NkMTgyYWUxNTJhZGFkODIwMzE2M2Y3ODBjNjVhOGFhNSc7XG4gICAgICAgIGNvbnN0IHRvSGV4ID0gJzQxZDZjZDZhMmMwZmYzNWEzMTllNmFiYjViOTUwM2JhMDI3ODY3OTg4Mic7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IDEwMDAwMDA7XG5cbiAgICAgICAgY29uc3QgcmF3RGF0YUhleCA9IGJ1aWxkVHNzVHJhbnNmZXJUeEhleCh7IG93bmVyQWRkcmVzczogb3duZXJIZXgsIHRvQWRkcmVzczogdG9IZXgsIGFtb3VudCB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC8vIFRTUyBwYXRoOiByZWNpcGllbnRzIHVzZSBiYXNlNTggYWRkcmVzc2VzXG4gICAgICAgICAgICAgICAgYWRkcmVzczogVXRpbHMuZ2V0QmFzZTU4QWRkcmVzc0Zyb21IZXgodG9IZXgpLFxuICAgICAgICAgICAgICAgIGFtb3VudDogYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgLy8gVFNTIHBhdGg6IHR4SGV4IGlzIHRoZSByYXcgcHJvdG9idWYgaGV4LCBub3QgYSBKU09OIHN0cmluZ1xuICAgICAgICAgICAgdHhIZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBUU1MgdmVyaWZpY2F0aW9uIHdoZW4gYW1vdW50IGRvZXMgbm90IG1hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBvd25lckhleCA9ICc0MTczYTU5OTNjZDE4MmFlMTUyYWRhZDgyMDMxNjNmNzgwYzY1YThhYTUnO1xuICAgICAgICBjb25zdCB0b0hleCA9ICc0MWQ2Y2Q2YTJjMGZmMzVhMzE5ZTZhYmI1Yjk1MDNiYTAyNzg2Nzk4ODInO1xuXG4gICAgICAgIGNvbnN0IHJhd0RhdGFIZXggPSBidWlsZFRzc1RyYW5zZmVyVHhIZXgoeyBvd25lckFkZHJlc3M6IG93bmVySGV4LCB0b0FkZHJlc3M6IHRvSGV4LCBhbW91bnQ6IDIwMDAwMDAgfSk7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIHR4UGFyYW1zOiB7XG4gICAgICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhZGRyZXNzOiBVdGlscy5nZXRCYXNlNThBZGRyZXNzRnJvbUhleCh0b0hleCksXG4gICAgICAgICAgICAgICAgYW1vdW50OiAnMTAwMDAwMCcsIC8vIG1pc21hdGNoOiB0eEhleCBoYXMgMjAwMDAwMFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiByYXdEYXRhSGV4LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXMpLCB7XG4gICAgICAgICAgbWVzc2FnZTogJ3RyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoZSB2YWx1ZSBnaXZlbiBieSBjbGllbnQnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgVFNTIHZlcmlmaWNhdGlvbiB3aGVuIGRlc3RpbmF0aW9uIGFkZHJlc3MgZG9lcyBub3QgbWF0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG93bmVySGV4ID0gJzQxNzNhNTk5M2NkMTgyYWUxNTJhZGFkODIwMzE2M2Y3ODBjNjVhOGFhNSc7XG4gICAgICAgIGNvbnN0IHRvSGV4ID0gJzQxZDZjZDZhMmMwZmYzNWEzMTllNmFiYjViOTUwM2JhMDI3ODY3OTg4Mic7XG5cbiAgICAgICAgY29uc3QgcmF3RGF0YUhleCA9IGJ1aWxkVHNzVHJhbnNmZXJUeEhleCh7IG93bmVyQWRkcmVzczogb3duZXJIZXgsIHRvQWRkcmVzczogdG9IZXgsIGFtb3VudDogMTAwMDAwMCB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC8vIERpZmZlcmVudCBhZGRyZXNzIHRoYW4gd2hhdCdzIGluIHRoZSB0cmFuc2FjdGlvblxuICAgICAgICAgICAgICAgIGFkZHJlc3M6ICdUVHNHd25UTFE0ZXJ5RkpwRHZKU2Z1R1F4UFhSQ2pYdlp6JyxcbiAgICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogcmF3RGF0YUhleCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICAgIG1lc3NhZ2U6ICdkZXN0aW5hdGlvbiBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIHJlY2lwaWVudCBhZGRyZXNzJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIG5vbi1UcmFuc2Zlciwgbm9uLVRyaWdnZXJTbWFydENvbnRyYWN0IHR5cGVzIGluIFRTUycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEFjY291bnRQZXJtaXNzaW9uVXBkYXRlIGFuZCBvdGhlciBuYXRpdmUgVFJYIGNvbnRyYWN0cyAoZnJlZXplLCB2b3RlLCBldGMuKSBwYXNzIHRocm91Z2hcbiAgICAgIC8vIHdpdGhvdXQgcmVjaXBpZW50IHZhbGlkYXRpb24gaW4gdGhlIFRTUyBwYXRoLlxuICAgICAgY29uc3QgcmF3RGF0YUhleCA9IFVuc2lnbmVkQWNjb3VudFBlcm1pc3Npb25VcGRhdGVDb250cmFjdFR4LnJhd19kYXRhX2hleDtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHJlY2lwaWVudHM6IFtdLFxuICAgICAgICB9LFxuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgIH0sXG4gICAgICAgIHdhbGxldDoge30sXG4gICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1RyaWdnZXJTbWFydENvbnRyYWN0IChUUkMyMCkgcm91dGVkIHRocm91Z2ggbmF0aXZlIFRyeCcsICgpID0+IHtcbiAgICAgIC8vIENFQ0hPLTIyNDg6IHRva2VuIHdhbGxldHMgYXJlIHNvbWV0aW1lcyBjb25zdHJ1Y3RlZCB3aXRoIHRoZSBuYXRpdmUgY29pbiBpbnN0YW5jZVxuICAgICAgLy8gKGUuZy4gYml0Z28uY29pbigndHJ4Jykud2FsbGV0cygpLmdldCgpIG9uIGEgdHJ4Ojx0b2tlbj4gd2FsbGV0KSwgc28gYSBUUkMyMFxuICAgICAgLy8gVHJpZ2dlclNtYXJ0Q29udHJhY3QgcHJlYnVpbGQgY2FuIHJlYWNoIHRoZSBuYXRpdmUgVHJ4IHZlcmlmaWVyLiBJdCBtdXN0IHZhbGlkYXRlXG4gICAgICAvLyByZWNpcGllbnQgYW5kIGFtb3VudCAoc2FtZSBhcyBUcnhUb2tlbi52ZXJpZnlUcmFuc2FjdGlvbikgaW5zdGVhZCBvZiB0aHJvd2luZy5cbiAgICAgIGNvbnN0IHRyYzIwUmF3RGF0YUhleCA9XG4gICAgICAgICcwYTAyNTc4YjIyMDg2MTEzYmI5YWMzNTE0MzJiNDA4OGVhZTdhNmRlMzA1YWFlMDEwODFmMTJhOTAxMGEzMTc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjk2NzY3NjU3MjUzNmQ2MTcyNzQ0MzZmNmU3NDcyNjE2Mzc0MTI3NDBhMTU0MWM1MWZiZWVhNzg5MTBiMTViMWQzZThhOWI2MjkxNGNhOTRkMWE0YWMxMjE1NDE0MmExZTM5YWVmYTQ5MjkwZjJiM2Y5ZWQ2ODhkN2NlY2Y4NmNkNmUwMjI0NGE5MDU5Y2JiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwODQ4MzYxOGNhODVjMzVhOWI5MjNkOThiZWJjYTcxOGY1YTFkYjI3OTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDVmNWUxMDA3MDg4OGQ4Y2E1ZGUzMDkwMDFjMGMzOTMwNyc7XG5cbiAgICAgIC8vIFJlY2lwaWVudCBhZGRyZXNzIGRlY29kZWQgZnJvbSB0aGUgQUJJIGRhdGEgaW4gdGhlIHByb3RvYnVmIGFib3ZlICg0MSBwcmVmaXgg4oaSIGJhc2U1OClcbiAgICAgIGNvbnN0IHRyYzIwUmVjaXBpZW50SGV4ID0gJzQxODQ4MzYxOGNhODVjMzVhOWI5MjNkOThiZWJjYTcxOGY1YTFkYjI3OSc7XG4gICAgICBjb25zdCB0cmMyMFJlY2lwaWVudEJhc2U1OCA9IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHRyYzIwUmVjaXBpZW50SGV4KTtcbiAgICAgIGNvbnN0IHRyYzIwQW1vdW50ID0gJzEwMDAwMDAwMCc7XG5cbiAgICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYSBtYXRjaGluZyBUUkMyMCB0cmFuc2ZlciBpbnN0ZWFkIG9mIHRocm93aW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IHRyYzIwUmVjaXBpZW50QmFzZTU4LCBhbW91bnQ6IHRyYzIwQW1vdW50IH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHRyYzIwUmF3RGF0YUhleCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gVFJDMjAgYW1vdW50IGRvZXMgbm90IG1hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6IHRyYzIwUmVjaXBpZW50QmFzZTU4LCBhbW91bnQ6ICc5OTknIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHRyYzIwUmF3RGF0YUhleCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICAgIG1lc3NhZ2U6ICd0cmFuc2FjdGlvbiBhbW91bnQgaW4gdHhQcmVidWlsZCBkb2VzIG5vdCBtYXRjaCB0aGUgdmFsdWUgZ2l2ZW4gYnkgY2xpZW50JyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gVFJDMjAgZGVzdGluYXRpb24gZG9lcyBub3QgbWF0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgICAgcmVjaXBpZW50czogW3sgYWRkcmVzczogJ1RMV2g2N1A5M0tndG5aTkN0R25FSE0xSDMzTmhxMnV2dk4nLCBhbW91bnQ6IHRyYzIwQW1vdW50IH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHRyYzIwUmF3RGF0YUhleCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKSwge1xuICAgICAgICAgIG1lc3NhZ2U6ICdkZXN0aW5hdGlvbiBhZGRyZXNzIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIHJlY2lwaWVudCBhZGRyZXNzJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIG5vIHJlY2lwaWVudHMgYXJlIHByb3ZpZGVkIChjb25zb2xpZGF0aW9uIHBhdGgpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHRyYzIwUmF3RGF0YUhleCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdhbGxldDoge30sXG4gICAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24ocGFyYW1zKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiB0eEhleCBpcyBtaXNzaW5nIGZvciBUU1Mgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICB0eFBhcmFtczoge1xuICAgICAgICAgIHJlY2lwaWVudHM6IFt7IGFkZHJlc3M6ICdUUUZ4RFNvWHkyeVhSRTVIdEt3QXdyTlJYR3hZeGtlU0drJywgYW1vdW50OiAnMTAwMDAwMCcgfV0sXG4gICAgICAgIH0sXG4gICAgICAgIHR4UHJlYnVpbGQ6IHt9LFxuICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtcyksIHtcbiAgICAgICAgbWVzc2FnZTogJ21pc3NpbmcgdHhIZXggaW4gdHhQcmVidWlsZCcsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZXJpYWxpemVkVHhIZXggKEpTT04gc3RyaW5nKSBwYXRoJywgKCkgPT4ge1xuICAgICAgLy8gcHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24gcGFzc2VzIHR4SGV4IGFzIHNlcmlhbGl6ZWRUeEhleCDigJQgYSBmdWxsIEpTT04gc3RyaW5nXG4gICAgICAvLyBjb250YWluaW5nIHsgdHhJRCwgcmF3X2RhdGEsIHJhd19kYXRhX2hleCB9LiBUaGUgVFNTIGJyYW5jaCBtdXN0IGhhbmRsZSB0aGlzIGZvcm1hdFxuICAgICAgLy8gYnkgZXh0cmFjdGluZyByYXdfZGF0YV9oZXggYmVmb3JlIHByb3RvYnVmIGRlY29kaW5nLlxuXG4gICAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIFRTUyBUcmFuc2ZlckNvbnRyYWN0IHdoZW4gdHhIZXggaXMgYSBKU09OIHN0cmluZyAoc2VyaWFsaXplZFR4SGV4KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgb3duZXJIZXggPSAnNDE3M2E1OTkzY2QxODJhZTE1MmFkYWQ4MjAzMTYzZjc4MGM2NWE4YWE1JztcbiAgICAgICAgY29uc3QgdG9IZXggPSAnNDFkNmNkNmEyYzBmZjM1YTMxOWU2YWJiNWI5NTAzYmEwMjc4Njc5ODgyJztcbiAgICAgICAgY29uc3QgYW1vdW50ID0gMTAwMDAwMDtcblxuICAgICAgICBjb25zdCByYXdEYXRhSGV4ID0gYnVpbGRUc3NUcmFuc2ZlclR4SGV4KHsgb3duZXJBZGRyZXNzOiBvd25lckhleCwgdG9BZGRyZXNzOiB0b0hleCwgYW1vdW50IH0pO1xuICAgICAgICBjb25zdCB0eElEID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKEJ1ZmZlci5mcm9tKHJhd0RhdGFIZXgsICdoZXgnKSkuZGlnZXN0KCdoZXgnKTtcblxuICAgICAgICAvLyBTaW11bGF0ZSB0aGUgc2VyaWFsaXplZFR4SGV4IGZvcm1hdCBmcm9tIEJpdEdvIEFQSSAoSlNPTiBzdHJpbmcgd2l0aCB0eElEICsgcmF3X2RhdGFfaGV4KVxuICAgICAgICBjb25zdCBzZXJpYWxpemVkVHhIZXggPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdHhJRCxcbiAgICAgICAgICByYXdfZGF0YV9oZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgICAgcmF3X2RhdGE6IHt9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFkZHJlc3M6IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHRvSGV4KSxcbiAgICAgICAgICAgICAgICBhbW91bnQ6IGFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBzZXJpYWxpemVkVHhIZXgsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB3YWxsZXQ6IHt9LFxuICAgICAgICAgIHdhbGxldFR5cGU6ICd0c3MnLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIGFtb3VudCBtaXNtYXRjaGVzIHdpdGggSlNPTiB0eEhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgb3duZXJIZXggPSAnNDE3M2E1OTkzY2QxODJhZTE1MmFkYWQ4MjAzMTYzZjc4MGM2NWE4YWE1JztcbiAgICAgICAgY29uc3QgdG9IZXggPSAnNDFkNmNkNmEyYzBmZjM1YTMxOWU2YWJiNWI5NTAzYmEwMjc4Njc5ODgyJztcblxuICAgICAgICBjb25zdCByYXdEYXRhSGV4ID0gYnVpbGRUc3NUcmFuc2ZlclR4SGV4KHsgb3duZXJBZGRyZXNzOiBvd25lckhleCwgdG9BZGRyZXNzOiB0b0hleCwgYW1vdW50OiAyMDAwMDAwIH0pO1xuICAgICAgICBjb25zdCBzZXJpYWxpemVkVHhIZXggPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdHhJRDogY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKEJ1ZmZlci5mcm9tKHJhd0RhdGFIZXgsICdoZXgnKSkuZGlnZXN0KCdoZXgnKSxcbiAgICAgICAgICByYXdfZGF0YV9oZXg6IHJhd0RhdGFIZXgsXG4gICAgICAgICAgcmF3X2RhdGE6IHt9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgdHhQYXJhbXM6IHtcbiAgICAgICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFkZHJlc3M6IFV0aWxzLmdldEJhc2U1OEFkZHJlc3NGcm9tSGV4KHRvSGV4KSxcbiAgICAgICAgICAgICAgICBhbW91bnQ6ICcxMDAwMDAwJywgLy8gbWlzbWF0Y2hcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogc2VyaWFsaXplZFR4SGV4LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2FsbGV0OiB7fSxcbiAgICAgICAgICB3YWxsZXRUeXBlOiAndHNzJyxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbihwYXJhbXMpLCB7XG4gICAgICAgICAgbWVzc2FnZTogJ3RyYW5zYWN0aW9uIGFtb3VudCBpbiB0eFByZWJ1aWxkIGRvZXMgbm90IG1hdGNoIHRoZSB2YWx1ZSBnaXZlbiBieSBjbGllbnQnLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19