@bitgo-beta/sdk-coin-flrp 1.0.1-beta.40 → 1.0.1-beta.401

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