@bitgo/sdk-coin-hbar 2.4.1 → 2.4.3

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 (44) hide show
  1. package/dist/test/fixtures/hbar.d.ts +6 -0
  2. package/dist/test/fixtures/hbar.d.ts.map +1 -0
  3. package/dist/test/fixtures/hbar.js +9 -0
  4. package/dist/test/resources/hbar.d.ts +67 -0
  5. package/dist/test/resources/hbar.d.ts.map +1 -0
  6. package/dist/test/resources/hbar.js +73 -0
  7. package/dist/test/unit/fixtures/hbarBackupKey.d.ts +4 -0
  8. package/dist/test/unit/fixtures/hbarBackupKey.d.ts.map +1 -0
  9. package/dist/test/unit/fixtures/hbarBackupKey.js +10 -0
  10. package/dist/test/unit/getBuilderFactory.d.ts +3 -0
  11. package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
  12. package/dist/test/unit/getBuilderFactory.js +10 -0
  13. package/dist/test/unit/hbar.d.ts +2 -0
  14. package/dist/test/unit/hbar.d.ts.map +1 -0
  15. package/dist/test/unit/hbar.js +1216 -0
  16. package/dist/test/unit/hbarToken.d.ts +2 -0
  17. package/dist/test/unit/hbarToken.d.ts.map +1 -0
  18. package/dist/test/unit/hbarToken.js +34 -0
  19. package/dist/test/unit/keyPair.d.ts +2 -0
  20. package/dist/test/unit/keyPair.d.ts.map +1 -0
  21. package/dist/test/unit/keyPair.js +179 -0
  22. package/dist/test/unit/transaction.d.ts +2 -0
  23. package/dist/test/unit/transaction.d.ts.map +1 -0
  24. package/dist/test/unit/transaction.js +94 -0
  25. package/dist/test/unit/transactionBuilder/tokenAssociateBuilder.d.ts +2 -0
  26. package/dist/test/unit/transactionBuilder/tokenAssociateBuilder.d.ts.map +1 -0
  27. package/dist/test/unit/transactionBuilder/tokenAssociateBuilder.js +215 -0
  28. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts +2 -0
  29. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.d.ts.map +1 -0
  30. package/dist/test/unit/transactionBuilder/tokenTransferBuilder.js +329 -0
  31. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
  32. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  33. package/dist/test/unit/transactionBuilder/transferBuilder.js +353 -0
  34. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +2 -0
  35. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  36. package/dist/test/unit/transactionBuilder/walletInitialization.js +214 -0
  37. package/dist/test/unit/utils.d.ts +2 -0
  38. package/dist/test/unit/utils.d.ts.map +1 -0
  39. package/dist/test/unit/utils.js +275 -0
  40. package/dist/tsconfig.tsbuildinfo +1 -0
  41. package/package.json +10 -7
  42. package/.eslintignore +0 -5
  43. package/.mocharc.yml +0 -8
  44. package/CHANGELOG.md +0 -882
@@ -0,0 +1,214 @@
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 assert_1 = __importDefault(require("assert"));
40
+ const should = __importStar(require("should"));
41
+ const getBuilderFactory_1 = require("../getBuilderFactory");
42
+ const src_1 = require("../../../src");
43
+ const testData = __importStar(require("../../resources/hbar"));
44
+ const sdk_core_1 = require("@bitgo/sdk-core");
45
+ describe('HBAR Wallet initialization', () => {
46
+ const factory = (0, getBuilderFactory_1.getBuilderFactory)('thbar');
47
+ const initTxBuilder = () => {
48
+ const txBuilder = factory.getWalletInitializationBuilder();
49
+ txBuilder.fee({ fee: '1000000000' });
50
+ txBuilder.owner(testData.OWNER1);
51
+ txBuilder.owner(testData.OWNER2);
52
+ txBuilder.owner(testData.OWNER3);
53
+ txBuilder.source({ address: testData.OPERATOR.accountId });
54
+ txBuilder.sign({ key: testData.OPERATOR.privateKey });
55
+ return txBuilder;
56
+ };
57
+ describe('should build ', () => {
58
+ it('a valid raw tx for wallet init', async () => {
59
+ const builder = initTxBuilder();
60
+ const tx = await builder.build();
61
+ const raw = tx.toBroadcastFormat();
62
+ const builder2 = factory.from(raw);
63
+ const tx2 = await builder2.build();
64
+ should.deepEqual(tx.signature.length, 1);
65
+ should.deepEqual(tx.toJson(), tx2.toJson());
66
+ should.deepEqual(raw, tx2.toBroadcastFormat());
67
+ tx.type.should.equal(sdk_core_1.TransactionType.WalletInitialization);
68
+ tx2.type.should.equal(sdk_core_1.TransactionType.WalletInitialization);
69
+ });
70
+ it('an init transaction', async () => {
71
+ const txBuilder = initTxBuilder();
72
+ const tx = await txBuilder.build();
73
+ const txJson = tx.toJson();
74
+ txJson.fee.should.equal(1000000000);
75
+ should.deepEqual(tx.signature.length, 1);
76
+ should.equal(txJson.from, testData.OPERATOR.accountId);
77
+ tx.type.should.equal(sdk_core_1.TransactionType.WalletInitialization);
78
+ });
79
+ it('offline signing init transaction', async () => {
80
+ const txBuilder1 = factory.getWalletInitializationBuilder();
81
+ txBuilder1.startTime('1596110493.372646570');
82
+ txBuilder1.fee({ fee: '1000000000' });
83
+ txBuilder1.owner(testData.OWNER1);
84
+ txBuilder1.owner(testData.OWNER2);
85
+ txBuilder1.owner(testData.OWNER3);
86
+ txBuilder1.source({ address: testData.OPERATOR.accountId });
87
+ const tx1 = await txBuilder1.build();
88
+ const factory2 = (0, getBuilderFactory_1.getBuilderFactory)('thbar');
89
+ const txBuilder2 = factory2.from(tx1.toBroadcastFormat());
90
+ txBuilder2.sign({ key: testData.OPERATOR.privateKey });
91
+ const tx2 = await txBuilder2.build();
92
+ const factory3 = (0, getBuilderFactory_1.getBuilderFactory)('thbar');
93
+ const txBuilder3 = factory3.from(tx2.toBroadcastFormat());
94
+ txBuilder3.sign({ key: testData.ACCOUNT_1.prvKeyWithPrefix });
95
+ const tx3 = await txBuilder3.build();
96
+ should.deepEqual(tx2.signature.length, 1);
97
+ should.deepEqual(tx3.signature.length, 2);
98
+ should.deepEqual(tx2.toBroadcastFormat(), testData.WALLET_BUILDER_SIGNED_TRANSACTION);
99
+ should.deepEqual(tx3.toBroadcastFormat(), testData.WALLET_BUILDER_SIGNED_TWICE_TRANSACTION);
100
+ });
101
+ it('initialize from invalid tx adding new fields', async () => {
102
+ const txBuilder = factory.from(testData.WALLET_INIT_2_OWNERS);
103
+ txBuilder.owner(testData.OWNER3);
104
+ txBuilder.sign({ key: testData.OPERATOR.privateKey });
105
+ const tx = await txBuilder.build();
106
+ should.deepEqual(tx.signature.length, 1);
107
+ should.deepEqual(tx.toBroadcastFormat(), testData.WALLET_BUILDER_SIGNED_TRANSACTION);
108
+ });
109
+ it('an init transaction with external signature', async () => {
110
+ const txBuilder = factory.getWalletInitializationBuilder();
111
+ txBuilder.fee({ fee: '1000000000' });
112
+ txBuilder.owner(testData.OWNER1);
113
+ txBuilder.owner(testData.OWNER2);
114
+ txBuilder.owner(testData.OWNER3);
115
+ txBuilder.source({ address: testData.OPERATOR.accountId });
116
+ txBuilder.signature('20bc01a6da677b99974b17204de5ff6f34f8e5904f58d6df1ceb39b473e7295dccf60fcedaf4f' +
117
+ 'dc3f6bef93edcfbe2a7ec33cc94c893906a063383c27b014f09', new src_1.KeyPair({ pub: testData.ACCOUNT_1.pubKeyWithPrefix }));
118
+ const tx = await txBuilder.build();
119
+ const txJson = tx.toJson();
120
+ should.equal(txJson.from, testData.OPERATOR.accountId);
121
+ });
122
+ it('an init transaction with external signature included twice', async () => {
123
+ const txBuilder = factory.getWalletInitializationBuilder();
124
+ txBuilder.fee({ fee: '1000000000' });
125
+ txBuilder.owner(testData.OWNER1);
126
+ txBuilder.owner(testData.OWNER2);
127
+ txBuilder.owner(testData.OWNER3);
128
+ txBuilder.source({ address: testData.OPERATOR.accountId });
129
+ txBuilder.signature('20bc01a6da677b99974b17204de5ff6f34f8e5904f58d6df1ceb39b473e7295dccf60fcedaf4f' +
130
+ 'dc3f6bef93edcfbe2a7ec33cc94c893906a063383c27b014f09', new src_1.KeyPair({ pub: testData.ACCOUNT_1.pubKeyWithPrefix }));
131
+ txBuilder.signature('20bc01a6da677b99974b17204de5ff6f34f8e5904f58d6df1ceb39b473e7295dccf60fcedaf4f' +
132
+ 'dc3f6bef93edcfbe2a7ec33cc94c893906a063383c27b014f09', new src_1.KeyPair({ pub: testData.ACCOUNT_1.pubKeyWithPrefix }));
133
+ const tx = await txBuilder.build();
134
+ const txJson = tx.toJson();
135
+ should.equal(txJson.from, testData.OPERATOR.accountId);
136
+ });
137
+ });
138
+ describe('should fail to build', () => {
139
+ it('a transaction without fee', async () => {
140
+ const txBuilder = factory.getWalletInitializationBuilder();
141
+ txBuilder.owner(testData.OWNER1);
142
+ txBuilder.owner(testData.OWNER2);
143
+ txBuilder.owner(testData.OWNER3);
144
+ txBuilder.source({ address: testData.OPERATOR.accountId });
145
+ await txBuilder.build().should.be.rejectedWith('Invalid transaction: missing fee');
146
+ });
147
+ it('a wallet initialization the wrong number of owners', async () => {
148
+ const txBuilder = factory.getWalletInitializationBuilder();
149
+ txBuilder.fee({ fee: '1000000000' });
150
+ txBuilder.owner(testData.OWNER1);
151
+ txBuilder.owner(testData.OWNER2);
152
+ txBuilder.source({ address: testData.OPERATOR.accountId });
153
+ await txBuilder
154
+ .build()
155
+ .should.be.rejectedWith('Invalid transaction: wrong number of owners -- required: 3, found: 2');
156
+ assert_1.default.throws(() => txBuilder.owner(testData.OWNER1), new RegExp('Repeated owner address: ' + testData.OWNER1));
157
+ const newTxBuilder = factory.getWalletInitializationBuilder();
158
+ newTxBuilder.fee({ fee: '1000000000' });
159
+ newTxBuilder.source({ address: testData.OPERATOR.accountId });
160
+ await newTxBuilder
161
+ .build()
162
+ .should.be.rejectedWith('Invalid transaction: wrong number of owners -- required: 3, found: 0');
163
+ });
164
+ it('a transaction with invalid source', async () => {
165
+ const factory = (0, getBuilderFactory_1.getBuilderFactory)('thbar');
166
+ const txBuilder = factory.getWalletInitializationBuilder();
167
+ txBuilder.fee({ fee: '1000000000' });
168
+ txBuilder.owner(testData.OWNER1);
169
+ txBuilder.owner(testData.OWNER2);
170
+ txBuilder.owner(testData.OWNER3);
171
+ await txBuilder.build().should.be.rejectedWith('Invalid transaction: missing source');
172
+ });
173
+ });
174
+ describe('should validate', () => {
175
+ it('an address', async () => {
176
+ const txBuilder = factory.getWalletInitializationBuilder();
177
+ txBuilder.validateAddress(testData.VALID_ADDRESS);
178
+ assert_1.default.throws(() => txBuilder.validateAddress(testData.INVALID_ADDRESS), new RegExp('Invalid address ' + testData.INVALID_ADDRESS.address));
179
+ });
180
+ it('value should be greater than zero', () => {
181
+ const txBuilder = factory.getWalletInitializationBuilder();
182
+ assert_1.default.throws(() => txBuilder.fee({ fee: '-10' }));
183
+ should.doesNotThrow(() => txBuilder.fee({ fee: '10' }));
184
+ });
185
+ it('a private key', () => {
186
+ const txBuilder = factory.getWalletInitializationBuilder();
187
+ assert_1.default.throws(() => txBuilder.validateKey({ key: 'abc' }), /Invalid private key length/);
188
+ should.doesNotThrow(() => txBuilder.validateKey({ key: testData.ACCOUNT_1.prvKeyWithPrefix }));
189
+ });
190
+ it('a raw transaction', async () => {
191
+ const txBuilder = factory.getWalletInitializationBuilder();
192
+ should.doesNotThrow(() => txBuilder.validateRawTransaction(testData.WALLET_INITIALIZATION));
193
+ assert_1.default.throws(() => txBuilder.validateRawTransaction('0x00001000'));
194
+ assert_1.default.throws(() => txBuilder.validateRawTransaction(''));
195
+ assert_1.default.throws(() => txBuilder.validateRawTransaction('pqrs'));
196
+ assert_1.default.throws(() => txBuilder.validateRawTransaction(1234));
197
+ });
198
+ it('a transaction to build', async () => {
199
+ const txBuilder = factory.getWalletInitializationBuilder();
200
+ assert_1.default.throws(() => txBuilder.validateTransaction(), /Invalid transaction: wrong number of owners/);
201
+ txBuilder.fee({ fee: '10' });
202
+ assert_1.default.throws(() => txBuilder.validateTransaction(), /Invalid transaction: wrong number of owners/);
203
+ txBuilder.source(testData.VALID_ADDRESS);
204
+ assert_1.default.throws(() => txBuilder.validateTransaction(), /wrong number of owners -- required: 3, found: 0/);
205
+ txBuilder.owner(testData.OWNER1);
206
+ assert_1.default.throws(() => txBuilder.validateTransaction(), /wrong number of owners -- required: 3, found: 1/);
207
+ txBuilder.owner(testData.OWNER2);
208
+ assert_1.default.throws(() => txBuilder.validateTransaction(), /wrong number of owners -- required: 3, found: 2/);
209
+ txBuilder.owner(testData.OWNER3);
210
+ should.doesNotThrow(() => txBuilder.validateTransaction());
211
+ });
212
+ });
213
+ });
214
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0SW5pdGlhbGl6YXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvdHJhbnNhY3Rpb25CdWlsZGVyL3dhbGxldEluaXRpYWxpemF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLCtDQUFpQztBQUNqQyw0REFBeUQ7QUFDekQsc0NBQXVDO0FBQ3ZDLCtEQUFpRDtBQUNqRCw4Q0FBa0Q7QUFHbEQsUUFBUSxDQUFDLDRCQUE0QixFQUFFLEdBQUcsRUFBRTtJQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFBLHFDQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRTNDLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRTtRQUN6QixNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsOEJBQThCLEVBQUUsQ0FBQztRQUMzRCxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDckMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDakMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDM0QsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDdEQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQyxDQUFDO0lBRUYsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7UUFD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QUFDLENBQUM7WUFDN0IsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFLEVBQUUsNkNBQTZDLENBQUMsQ0FBQztZQUNwRyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN6QyxnQkFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxpREFBaUQsQ0FBQyxDQUFDO1lBQ3hHLFNBQVMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pDLGdCQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLGlEQUFpRCxDQUFDLENBQUM7WUFDeEcsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakMsZ0JBQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFLEVBQUUsaURBQWlELENBQUMsQ0FBQztZQUN4RyxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNqQyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7UUFDN0QsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyBnZXRCdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4uL2dldEJ1aWxkZXJGYWN0b3J5JztcbmltcG9ydCB7IEtleVBhaXIgfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2hiYXInO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25UeXBlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFdhbGxldEluaXRpYWxpemF0aW9uQnVpbGRlciB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvd2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyJztcblxuZGVzY3JpYmUoJ0hCQVIgV2FsbGV0IGluaXRpYWxpemF0aW9uJywgKCkgPT4ge1xuICBjb25zdCBmYWN0b3J5ID0gZ2V0QnVpbGRlckZhY3RvcnkoJ3RoYmFyJyk7XG5cbiAgY29uc3QgaW5pdFR4QnVpbGRlciA9ICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFdhbGxldEluaXRpYWxpemF0aW9uQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMDAwMDAwMDAwJyB9KTtcbiAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIxKTtcbiAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIyKTtcbiAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIzKTtcbiAgICB0eEJ1aWxkZXIuc291cmNlKHsgYWRkcmVzczogdGVzdERhdGEuT1BFUkFUT1IuYWNjb3VudElkIH0pO1xuICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5PUEVSQVRPUi5wcml2YXRlS2V5IH0pO1xuICAgIHJldHVybiB0eEJ1aWxkZXI7XG4gIH07XG5cbiAgZGVzY3JpYmUoJ3Nob3VsZCBidWlsZCAnLCAoKSA9PiB7XG4gICAgaXQoJ2EgdmFsaWQgcmF3IHR4IGZvciB3YWxsZXQgaW5pdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBpbml0VHhCdWlsZGVyKCk7XG4gICAgICBjb25zdCB0eCA9IGF3YWl0IGJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHJhdyA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCBidWlsZGVyMiA9IGZhY3RvcnkuZnJvbShyYXcpO1xuICAgICAgY29uc3QgdHgyID0gYXdhaXQgYnVpbGRlcjIuYnVpbGQoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHguc2lnbmF0dXJlLmxlbmd0aCwgMSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LnRvSnNvbigpLCB0eDIudG9Kc29uKCkpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChyYXcsIHR4Mi50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcbiAgICAgIHR4LnR5cGUuc2hvdWxkLmVxdWFsKFRyYW5zYWN0aW9uVHlwZS5XYWxsZXRJbml0aWFsaXphdGlvbik7XG4gICAgICB0eDIudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBpbml0IHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gaW5pdFR4QnVpbGRlcigpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgdHhKc29uLmZlZS5zaG91bGQuZXF1YWwoMTAwMDAwMDAwMCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LnNpZ25hdHVyZS5sZW5ndGgsIDEpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4SnNvbi5mcm9tLCB0ZXN0RGF0YS5PUEVSQVRPUi5hY2NvdW50SWQpO1xuICAgICAgdHgudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdvZmZsaW5lIHNpZ25pbmcgaW5pdCB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlcjEgPSBmYWN0b3J5LmdldFdhbGxldEluaXRpYWxpemF0aW9uQnVpbGRlcigpO1xuICAgICAgdHhCdWlsZGVyMS5zdGFydFRpbWUoJzE1OTYxMTA0OTMuMzcyNjQ2NTcwJyk7XG4gICAgICB0eEJ1aWxkZXIxLmZlZSh7IGZlZTogJzEwMDAwMDAwMDAnIH0pO1xuICAgICAgdHhCdWlsZGVyMS5vd25lcih0ZXN0RGF0YS5PV05FUjEpO1xuICAgICAgdHhCdWlsZGVyMS5vd25lcih0ZXN0RGF0YS5PV05FUjIpO1xuICAgICAgdHhCdWlsZGVyMS5vd25lcih0ZXN0RGF0YS5PV05FUjMpO1xuICAgICAgdHhCdWlsZGVyMS5zb3VyY2UoeyBhZGRyZXNzOiB0ZXN0RGF0YS5PUEVSQVRPUi5hY2NvdW50SWQgfSk7XG4gICAgICBjb25zdCB0eDEgPSBhd2FpdCB0eEJ1aWxkZXIxLmJ1aWxkKCk7XG4gICAgICBjb25zdCBmYWN0b3J5MiA9IGdldEJ1aWxkZXJGYWN0b3J5KCd0aGJhcicpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyMiA9IGZhY3RvcnkyLmZyb20odHgxLnRvQnJvYWRjYXN0Rm9ybWF0KCkpO1xuICAgICAgdHhCdWlsZGVyMi5zaWduKHsga2V5OiB0ZXN0RGF0YS5PUEVSQVRPUi5wcml2YXRlS2V5IH0pO1xuICAgICAgY29uc3QgdHgyID0gYXdhaXQgdHhCdWlsZGVyMi5idWlsZCgpO1xuXG4gICAgICBjb25zdCBmYWN0b3J5MyA9IGdldEJ1aWxkZXJGYWN0b3J5KCd0aGJhcicpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyMyA9IGZhY3RvcnkzLmZyb20odHgyLnRvQnJvYWRjYXN0Rm9ybWF0KCkpO1xuICAgICAgdHhCdWlsZGVyMy5zaWduKHsga2V5OiB0ZXN0RGF0YS5BQ0NPVU5UXzEucHJ2S2V5V2l0aFByZWZpeCB9KTtcbiAgICAgIGNvbnN0IHR4MyA9IGF3YWl0IHR4QnVpbGRlcjMuYnVpbGQoKTtcblxuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eDIuc2lnbmF0dXJlLmxlbmd0aCwgMSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4My5zaWduYXR1cmUubGVuZ3RoLCAyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgyLnRvQnJvYWRjYXN0Rm9ybWF0KCksIHRlc3REYXRhLldBTExFVF9CVUlMREVSX1NJR05FRF9UUkFOU0FDVElPTik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4My50b0Jyb2FkY2FzdEZvcm1hdCgpLCB0ZXN0RGF0YS5XQUxMRVRfQlVJTERFUl9TSUdORURfVFdJQ0VfVFJBTlNBQ1RJT04pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2luaXRpYWxpemUgZnJvbSBpbnZhbGlkIHR4IGFkZGluZyBuZXcgZmllbGRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHRlc3REYXRhLldBTExFVF9JTklUXzJfT1dORVJTKSBhcyBXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXI7XG4gICAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIzKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiB0ZXN0RGF0YS5PUEVSQVRPUi5wcml2YXRlS2V5IH0pO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcblxuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eC5zaWduYXR1cmUubGVuZ3RoLCAxKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHgudG9Ccm9hZGNhc3RGb3JtYXQoKSwgdGVzdERhdGEuV0FMTEVUX0JVSUxERVJfU0lHTkVEX1RSQU5TQUNUSU9OKTtcbiAgICB9KTtcblxuICAgIGl0KCdhbiBpbml0IHRyYW5zYWN0aW9uIHdpdGggZXh0ZXJuYWwgc2lnbmF0dXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMDAwMDAwMDAwJyB9KTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjEpO1xuICAgICAgdHhCdWlsZGVyLm93bmVyKHRlc3REYXRhLk9XTkVSMik7XG4gICAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIzKTtcbiAgICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiB0ZXN0RGF0YS5PUEVSQVRPUi5hY2NvdW50SWQgfSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbmF0dXJlKFxuICAgICAgICAnMjBiYzAxYTZkYTY3N2I5OTk3NGIxNzIwNGRlNWZmNmYzNGY4ZTU5MDRmNThkNmRmMWNlYjM5YjQ3M2U3Mjk1ZGNjZjYwZmNlZGFmNGYnICtcbiAgICAgICAgICAnZGMzZjZiZWY5M2VkY2ZiZTJhN2VjMzNjYzk0Yzg5MzkwNmEwNjMzODNjMjdiMDE0ZjA5JyxcbiAgICAgICAgbmV3IEtleVBhaXIoeyBwdWI6IHRlc3REYXRhLkFDQ09VTlRfMS5wdWJLZXlXaXRoUHJlZml4IH0pXG4gICAgICApO1xuXG4gICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBzaG91bGQuZXF1YWwodHhKc29uLmZyb20sIHRlc3REYXRhLk9QRVJBVE9SLmFjY291bnRJZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnYW4gaW5pdCB0cmFuc2FjdGlvbiB3aXRoIGV4dGVybmFsIHNpZ25hdHVyZSBpbmNsdWRlZCB0d2ljZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAwMDAwMDAwMCcgfSk7XG4gICAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIxKTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjIpO1xuICAgICAgdHhCdWlsZGVyLm93bmVyKHRlc3REYXRhLk9XTkVSMyk7XG4gICAgICB0eEJ1aWxkZXIuc291cmNlKHsgYWRkcmVzczogdGVzdERhdGEuT1BFUkFUT1IuYWNjb3VudElkIH0pO1xuICAgICAgdHhCdWlsZGVyLnNpZ25hdHVyZShcbiAgICAgICAgJzIwYmMwMWE2ZGE2NzdiOTk5NzRiMTcyMDRkZTVmZjZmMzRmOGU1OTA0ZjU4ZDZkZjFjZWIzOWI0NzNlNzI5NWRjY2Y2MGZjZWRhZjRmJyArXG4gICAgICAgICAgJ2RjM2Y2YmVmOTNlZGNmYmUyYTdlYzMzY2M5NGM4OTM5MDZhMDYzMzgzYzI3YjAxNGYwOScsXG4gICAgICAgIG5ldyBLZXlQYWlyKHsgcHViOiB0ZXN0RGF0YS5BQ0NPVU5UXzEucHViS2V5V2l0aFByZWZpeCB9KVxuICAgICAgKTtcbiAgICAgIHR4QnVpbGRlci5zaWduYXR1cmUoXG4gICAgICAgICcyMGJjMDFhNmRhNjc3Yjk5OTc0YjE3MjA0ZGU1ZmY2ZjM0ZjhlNTkwNGY1OGQ2ZGYxY2ViMzliNDczZTcyOTVkY2NmNjBmY2VkYWY0ZicgK1xuICAgICAgICAgICdkYzNmNmJlZjkzZWRjZmJlMmE3ZWMzM2NjOTRjODkzOTA2YTA2MzM4M2MyN2IwMTRmMDknLFxuICAgICAgICBuZXcgS2V5UGFpcih7IHB1YjogdGVzdERhdGEuQUNDT1VOVF8xLnB1YktleVdpdGhQcmVmaXggfSlcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eEpzb24uZnJvbSwgdGVzdERhdGEuT1BFUkFUT1IuYWNjb3VudElkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Nob3VsZCBmYWlsIHRvIGJ1aWxkJywgKCkgPT4ge1xuICAgIGl0KCdhIHRyYW5zYWN0aW9uIHdpdGhvdXQgZmVlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjEpO1xuICAgICAgdHhCdWlsZGVyLm93bmVyKHRlc3REYXRhLk9XTkVSMik7XG4gICAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIzKTtcbiAgICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiB0ZXN0RGF0YS5PUEVSQVRPUi5hY2NvdW50SWQgfSk7XG4gICAgICBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIGZlZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2Egd2FsbGV0IGluaXRpYWxpemF0aW9uIHRoZSB3cm9uZyBudW1iZXIgb2Ygb3duZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMDAwMDAwMDAwJyB9KTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjEpO1xuICAgICAgdHhCdWlsZGVyLm93bmVyKHRlc3REYXRhLk9XTkVSMik7XG4gICAgICB0eEJ1aWxkZXIuc291cmNlKHsgYWRkcmVzczogdGVzdERhdGEuT1BFUkFUT1IuYWNjb3VudElkIH0pO1xuICAgICAgYXdhaXQgdHhCdWlsZGVyXG4gICAgICAgIC5idWlsZCgpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiB3cm9uZyBudW1iZXIgb2Ygb3duZXJzIC0tIHJlcXVpcmVkOiAzLCBmb3VuZDogMicpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjEpLCBuZXcgUmVnRXhwKCdSZXBlYXRlZCBvd25lciBhZGRyZXNzOiAnICsgdGVzdERhdGEuT1dORVIxKSk7XG5cbiAgICAgIGNvbnN0IG5ld1R4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICBuZXdUeEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAwMDAwMDAwMCcgfSk7XG4gICAgICBuZXdUeEJ1aWxkZXIuc291cmNlKHsgYWRkcmVzczogdGVzdERhdGEuT1BFUkFUT1IuYWNjb3VudElkIH0pO1xuICAgICAgYXdhaXQgbmV3VHhCdWlsZGVyXG4gICAgICAgIC5idWlsZCgpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiB3cm9uZyBudW1iZXIgb2Ygb3duZXJzIC0tIHJlcXVpcmVkOiAzLCBmb3VuZDogMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2EgdHJhbnNhY3Rpb24gd2l0aCBpbnZhbGlkIHNvdXJjZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBnZXRCdWlsZGVyRmFjdG9yeSgndGhiYXInKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICB0eEJ1aWxkZXIuZmVlKHsgZmVlOiAnMTAwMDAwMDAwMCcgfSk7XG4gICAgICB0eEJ1aWxkZXIub3duZXIodGVzdERhdGEuT1dORVIxKTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjIpO1xuICAgICAgdHhCdWlsZGVyLm93bmVyKHRlc3REYXRhLk9XTkVSMyk7XG4gICAgICBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIHNvdXJjZScpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hvdWxkIHZhbGlkYXRlJywgKCkgPT4ge1xuICAgIGl0KCdhbiBhZGRyZXNzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIHR4QnVpbGRlci52YWxpZGF0ZUFkZHJlc3ModGVzdERhdGEuVkFMSURfQUREUkVTUyk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVBZGRyZXNzKHRlc3REYXRhLklOVkFMSURfQUREUkVTUyksXG4gICAgICAgIG5ldyBSZWdFeHAoJ0ludmFsaWQgYWRkcmVzcyAnICsgdGVzdERhdGEuSU5WQUxJRF9BRERSRVNTLmFkZHJlc3MpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3ZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gemVybycsICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4QnVpbGRlci5mZWUoeyBmZWU6ICctMTAnIH0pKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHhCdWlsZGVyLmZlZSh7IGZlZTogJzEwJyB9KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnYSBwcml2YXRlIGtleScsICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZUtleSh7IGtleTogJ2FiYycgfSksIC9JbnZhbGlkIHByaXZhdGUga2V5IGxlbmd0aC8pO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVLZXkoeyBrZXk6IHRlc3REYXRhLkFDQ09VTlRfMS5wcnZLZXlXaXRoUHJlZml4IH0pKTtcbiAgICB9KTtcblxuICAgIGl0KCdhIHJhdyB0cmFuc2FjdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHRlc3REYXRhLldBTExFVF9JTklUSUFMSVpBVElPTikpO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbignMHgwMDAwMTAwMCcpKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oJycpKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oJ3BxcnMnKSk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKDEyMzQpKTtcbiAgICB9KTtcblxuICAgIGl0KCdhIHRyYW5zYWN0aW9uIHRvIGJ1aWxkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdHhCdWlsZGVyLnZhbGlkYXRlVHJhbnNhY3Rpb24oKSwgL0ludmFsaWQgdHJhbnNhY3Rpb246IHdyb25nIG51bWJlciBvZiBvd25lcnMvKTtcbiAgICAgIHR4QnVpbGRlci5mZWUoeyBmZWU6ICcxMCcgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHR4QnVpbGRlci52YWxpZGF0ZVRyYW5zYWN0aW9uKCksIC9JbnZhbGlkIHRyYW5zYWN0aW9uOiB3cm9uZyBudW1iZXIgb2Ygb3duZXJzLyk7XG4gICAgICB0eEJ1aWxkZXIuc291cmNlKHRlc3REYXRhLlZBTElEX0FERFJFU1MpO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVUcmFuc2FjdGlvbigpLCAvd3JvbmcgbnVtYmVyIG9mIG93bmVycyAtLSByZXF1aXJlZDogMywgZm91bmQ6IDAvKTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjEpO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVUcmFuc2FjdGlvbigpLCAvd3JvbmcgbnVtYmVyIG9mIG93bmVycyAtLSByZXF1aXJlZDogMywgZm91bmQ6IDEvKTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjIpO1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVUcmFuc2FjdGlvbigpLCAvd3JvbmcgbnVtYmVyIG9mIG93bmVycyAtLSByZXF1aXJlZDogMywgZm91bmQ6IDIvKTtcbiAgICAgIHR4QnVpbGRlci5vd25lcih0ZXN0RGF0YS5PV05FUjMpO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIudmFsaWRhdGVUcmFuc2FjdGlvbigpKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../test/unit/utils.ts"],"names":[],"mappings":""}
@@ -0,0 +1,275 @@
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 assert_1 = __importDefault(require("assert"));
40
+ const should_1 = __importDefault(require("should"));
41
+ const stellar = __importStar(require("stellar-sdk"));
42
+ const Utils = __importStar(require("../../src/lib/utils"));
43
+ const testData = __importStar(require("../resources/hbar"));
44
+ const sdk_core_1 = require("@bitgo/sdk-core");
45
+ describe('HBAR util library', function () {
46
+ describe('address', function () {
47
+ it('should validate addresses', function () {
48
+ const validAddresses = ['0', '0.0.0', '99.99.99', '0.0.41098'];
49
+ const validAddressesWithMemo = ['0.0.41098?memoId=4'];
50
+ for (const address of validAddresses) {
51
+ Utils.isValidAddress(address).should.be.true();
52
+ }
53
+ for (const address of validAddressesWithMemo) {
54
+ Utils.isValidAddress(address).should.be.true();
55
+ }
56
+ });
57
+ it('should fail to validate invalid addresses', function () {
58
+ const invalidAddresses = ['0.0', '0.0.0.0', 'abc', 'a.b.c', '', '0x23C3E227BE97281A70A549c7dDB8d5Caad3E7C84'];
59
+ const invalidAddressesWithMemo = ['0.0.41098?memoId=m?memoId=4'];
60
+ for (const address of invalidAddresses) {
61
+ should_1.default.doesNotThrow(() => Utils.isValidAddress(address));
62
+ Utils.isValidAddress(address).should.be.false();
63
+ }
64
+ for (const address of invalidAddressesWithMemo) {
65
+ should_1.default.doesNotThrow(() => Utils.isValidAddress(address));
66
+ Utils.isValidAddress(address).should.be.false();
67
+ }
68
+ });
69
+ });
70
+ describe('transaction id', function () {
71
+ it('should validate tx ids', function () {
72
+ const validHashes = ['0.0.14621@1595374723.356981689'];
73
+ for (const hash of validHashes) {
74
+ Utils.isValidTransactionId(hash).should.be.true();
75
+ }
76
+ });
77
+ it('should fail to validate invalid tx ids', function () {
78
+ const invalidHashes = ['0.0.14621', 'invalid', ''];
79
+ for (const hash of invalidHashes) {
80
+ Utils.isValidTransactionId(hash).should.be.false();
81
+ }
82
+ });
83
+ });
84
+ describe('transaction timestamp', function () {
85
+ it('should validate tx timestamps', function () {
86
+ const validTimestamps = ['1595374723.356981689', '1595374723'];
87
+ for (const timestamp of validTimestamps) {
88
+ Utils.isValidTimeString(timestamp).should.be.true();
89
+ }
90
+ });
91
+ it('should fail to validate invalid tx timestamp', function () {
92
+ const invalidTimestamp = ['0.0.14621', 'invalid', ''];
93
+ for (const timestamp of invalidTimestamp) {
94
+ Utils.isValidTimeString(timestamp).should.be.false();
95
+ }
96
+ });
97
+ });
98
+ describe('should remove prefix', function () {
99
+ it('from a private key', function () {
100
+ const rawPrivateKey = Utils.removePrefix(testData.ed25519PrivKeyPrefix, testData.ACCOUNT_1.prvKeyWithPrefix);
101
+ should_1.default.deepEqual(rawPrivateKey, '62b0b669de0ab5e91b4328e1431859a5ca47e7426e701019272f5c2d52825b01');
102
+ });
103
+ it('from a public key', function () {
104
+ const rawPublicKey = Utils.removePrefix(testData.ed25519PubKeyPrefix, testData.ACCOUNT_1.pubKeyWithPrefix);
105
+ should_1.default.deepEqual(rawPublicKey, '5a9111b5e6881ff20b9243a42ac1a9a67fa16cd4f01e58bab30c1fe611ea8cf9');
106
+ });
107
+ });
108
+ describe('should convert a stellar pub', function () {
109
+ it('and get back a valid ed pub', function () {
110
+ const stellarPub = 'GBVEZT27ZUCMJABF76XIPPO7M3KUABVR4GZNPBAD3YTPXUSDA57ANRLD';
111
+ const newPub = Utils.convertFromStellarPub(stellarPub);
112
+ should_1.default.equal((0, sdk_core_1.isValidEd25519PublicKey)(newPub), true);
113
+ });
114
+ it('and get back a specific ed pub', function () {
115
+ const stellarPub = 'GBVEZT27ZUCMJABF76XIPPO7M3KUABVR4GZNPBAD3YTPXUSDA57ANRLD';
116
+ const newPub = Utils.convertFromStellarPub(stellarPub);
117
+ newPub.should.equal('6a4ccf5fcd04c48025ffae87bddf66d54006b1e1b2d78403de26fbd243077e06');
118
+ });
119
+ it('and create a valid ed pub that can be transformed back into a stellar pub', function () {
120
+ const stellarPub = 'GBVEZT27ZUCMJABF76XIPPO7M3KUABVR4GZNPBAD3YTPXUSDA57ANRLD';
121
+ const newPub = Utils.convertFromStellarPub(stellarPub);
122
+ const stellarDecoded = stellar.StrKey.encodeEd25519PublicKey(Buffer.from(newPub, 'hex'));
123
+ const beginStellarKeyPair = stellar.Keypair.fromPublicKey(stellarPub);
124
+ const endStellarKeyPair = stellar.Keypair.fromPublicKey(stellarDecoded);
125
+ should_1.default.equal(beginStellarKeyPair.publicKey(), endStellarKeyPair.publicKey());
126
+ });
127
+ });
128
+ describe('should return the same key', function () {
129
+ it('from a private key without the prefix', function () {
130
+ const rawPrivateKey = Utils.removePrefix(testData.ed25519PrivKeyPrefix, testData.ACCOUNT_2.privateKey);
131
+ should_1.default.deepEqual(rawPrivateKey, testData.ACCOUNT_2.privateKey);
132
+ });
133
+ it('from a public key without the prefix', function () {
134
+ const rawPublicKey = Utils.removePrefix(testData.ed25519PubKeyPrefix, testData.ACCOUNT_2.publicKey);
135
+ should_1.default.deepEqual(rawPublicKey, testData.ACCOUNT_2.publicKey);
136
+ });
137
+ it('from a public key with chars of prefix in the middle', function () {
138
+ const publicKey = '592a4fbb7263c59d450e651d' + testData.ed25519PubKeyPrefix + 'f96620dc9208ee7c';
139
+ const rawPublicKey = Utils.removePrefix(testData.ed25519PubKeyPrefix, publicKey);
140
+ should_1.default.deepEqual(rawPublicKey, publicKey);
141
+ });
142
+ it('from a private key with chars of prefix in the middle', function () {
143
+ const privateKey = '5bb72603f237c099' + testData.ed25519PrivKeyPrefix + '3f7973d37fdade3c';
144
+ const rawPrivateKey = Utils.removePrefix(testData.ed25519PrivKeyPrefix, privateKey);
145
+ should_1.default.deepEqual(rawPrivateKey, privateKey);
146
+ });
147
+ });
148
+ describe('getAddressDetails', function () {
149
+ it('should get memoId and address', async function () {
150
+ const addr = '0.0.41098?memoId=23233';
151
+ const details = Utils.getAddressDetails(addr);
152
+ details.address.should.equal('0.0.41098');
153
+ details.memoId?.should.equal('23233');
154
+ });
155
+ it('should throw when memoId=null', async function () {
156
+ const addr = '0.0.41098?memoId=';
157
+ assert_1.default.throws(() => Utils.getAddressDetails(addr), /invalid address: '0.0.41098\?memoId=', memoId is not valid/);
158
+ });
159
+ it('should get memoId and address when no memoId', async function () {
160
+ const addr = '0.0.41098';
161
+ const details = Utils.getAddressDetails(addr);
162
+ details.address.should.equal('0.0.41098');
163
+ details.memoId?.should.equal(undefined);
164
+ });
165
+ });
166
+ describe('normalizeAddress', function () {
167
+ it('should build without a memoId if its missing for an address', async function () {
168
+ const address = '0.0.41098';
169
+ let memoId = undefined;
170
+ let norm = Utils.normalizeAddress({ address, memoId });
171
+ norm.should.equal('0.0.41098');
172
+ memoId = '';
173
+ norm = Utils.normalizeAddress({ address, memoId });
174
+ norm.should.equal('0.0.41098');
175
+ });
176
+ });
177
+ describe('getBaseAddress', function () {
178
+ it('should return the base address', async function () {
179
+ const addressWithMemo = '0.0.41098?memoId=1';
180
+ const baseAddress = '0.0.41098';
181
+ Utils.getBaseAddress(addressWithMemo).should.equal(baseAddress);
182
+ Utils.getBaseAddress(baseAddress).should.equal(baseAddress);
183
+ });
184
+ });
185
+ describe('isSameBaseAddress', function () {
186
+ it('should validate if base address match', async function () {
187
+ const address = '0.0.41098?memoId=1';
188
+ const baseAddress = '0.0.41098';
189
+ Utils.isSameBaseAddress(address, baseAddress).should.true();
190
+ const address2 = '0.0.41098';
191
+ const baseAddress2 = '0.0.41098';
192
+ Utils.isSameBaseAddress(address2, baseAddress2).should.true();
193
+ const address3 = '0.0.41099?memoId=1';
194
+ const baseAddress3 = '0.0.41098';
195
+ Utils.isSameBaseAddress(address3, baseAddress3).should.false();
196
+ const address4 = '0.0.41099';
197
+ const baseAddress4 = '0.0.41098';
198
+ Utils.isSameBaseAddress(address4, baseAddress4).should.false();
199
+ const address5 = '0.0.0.0';
200
+ const baseAddress5 = '0.0.41098';
201
+ assert_1.default.throws(() => Utils.isSameBaseAddress(address5, baseAddress5).should.false(), new RegExp(`invalid address: ${address5}`));
202
+ });
203
+ });
204
+ describe('isValidMemoId', function () {
205
+ it('should validate memoId', async function () {
206
+ const memo1 = 'testmemo';
207
+ Utils.isValidMemo(memo1).should.true();
208
+ const memo2 = '';
209
+ Utils.isValidMemo(memo2).should.false();
210
+ const memo3 = undefined;
211
+ // @ts-expect-error testing for error
212
+ Utils.isValidMemo(memo3).should.false();
213
+ const memo4 = 'memoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo';
214
+ Utils.isValidMemo(memo4).should.false();
215
+ });
216
+ });
217
+ describe('isValidAddressWithPaymentId', function () {
218
+ it('should validate addresses with and without payment id', function () {
219
+ const validAddresses = ['0', '0.0.0', '99.99.99', '0.0.41098', '0.0.41098?memoId=4'];
220
+ for (const address of validAddresses) {
221
+ Utils.isValidAddressWithPaymentId(address).should.be.true();
222
+ }
223
+ });
224
+ it('should fail to validate invalid addresses', function () {
225
+ const invalidAddresses = [
226
+ '0.0.41098?memoId=memooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo',
227
+ '0.0.41098?memoId=',
228
+ '0.0',
229
+ '0.0.0.0',
230
+ 'abc',
231
+ 'a.b.c',
232
+ '',
233
+ '0x23C3E227BE97281A70A549c7dDB8d5Caad3E7C84',
234
+ ];
235
+ for (const address of invalidAddresses) {
236
+ Utils.isValidAddressWithPaymentId(address).should.be.false();
237
+ }
238
+ });
239
+ });
240
+ describe('shouldBroadcastNow', function () {
241
+ const getTimestampInSeconds = (secondsToChange = 0) => (Date.now() / 1000 + secondsToChange).toFixed();
242
+ it('should return true if the timestamp is in the valid time window', function () {
243
+ const timestamp = getTimestampInSeconds(-6);
244
+ Utils.shouldBroadcastNow(timestamp).should.be.true();
245
+ const timestamp2 = getTimestampInSeconds(-173);
246
+ Utils.shouldBroadcastNow(timestamp2).should.be.true();
247
+ });
248
+ it('should throw if the timestamp is in the past', function () {
249
+ const timestamp = getTimestampInSeconds(-1000);
250
+ assert_1.default.throws(() => Utils.shouldBroadcastNow(timestamp), (error) => {
251
+ assert_1.default.ok(error.message.includes('startTime window expired'));
252
+ return true;
253
+ });
254
+ });
255
+ it('should return false if the timestamp is in the future', function () {
256
+ const timestamp = getTimestampInSeconds(1000);
257
+ Utils.shouldBroadcastNow(timestamp).should.be.false();
258
+ });
259
+ });
260
+ describe('normalizeStarttime', function () {
261
+ it('should return the same timestamp', function () {
262
+ const timestamp = '1595374723.356981689';
263
+ Utils.normalizeStarttime(timestamp).should.equal(timestamp);
264
+ });
265
+ it('should return the timestamp with nanoseconds', function () {
266
+ const timestamp = '1595374723';
267
+ Utils.normalizeStarttime(timestamp).should.equal(timestamp + '.000000000');
268
+ });
269
+ it('should return the timestamp with nanoseconds', function () {
270
+ const timestamp = '1595374723.0145';
271
+ Utils.normalizeStarttime(timestamp).should.equal(timestamp + '00000');
272
+ });
273
+ });
274
+ });
275
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsb0RBQTRCO0FBQzVCLHFEQUF1QztBQUN2QywyREFBNkM7QUFDN0MsNERBQThDO0FBQzlDLDhDQUEwRDtBQUUxRCxRQUFRLENBQUMsbUJBQW1CLEVBQUU7SUFDNUIsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUMsMkJBQTJCLEVBQUU7WUFDOUIsTUFBTSxjQUFjLEdBQUcsQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztZQUMvRCxNQUFNLHNCQUFzQixHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUV0RCxLQUFLLE1BQU0sT0FBTyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNyQyxLQUFLLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDakQsQ0FBQztZQUVELEtBQUssTUFBTSxPQUFPLElBQUksc0JBQXNCLEVBQUUsQ0FBQztnQkFDN0MsS0FBSyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pELENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyQ0FBMkMsRUFBRTtZQUM5QyxNQUFNLGdCQUFnQixHQUFHLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSw0Q0FBNEMsQ0FBQyxDQUFDO1lBQzlHLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBRWpFLEtBQUssTUFBTSxPQUFPLElBQUksZ0JB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RixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUU7WUFDMUQsTUFBTSxTQUFTLEdBQUcscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxvQkFBb0IsRUFBRTtRQUM3QixFQUFFLENBQUMsa0NBQWtDLEVBQUU7WUFDckMsTUFBTSxTQUFTLEdBQUcsc0JBQXNCLENBQUM7WUFDekMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOENBQThDLEVBQUU7WUFDakQsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDO1lBQy9CLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxZQUFZLENBQUMsQ0FBQztRQUM3RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxNQUFNLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQztZQUNwQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0ICogYXMgc3RlbGxhciBmcm9tICdzdGVsbGFyLXNkayc7XG5pbXBvcnQgKiBhcyBVdGlscyBmcm9tICcuLi8uLi9zcmMvbGliL3V0aWxzJztcbmltcG9ydCAqIGFzIHRlc3REYXRhIGZyb20gJy4uL3Jlc291cmNlcy9oYmFyJztcbmltcG9ydCB7IGlzVmFsaWRFZDI1NTE5UHVibGljS2V5IH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcblxuZGVzY3JpYmUoJ0hCQVIgdXRpbCBsaWJyYXJ5JywgZnVuY3Rpb24gKCkge1xuICBkZXNjcmliZSgnYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkQWRkcmVzc2VzID0gWycwJywgJzAuMC4wJywgJzk5Ljk5Ljk5JywgJzAuMC40MTA5OCddO1xuICAgICAgY29uc3QgdmFsaWRBZGRyZXNzZXNXaXRoTWVtbyA9IFsnMC4wLjQxMDk4P21lbW9JZD00J107XG5cbiAgICAgIGZvciAoY29uc3QgYWRkcmVzcyBvZiB2YWxpZEFkZHJlc3Nlcykge1xuICAgICAgICBVdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGFkZHJlc3Mgb2YgdmFsaWRBZGRyZXNzZXNXaXRoTWVtbykge1xuICAgICAgICBVdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZhbGlkYXRlIGludmFsaWQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEFkZHJlc3NlcyA9IFsnMC4wJywgJzAuMC4wLjAnLCAnYWJjJywgJ2EuYi5jJywgJycsICcweDIzQzNFMjI3QkU5NzI4MUE3MEE1NDljN2REQjhkNUNhYWQzRTdDODQnXTtcbiAgICAgIGNvbnN0IGludmFsaWRBZGRyZXNzZXNXaXRoTWVtbyA9IFsnMC4wLjQxMDk4P21lbW9JZD1tP21lbW9JZD00J107XG5cbiAgICAgIGZvciAoY29uc3QgYWRkcmVzcyBvZiBpbnZhbGlkQWRkcmVzc2VzKSB7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gVXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykpO1xuICAgICAgICBVdGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGludmFsaWRBZGRyZXNzZXNXaXRoTWVtbykge1xuICAgICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IFV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpKTtcbiAgICAgICAgVXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd0cmFuc2FjdGlvbiBpZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHR4IGlkcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkSGFzaGVzID0gWycwLjAuMTQ2MjFAMTU5NTM3NDcyMy4zNTY5ODE2ODknXTtcblxuICAgICAgZm9yIChjb25zdCBoYXNoIG9mIHZhbGlkSGFzaGVzKSB7XG4gICAgICAgIFV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKGhhc2gpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmFsaWRhdGUgaW52YWxpZCB0eCBpZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkSGFzaGVzID0gWycwLjAuMTQ2MjEnLCAnaW52YWxpZCcsICcnXTtcblxuICAgICAgZm9yIChjb25zdCBoYXNoIG9mIGludmFsaWRIYXNoZXMpIHtcbiAgICAgICAgVXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSWQoaGFzaCkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd0cmFuc2FjdGlvbiB0aW1lc3RhbXAnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSB0eCB0aW1lc3RhbXBzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmFsaWRUaW1lc3RhbXBzID0gWycxNTk1Mzc0NzIzLjM1Njk4MTY4OScsICcxNTk1Mzc0NzIzJ107XG5cbiAgICAgIGZvciAoY29uc3QgdGltZXN0YW1wIG9mIHZhbGlkVGltZXN0YW1wcykge1xuICAgICAgICBVdGlscy5pc1ZhbGlkVGltZVN0cmluZyh0aW1lc3RhbXApLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmFsaWRhdGUgaW52YWxpZCB0eCB0aW1lc3RhbXAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkVGltZXN0YW1wID0gWycwLjAuMTQ2MjEnLCAnaW52YWxpZCcsICcnXTtcblxuICAgICAgZm9yIChjb25zdCB0aW1lc3RhbXAgb2YgaW52YWxpZFRpbWVzdGFtcCkge1xuICAgICAgICBVdGlscy5pc1ZhbGlkVGltZVN0cmluZyh0aW1lc3RhbXApLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hvdWxkIHJlbW92ZSBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2Zyb20gYSBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1ByaXZhdGVLZXkgPSBVdGlscy5yZW1vdmVQcmVmaXgodGVzdERhdGEuZWQyNTUxOVByaXZLZXlQcmVmaXgsIHRlc3REYXRhLkFDQ09VTlRfMS5wcnZLZXlXaXRoUHJlZml4KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwocmF3UHJpdmF0ZUtleSwgJzYyYjBiNjY5ZGUwYWI1ZTkxYjQzMjhlMTQzMTg1OWE1Y2E0N2U3NDI2ZTcwMTAxOTI3MmY1YzJkNTI4MjViMDEnKTtcbiAgICB9KTtcblxuICAgIGl0KCdmcm9tIGEgcHVibGljIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1B1YmxpY0tleSA9IFV0aWxzLnJlbW92ZVByZWZpeCh0ZXN0RGF0YS5lZDI1NTE5UHViS2V5UHJlZml4LCB0ZXN0RGF0YS5BQ0NPVU5UXzEucHViS2V5V2l0aFByZWZpeCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJhd1B1YmxpY0tleSwgJzVhOTExMWI1ZTY4ODFmZjIwYjkyNDNhNDJhYzFhOWE2N2ZhMTZjZDRmMDFlNThiYWIzMGMxZmU2MTFlYThjZjknKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Nob3VsZCBjb252ZXJ0IGEgc3RlbGxhciBwdWInLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2FuZCBnZXQgYmFjayBhIHZhbGlkIGVkIHB1YicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0ZWxsYXJQdWIgPSAnR0JWRVpUMjdaVUNNSkFCRjc2WElQUE83TTNLVUFCVlI0R1pOUEJBRDNZVFBYVVNEQTU3QU5STEQnO1xuICAgICAgY29uc3QgbmV3UHViID0gVXRpbHMuY29udmVydEZyb21TdGVsbGFyUHViKHN0ZWxsYXJQdWIpO1xuICAgICAgc2hvdWxkLmVxdWFsKGlzVmFsaWRFZDI1NTE5UHVibGljS2V5KG5ld1B1YiksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FuZCBnZXQgYmFjayBhIHNwZWNpZmljIGVkIHB1YicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0ZWxsYXJQdWIgPSAnR0JWRVpUMjdaVUNNSkFCRjc2WElQUE83TTNLVUFCVlI0R1pOUEJBRDNZVFBYVVNEQTU3QU5STEQnO1xuICAgICAgY29uc3QgbmV3UHViID0gVXRpbHMuY29udmVydEZyb21TdGVsbGFyUHViKHN0ZWxsYXJQdWIpO1xuICAgICAgbmV3UHViLnNob3VsZC5lcXVhbCgnNmE0Y2NmNWZjZDA0YzQ4MDI1ZmZhZTg3YmRkZjY2ZDU0MDA2YjFlMWIyZDc4NDAzZGUyNmZiZDI0MzA3N2UwNicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FuZCBjcmVhdGUgYSB2YWxpZCBlZCBwdWIgdGhhdCBjYW4gYmUgdHJhbnNmb3JtZWQgYmFjayBpbnRvIGEgc3RlbGxhciBwdWInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdGVsbGFyUHViID0gJ0dCVkVaVDI3WlVDTUpBQkY3NlhJUFBPN00zS1VBQlZSNEdaTlBCQUQzWVRQWFVTREE1N0FOUkxEJztcblxuICAgICAgY29uc3QgbmV3UHViID0gVXRpbHMuY29udmVydEZyb21TdGVsbGFyUHViKHN0ZWxsYXJQdWIpO1xuICAgICAgY29uc3Qgc3RlbGxhckRlY29kZWQgPSBzdGVsbGFyLlN0cktleS5lbmNvZGVFZDI1NTE5UHVibGljS2V5KEJ1ZmZlci5mcm9tKG5ld1B1YiwgJ2hleCcpKTtcbiAgICAgIGNvbnN0IGJlZ2luU3RlbGxhcktleVBhaXIgPSBzdGVsbGFyLktleXBhaXIuZnJvbVB1YmxpY0tleShzdGVsbGFyUHViKTtcbiAgICAgIGNvbnN0IGVuZFN0ZWxsYXJLZXlQYWlyID0gc3RlbGxhci5LZXlwYWlyLmZyb21QdWJsaWNLZXkoc3RlbGxhckRlY29kZWQpO1xuXG4gICAgICBzaG91bGQuZXF1YWwoYmVnaW5TdGVsbGFyS2V5UGFpci5wdWJsaWNLZXkoKSwgZW5kU3RlbGxhcktleVBhaXIucHVibGljS2V5KCkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hvdWxkIHJldHVybiB0aGUgc2FtZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2Zyb20gYSBwcml2YXRlIGtleSB3aXRob3V0IHRoZSBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByYXdQcml2YXRlS2V5ID0gVXRpbHMucmVtb3ZlUHJlZml4KHRlc3REYXRhLmVkMjU1MTlQcml2S2V5UHJlZml4LCB0ZXN0RGF0YS5BQ0NPVU5UXzIucHJpdmF0ZUtleSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJhd1ByaXZhdGVLZXksIHRlc3REYXRhLkFDQ09VTlRfMi5wcml2YXRlS2V5KTtcbiAgICB9KTtcblxuICAgIGl0KCdmcm9tIGEgcHVibGljIGtleSB3aXRob3V0IHRoZSBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByYXdQdWJsaWNLZXkgPSBVdGlscy5yZW1vdmVQcmVmaXgodGVzdERhdGEuZWQyNTUxOVB1YktleVByZWZpeCwgdGVzdERhdGEuQUNDT1VOVF8yLnB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHJhd1B1YmxpY0tleSwgdGVzdERhdGEuQUNDT1VOVF8yLnB1YmxpY0tleSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZnJvbSBhIHB1YmxpYyBrZXkgd2l0aCBjaGFycyBvZiBwcmVmaXggaW4gdGhlIG1pZGRsZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9ICc1OTJhNGZiYjcyNjNjNTlkNDUwZTY1MWQnICsgdGVzdERhdGEuZWQyNTUxOVB1YktleVByZWZpeCArICdmOTY2MjBkYzkyMDhlZTdjJztcbiAgICAgIGNvbnN0IHJhd1B1YmxpY0tleSA9IFV0aWxzLnJlbW92ZVByZWZpeCh0ZXN0RGF0YS5lZDI1NTE5UHViS2V5UHJlZml4LCBwdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChyYXdQdWJsaWNLZXksIHB1YmxpY0tleSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZnJvbSBhIHByaXZhdGUga2V5IHdpdGggY2hhcnMgb2YgcHJlZml4IGluIHRoZSBtaWRkbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gJzViYjcyNjAzZjIzN2MwOTknICsgdGVzdERhdGEuZWQyNTUxOVByaXZLZXlQcmVmaXggKyAnM2Y3OTczZDM3ZmRhZGUzYyc7XG4gICAgICBjb25zdCByYXdQcml2YXRlS2V5ID0gVXRpbHMucmVtb3ZlUHJlZml4KHRlc3REYXRhLmVkMjU1MTlQcml2S2V5UHJlZml4LCBwcml2YXRlS2V5KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwocmF3UHJpdmF0ZUtleSwgcHJpdmF0ZUtleSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdnZXRBZGRyZXNzRGV0YWlscycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGdldCBtZW1vSWQgYW5kIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyID0gJzAuMC40MTA5OD9tZW1vSWQ9MjMyMzMnO1xuICAgICAgY29uc3QgZGV0YWlscyA9IFV0aWxzLmdldEFkZHJlc3NEZXRhaWxzKGFkZHIpO1xuXG4gICAgICBkZXRhaWxzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcwLjAuNDEwOTgnKTtcbiAgICAgIGRldGFpbHMubWVtb0lkPy5zaG91bGQuZXF1YWwoJzIzMjMzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gbWVtb0lkPW51bGwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyID0gJzAuMC40MTA5OD9tZW1vSWQ9JztcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gVXRpbHMuZ2V0QWRkcmVzc0RldGFpbHMoYWRkciksIC9pbnZhbGlkIGFkZHJlc3M6ICcwLjAuNDEwOThcXD9tZW1vSWQ9JywgbWVtb0lkIGlzIG5vdCB2YWxpZC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgbWVtb0lkIGFuZCBhZGRyZXNzIHdoZW4gbm8gbWVtb0lkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkciA9ICcwLjAuNDEwOTgnO1xuICAgICAgY29uc3QgZGV0YWlscyA9IFV0aWxzLmdldEFkZHJlc3NEZXRhaWxzKGFkZHIpO1xuXG4gICAgICBkZXRhaWxzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcwLjAuNDEwOTgnKTtcbiAgICAgIGRldGFpbHMubWVtb0lkPy5zaG91bGQuZXF1YWwodW5kZWZpbmVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ25vcm1hbGl6ZUFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBidWlsZCB3aXRob3V0IGEgbWVtb0lkIGlmIGl0cyBtaXNzaW5nIGZvciBhbiBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcwLjAuNDEwOTgnO1xuICAgICAgbGV0IG1lbW9JZDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgbGV0IG5vcm0gPSBVdGlscy5ub3JtYWxpemVBZGRyZXNzKHsgYWRkcmVzcywgbWVtb0lkIH0pO1xuICAgICAgbm9ybS5zaG91bGQuZXF1YWwoJzAuMC40MTA5OCcpO1xuICAgICAgbWVtb0lkID0gJyc7XG4gICAgICBub3JtID0gVXRpbHMubm9ybWFsaXplQWRkcmVzcyh7IGFkZHJlc3MsIG1lbW9JZCB9KTtcbiAgICAgIG5vcm0uc2hvdWxkLmVxdWFsKCcwLjAuNDEwOTgnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldEJhc2VBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBiYXNlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzV2l0aE1lbW8gPSAnMC4wLjQxMDk4P21lbW9JZD0xJztcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gJzAuMC40MTA5OCc7XG4gICAgICBVdGlscy5nZXRCYXNlQWRkcmVzcyhhZGRyZXNzV2l0aE1lbW8pLnNob3VsZC5lcXVhbChiYXNlQWRkcmVzcyk7XG4gICAgICBVdGlscy5nZXRCYXNlQWRkcmVzcyhiYXNlQWRkcmVzcykuc2hvdWxkLmVxdWFsKGJhc2VBZGRyZXNzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzU2FtZUJhc2VBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgaWYgYmFzZSBhZGRyZXNzIG1hdGNoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICcwLjAuNDEwOTg/bWVtb0lkPTEnO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMC4wLjQxMDk4JztcbiAgICAgIFV0aWxzLmlzU2FtZUJhc2VBZGRyZXNzKGFkZHJlc3MsIGJhc2VBZGRyZXNzKS5zaG91bGQudHJ1ZSgpO1xuXG4gICAgICBjb25zdCBhZGRyZXNzMiA9ICcwLjAuNDEwOTgnO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MyID0gJzAuMC40MTA5OCc7XG4gICAgICBVdGlscy5pc1NhbWVCYXNlQWRkcmVzcyhhZGRyZXNzMiwgYmFzZUFkZHJlc3MyKS5zaG91bGQudHJ1ZSgpO1xuXG4gICAgICBjb25zdCBhZGRyZXNzMyA9ICcwLjAuNDEwOTk/bWVtb0lkPTEnO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MzID0gJzAuMC40MTA5OCc7XG4gICAgICBVdGlscy5pc1NhbWVCYXNlQWRkcmVzcyhhZGRyZXNzMywgYmFzZUFkZHJlc3MzKS5zaG91bGQuZmFsc2UoKTtcblxuICAgICAgY29uc3QgYWRkcmVzczQgPSAnMC4wLjQxMDk5JztcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzNCA9ICcwLjAuNDEwOTgnO1xuICAgICAgVXRpbHMuaXNTYW1lQmFzZUFkZHJlc3MoYWRkcmVzczQsIGJhc2VBZGRyZXNzNCkuc2hvdWxkLmZhbHNlKCk7XG5cbiAgICAgIGNvbnN0IGFkZHJlc3M1ID0gJzAuMC4wLjAnO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3M1ID0gJzAuMC40MTA5OCc7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBVdGlscy5pc1NhbWVCYXNlQWRkcmVzcyhhZGRyZXNzNSwgYmFzZUFkZHJlc3M1KS5zaG91bGQuZmFsc2UoKSxcbiAgICAgICAgbmV3IFJlZ0V4cChgaW52YWxpZCBhZGRyZXNzOiAke2FkZHJlc3M1fWApXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZE1lbW9JZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIG1lbW9JZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lbW8xID0gJ3Rlc3RtZW1vJztcbiAgICAgIFV0aWxzLmlzVmFsaWRNZW1vKG1lbW8xKS5zaG91bGQudHJ1ZSgpO1xuICAgICAgY29uc3QgbWVtbzIgPSAnJztcbiAgICAgIFV0aWxzLmlzVmFsaWRNZW1vKG1lbW8yKS5zaG91bGQuZmFsc2UoKTtcbiAgICAgIGNvbnN0IG1lbW8zID0gdW5kZWZpbmVkO1xuICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0ZXN0aW5nIGZvciBlcnJvclxuICAgICAgVXRpbHMuaXNWYWxpZE1lbW8obWVtbzMpLnNob3VsZC5mYWxzZSgpO1xuICAgICAgY29uc3QgbWVtbzQgPVxuICAgICAgICAnbWVtb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vJztcbiAgICAgIFV0aWxzLmlzVmFsaWRNZW1vKG1lbW80KS5zaG91bGQuZmFsc2UoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRBZGRyZXNzV2l0aFBheW1lbnRJZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFkZHJlc3NlcyB3aXRoIGFuZCB3aXRob3V0IHBheW1lbnQgaWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZEFkZHJlc3NlcyA9IFsnMCcsICcwLjAuMCcsICc5OS45OS45OScsICcwLjAuNDEwOTgnLCAnMC4wLjQxMDk4P21lbW9JZD00J107XG5cbiAgICAgIGZvciAoY29uc3QgYWRkcmVzcyBvZiB2YWxpZEFkZHJlc3Nlcykge1xuICAgICAgICBVdGlscy5pc1ZhbGlkQWRkcmVzc1dpdGhQYXltZW50SWQoYWRkcmVzcykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byB2YWxpZGF0ZSBpbnZhbGlkIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRBZGRyZXNzZXMgPSBbXG4gICAgICAgICcwLjAuNDEwOTg/bWVtb0lkPW1lbW9vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb29vb28nLFxuICAgICAgICAnMC4wLjQxMDk4P21lbW9JZD0nLFxuICAgICAgICAnMC4wJyxcbiAgICAgICAgJzAuMC4wLjAnLFxuICAgICAgICAnYWJjJyxcbiAgICAgICAgJ2EuYi5jJyxcbiAgICAgICAgJycsXG4gICAgICAgICcweDIzQzNFMjI3QkU5NzI4MUE3MEE1NDljN2REQjhkNUNhYWQzRTdDODQnLFxuICAgICAgXTtcblxuICAgICAgZm9yIChjb25zdCBhZGRyZXNzIG9mIGludmFsaWRBZGRyZXNzZXMpIHtcbiAgICAgICAgVXRpbHMuaXNWYWxpZEFkZHJlc3NXaXRoUGF5bWVudElkKGFkZHJlc3MpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hvdWxkQnJvYWRjYXN0Tm93JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGdldFRpbWVzdGFtcEluU2Vjb25kcyA9IChzZWNvbmRzVG9DaGFuZ2UgPSAwKSA9PiAoRGF0ZS5ub3coKSAvIDEwMDAgKyBzZWNvbmRzVG9DaGFuZ2UpLnRvRml4ZWQoKTtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGlmIHRoZSB0aW1lc3RhbXAgaXMgaW4gdGhlIHZhbGlkIHRpbWUgd2luZG93JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gZ2V0VGltZXN0YW1wSW5TZWNvbmRzKC02KTtcbiAgICAgIFV0aWxzLnNob3VsZEJyb2FkY2FzdE5vdyh0aW1lc3RhbXApLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGNvbnN0IHRpbWVzdGFtcDIgPSBnZXRUaW1lc3RhbXBJblNlY29uZHMoLTE3Myk7XG4gICAgICBVdGlscy5zaG91bGRCcm9hZGNhc3ROb3codGltZXN0YW1wMikuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgdGhlIHRpbWVzdGFtcCBpcyBpbiB0aGUgcGFzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRpbWVzdGFtcCA9IGdldFRpbWVzdGFtcEluU2Vjb25kcygtMTAwMCk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBVdGlscy5zaG91bGRCcm9hZGNhc3ROb3codGltZXN0YW1wKSxcbiAgICAgICAgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICBhc3NlcnQub2soZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnc3RhcnRUaW1lIHdpbmRvdyBleHBpcmVkJykpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgaWYgdGhlIHRpbWVzdGFtcCBpcyBpbiB0aGUgZnV0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gZ2V0VGltZXN0YW1wSW5TZWNvbmRzKDEwMDApO1xuICAgICAgVXRpbHMuc2hvdWxkQnJvYWRjYXN0Tm93KHRpbWVzdGFtcCkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdub3JtYWxpemVTdGFydHRpbWUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHNhbWUgdGltZXN0YW1wJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gJzE1OTUzNzQ3MjMuMzU2OTgxNjg5JztcbiAgICAgIFV0aWxzLm5vcm1hbGl6ZVN0YXJ0dGltZSh0aW1lc3RhbXApLnNob3VsZC5lcXVhbCh0aW1lc3RhbXApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIHRpbWVzdGFtcCB3aXRoIG5hbm9zZWNvbmRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGltZXN0YW1wID0gJzE1OTUzNzQ3MjMnO1xuICAgICAgVXRpbHMubm9ybWFsaXplU3RhcnR0aW1lKHRpbWVzdGFtcCkuc2hvdWxkLmVxdWFsKHRpbWVzdGFtcCArICcuMDAwMDAwMDAwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0aGUgdGltZXN0YW1wIHdpdGggbmFub3NlY29uZHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSAnMTU5NTM3NDcyMy4wMTQ1JztcbiAgICAgIFV0aWxzLm5vcm1hbGl6ZVN0YXJ0dGltZSh0aW1lc3RhbXApLnNob3VsZC5lcXVhbCh0aW1lc3RhbXAgKyAnMDAwMDAnKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==