@bitgo-beta/sdk-coin-flrp 1.0.1-beta.27 → 1.0.1-beta.271

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 (97) hide show
  1. package/dist/src/flrp.d.ts +6 -75
  2. package/dist/src/flrp.d.ts.map +1 -1
  3. package/dist/src/flrp.js +13 -298
  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 +50 -0
  8. package/dist/src/lib/ExportInCTxBuilder.d.ts.map +1 -0
  9. package/dist/src/lib/ExportInCTxBuilder.js +163 -0
  10. package/dist/src/lib/ExportInPTxBuilder.d.ts +36 -0
  11. package/dist/src/lib/ExportInPTxBuilder.d.ts.map +1 -0
  12. package/dist/src/lib/ExportInPTxBuilder.js +128 -0
  13. package/dist/src/lib/ImportInCTxBuilder.d.ts +47 -0
  14. package/dist/src/lib/ImportInCTxBuilder.d.ts.map +1 -0
  15. package/dist/src/lib/ImportInCTxBuilder.js +213 -0
  16. package/dist/src/lib/ImportInPTxBuilder.d.ts +23 -0
  17. package/dist/src/lib/ImportInPTxBuilder.d.ts.map +1 -0
  18. package/dist/src/lib/ImportInPTxBuilder.js +101 -0
  19. package/dist/src/lib/atomicInCTransactionBuilder.d.ts +18 -16
  20. package/dist/src/lib/atomicInCTransactionBuilder.d.ts.map +1 -1
  21. package/dist/src/lib/atomicInCTransactionBuilder.js +38 -36
  22. package/dist/src/lib/atomicTransactionBuilder.d.ts +34 -81
  23. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
  24. package/dist/src/lib/atomicTransactionBuilder.js +123 -226
  25. package/dist/src/lib/iface.d.ts +50 -51
  26. package/dist/src/lib/iface.d.ts.map +1 -1
  27. package/dist/src/lib/iface.js +22 -10
  28. package/dist/src/lib/index.d.ts +4 -0
  29. package/dist/src/lib/index.d.ts.map +1 -1
  30. package/dist/src/lib/index.js +10 -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 +46 -0
  35. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/permissionlessValidatorTxBuilder.js +134 -0
  37. package/dist/src/lib/transaction.d.ts +8 -74
  38. package/dist/src/lib/transaction.d.ts.map +1 -1
  39. package/dist/src/lib/transaction.js +59 -207
  40. package/dist/src/lib/transactionBuilder.d.ts +107 -0
  41. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  42. package/dist/src/lib/transactionBuilder.js +210 -0
  43. package/dist/src/lib/transactionBuilderFactory.d.ts +27 -30
  44. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  45. package/dist/src/lib/transactionBuilderFactory.js +69 -75
  46. package/dist/src/lib/utils.d.ts +66 -151
  47. package/dist/src/lib/utils.d.ts.map +1 -1
  48. package/dist/src/lib/utils.js +205 -327
  49. package/dist/test/resources/account.d.ts +49 -0
  50. package/dist/test/resources/account.d.ts.map +1 -0
  51. package/dist/test/resources/account.js +52 -0
  52. package/dist/test/resources/transactionData/exportInC.d.ts +20 -0
  53. package/dist/test/resources/transactionData/exportInC.d.ts.map +1 -0
  54. package/dist/test/resources/transactionData/exportInC.js +30 -0
  55. package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
  56. package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
  57. package/dist/test/unit/lib/exportInCTxBuilder.js +163 -0
  58. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  59. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  60. package/dist/test/unit/lib/keyPair.js +158 -0
  61. package/dist/test/unit/lib/utils.js +29 -223
  62. package/dist/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +16 -13
  64. package/.eslintignore +0 -5
  65. package/.eslintrc.json +0 -7
  66. package/.mocharc.yml +0 -8
  67. package/CHANGELOG.md +0 -0
  68. package/dist/src/iface.d.ts +0 -25
  69. package/dist/src/iface.d.ts.map +0 -1
  70. package/dist/src/iface.js +0 -3
  71. package/dist/src/lib/constants.d.ts +0 -11
  72. package/dist/src/lib/constants.d.ts.map +0 -1
  73. package/dist/src/lib/constants.js +0 -17
  74. package/dist/src/lib/errors.d.ts +0 -8
  75. package/dist/src/lib/errors.d.ts.map +0 -1
  76. package/dist/src/lib/errors.js +0 -19
  77. package/dist/src/lib/exportInCTxBuilder.d.ts +0 -77
  78. package/dist/src/lib/exportInCTxBuilder.d.ts.map +0 -1
  79. package/dist/src/lib/exportInCTxBuilder.js +0 -170
  80. package/dist/src/lib/exportInPTxBuilder.d.ts +0 -30
  81. package/dist/src/lib/exportInPTxBuilder.d.ts.map +0 -1
  82. package/dist/src/lib/exportInPTxBuilder.js +0 -56
  83. package/dist/test/unit/flrp.d.ts +0 -2
  84. package/dist/test/unit/flrp.d.ts.map +0 -1
  85. package/dist/test/unit/flrp.js +0 -118
  86. package/dist/test/unit/lib/atomicTransactionBuilder.d.ts +0 -2
  87. package/dist/test/unit/lib/atomicTransactionBuilder.d.ts.map +0 -1
  88. package/dist/test/unit/lib/atomicTransactionBuilder.js +0 -222
  89. package/dist/test/unit/lib/exportTxBuilder.d.ts +0 -2
  90. package/dist/test/unit/lib/exportTxBuilder.d.ts.map +0 -1
  91. package/dist/test/unit/lib/exportTxBuilder.js +0 -45
  92. package/dist/test/unit/lib/transaction.d.ts +0 -2
  93. package/dist/test/unit/lib/transaction.d.ts.map +0 -1
  94. package/dist/test/unit/lib/transaction.js +0 -460
  95. package/dist/test/unit/smoke.d.ts +0 -2
  96. package/dist/test/unit/smoke.d.ts.map +0 -1
  97. package/dist/test/unit/smoke.js +0 -23
@@ -1,27 +1,74 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.Utils = void 0;
7
+ const flarejs_1 = require("@flarenetwork/flarejs");
4
8
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
- const secp256k1_1 = require("@bitgo-beta/secp256k1");
9
+ const buffer_1 = require("buffer");
6
10
  const crypto_1 = require("crypto");
7
- const constants_1 = require("./constants");
11
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
12
+ const iface_1 = require("./iface");
13
+ const bs58_1 = __importDefault(require("bs58"));
14
+ const bech32_1 = require("bech32");
8
15
  class Utils {
9
16
  constructor() {
10
- this.parseAddress = (pub) => {
11
- // FlareJS equivalent for address parsing
12
- return Buffer.from(pub, 'hex'); // Simplified implementation
17
+ /**
18
+ * Helper method to convert address components to string
19
+ */
20
+ this.addressToString = (hrp, prefix, address) => {
21
+ // Convert the address bytes to 5-bit words for bech32 encoding
22
+ const words = bech32_1.bech32.toWords(address);
23
+ // Create the full bech32 address with format: P-{hrp}1{bech32_encoded_address}
24
+ return `${prefix}-${bech32_1.bech32.encode(hrp, words)}`;
25
+ };
26
+ // In utils.ts, add this method to the Utils class:
27
+ /**
28
+ * Parse an address string into a Buffer
29
+ * @param address - The address to parse
30
+ * @returns Buffer containing the parsed address
31
+ */
32
+ //TODO: need check and validate this method
33
+ this.parseAddress = (address) => {
34
+ return this.stringToAddress(address);
35
+ };
36
+ this.stringToAddress = (address, hrp) => {
37
+ // Handle hex addresses
38
+ if (address.startsWith('0x')) {
39
+ return buffer_1.Buffer.from(address.slice(2), 'hex');
40
+ }
41
+ // Handle raw hex without 0x prefix
42
+ if (/^[0-9a-fA-F]{40}$/.test(address)) {
43
+ return buffer_1.Buffer.from(address, 'hex');
44
+ }
45
+ // Handle Bech32 addresses
46
+ const parts = address.trim().split('-');
47
+ if (parts.length < 2) {
48
+ throw new Error('Error - Valid address should include -');
49
+ }
50
+ const split = parts[1].lastIndexOf('1');
51
+ if (split < 0) {
52
+ throw new Error('Error - Valid bech32 address must include separator (1)');
53
+ }
54
+ const humanReadablePart = parts[1].slice(0, split);
55
+ if (humanReadablePart !== 'flare' && humanReadablePart !== 'costwo') {
56
+ throw new Error('Error - Invalid HRP');
57
+ }
58
+ return buffer_1.Buffer.from(bech32_1.bech32.fromWords(bech32_1.bech32.decode(parts[1]).words));
13
59
  };
14
60
  }
61
+ /**
62
+ * Check if addresses in wallet match UTXO output addresses
63
+ */
15
64
  includeIn(walletAddresses, otxoOutputAddresses) {
16
65
  return walletAddresses.map((a) => otxoOutputAddresses.includes(a)).reduce((a, b) => a && b, true);
17
66
  }
18
67
  /**
19
- * Checks if it is a valid address no illegal characters
20
- *
21
- * @param {string} address - address to be validated
22
- * @returns {boolean} - the validation result
68
+ * Validates a Flare address or array of addresses
69
+ * @param {string | string[]} address - address(es) to validate
70
+ * @returns {boolean} - validation result
23
71
  */
24
- /** @inheritdoc */
25
72
  isValidAddress(address) {
26
73
  const addressArr = Array.isArray(address) ? address : address.split('~');
27
74
  for (const address of addressArr) {
@@ -31,66 +78,57 @@ class Utils {
31
78
  }
32
79
  return true;
33
80
  }
81
+ // Regex patterns
82
+ // export const ADDRESS_REGEX = /^(^P||NodeID)-[a-zA-Z0-9]+$/;
83
+ // export const HEX_REGEX = /^(0x){0,1}([0-9a-f])+$/i;
34
84
  isValidAddressRegex(address) {
35
- return constants_1.ADDRESS_REGEX.test(address);
85
+ return /^(^P||NodeID)-[a-zA-Z0-9]+$/.test(address);
36
86
  }
37
87
  /**
38
- * Checks if it is a valid blockId with length 66 including 0x
39
- *
40
- * @param {string} hash - blockId to be validated
41
- * @returns {boolean} - the validation result
88
+ * Validates a block ID
89
+ * @param {string} hash - block ID to validate
90
+ * @returns {boolean} - validation result
42
91
  */
43
- /** @inheritdoc */
44
92
  isValidBlockId(hash) {
45
- // FlareJS equivalent - check if it's a valid CB58 hash with correct length
46
93
  try {
47
- const decoded = Buffer.from(hash); // FlareJS should provide CB58 utilities
48
- return decoded.length === constants_1.DECODED_BLOCK_ID_LENGTH;
94
+ const decoded = buffer_1.Buffer.from(hash, 'hex');
95
+ return decoded.length === 32;
49
96
  }
50
97
  catch {
51
98
  return false;
52
99
  }
53
100
  }
54
101
  /**
55
- * Checks if the string is a valid protocol public key or
56
- * extended public key.
57
- *
58
- * @param {string} pub - the public key to be validated
59
- * @returns {boolean} - the validation result
102
+ * Validates a public key
103
+ * @param {string} pub - public key to validate
104
+ * @returns {boolean} - validation result
60
105
  */
61
106
  isValidPublicKey(pub) {
62
107
  if ((0, sdk_core_1.isValidXpub)(pub))
63
108
  return true;
64
109
  let pubBuf;
65
- if (pub.length === constants_1.SHORT_PUB_KEY_LENGTH) {
110
+ if (pub.length === 50) {
66
111
  try {
67
- // For FlareJS, we'll need to implement CB58 decode functionality
68
- pubBuf = Buffer.from(pub, 'hex'); // Temporary placeholder
112
+ pubBuf = buffer_1.Buffer.from(pub, 'hex');
69
113
  }
70
114
  catch {
71
115
  return false;
72
116
  }
73
117
  }
74
118
  else {
75
- if (pub.length !== constants_1.COMPRESSED_PUBLIC_KEY_LENGTH && pub.length !== constants_1.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
119
+ if (pub.length !== 66 && pub.length !== 130)
76
120
  return false;
77
- }
78
121
  const firstByte = pub.slice(0, 2);
79
- // uncompressed public key
80
- if (pub.length === constants_1.UNCOMPRESSED_PUBLIC_KEY_LENGTH && firstByte !== '04') {
122
+ if (pub.length === 130 && firstByte !== '04')
81
123
  return false;
82
- }
83
- // compressed public key
84
- if (pub.length === constants_1.COMPRESSED_PUBLIC_KEY_LENGTH && firstByte !== '02' && firstByte !== '03') {
124
+ if (pub.length === 66 && firstByte !== '02' && firstByte !== '03')
85
125
  return false;
86
- }
87
126
  if (!this.allHexChars(pub))
88
127
  return false;
89
- pubBuf = Buffer.from(pub, 'hex');
128
+ pubBuf = buffer_1.Buffer.from(pub, 'hex');
90
129
  }
91
- // validate the public key using BitGo secp256k1
92
130
  try {
93
- secp256k1_1.ecc.isPoint(pubBuf); // Check if it's a valid point
131
+ secp256k1_1.ecc.isPoint(pubBuf);
94
132
  return true;
95
133
  }
96
134
  catch (e) {
@@ -98,269 +136,106 @@ class Utils {
98
136
  }
99
137
  }
100
138
  /**
101
- * Returns whether or not the string is a valid protocol private key, or extended
102
- * private key.
103
- *
104
- * The protocol key format is described in the @stacks/transactions npm package, in the
105
- * createStacksPrivateKey function:
106
- * https://github.com/blockstack/stacks.js/blob/master/packages/transactions/src/keys.ts#L125
107
- *
108
- * @param {string} prv - the private key (or extended private key) to be validated
109
- * @returns {boolean} - the validation result
139
+ * Validates a private key
140
+ * @param {string} prv - private key to validate
141
+ * @returns {boolean} - validation result
110
142
  */
111
143
  isValidPrivateKey(prv) {
112
144
  if ((0, sdk_core_1.isValidXprv)(prv))
113
145
  return true;
114
- if (prv.length !== constants_1.RAW_PRIVATE_KEY_LENGTH && prv.length !== constants_1.SUFFIXED_PRIVATE_KEY_LENGTH) {
146
+ if (prv.length !== 64 && prv.length !== 66)
115
147
  return false;
116
- }
117
- if (prv.length === constants_1.SUFFIXED_PRIVATE_KEY_LENGTH &&
118
- prv.slice(constants_1.RAW_PRIVATE_KEY_LENGTH) !== constants_1.PRIVATE_KEY_COMPRESSED_SUFFIX) {
148
+ if (prv.length === 66 && prv.slice(64) !== '01')
119
149
  return false;
120
- }
121
150
  return this.allHexChars(prv);
122
151
  }
123
152
  /**
124
- * Returns whether or not the string is a composed of hex chars only
125
- *
126
- * @param {string} maybe - the string to be validated
127
- * @returns {boolean} - the validation result
128
- */
129
- allHexChars(maybe) {
130
- return constants_1.HEX_REGEX.test(maybe);
131
- }
132
- /**
133
- * Lightweight Ethereum address validation
134
- * Validates that an address is a 40-character hex string (optionally prefixed with 0x)
135
- *
136
- * @param {string} address - the Ethereum address to validate
137
- * @returns {boolean} - true if valid Ethereum address format
153
+ * Checks if a string contains only hex characters
138
154
  */
139
- isValidEthereumAddress(address) {
140
- if (!address || typeof address !== 'string') {
141
- return false;
142
- }
143
- // Remove 0x prefix if present
144
- const cleanAddress = address.startsWith('0x') ? address.slice(2) : address;
145
- // Check if it's exactly 40 hex characters
146
- return cleanAddress.length === 40 && /^[0-9a-fA-F]{40}$/.test(cleanAddress);
155
+ allHexChars(str) {
156
+ return /^(0x){0,1}([0-9a-f])+$/i.test(str);
147
157
  }
148
158
  /**
149
- * Pick specific properties from an object (replaces lodash.pick)
150
- *
151
- * @param {T} obj - the source object
152
- * @param {K[]} keys - array of property keys to pick
153
- * @returns {Pick<T, K>} - new object with only the specified properties
154
- */
155
- pick(obj, keys) {
156
- const result = {};
157
- for (const key of keys) {
158
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
159
- result[key] = obj[key];
160
- }
161
- }
162
- return result;
163
- }
164
- /**
165
- * Deep equality comparison (replaces lodash.isEqual)
166
- *
167
- * @param {unknown} a - first value to compare
168
- * @param {unknown} b - second value to compare
169
- * @returns {boolean} - true if values are deeply equal
170
- */
171
- isEqual(a, b) {
172
- if (a === b)
173
- return true;
174
- if (a === null || a === undefined || b === null || b === undefined)
175
- return a === b;
176
- if (typeof a !== typeof b)
177
- return false;
178
- if (typeof a === 'object') {
179
- if (Array.isArray(a) !== Array.isArray(b))
180
- return false;
181
- if (Array.isArray(a)) {
182
- const arrB = b;
183
- if (a.length !== arrB.length)
184
- return false;
185
- for (let i = 0; i < a.length; i++) {
186
- if (!this.isEqual(a[i], arrB[i]))
187
- return false;
188
- }
189
- return true;
190
- }
191
- const objA = a;
192
- const objB = b;
193
- const keysA = Object.keys(objA);
194
- const keysB = Object.keys(objB);
195
- if (keysA.length !== keysB.length)
196
- return false;
197
- for (const key of keysA) {
198
- if (!keysB.includes(key))
199
- return false;
200
- if (!this.isEqual(objA[key], objB[key]))
201
- return false;
202
- }
203
- return true;
204
- }
205
- return false;
206
- }
207
- /** @inheritdoc */
208
- isValidSignature(signature) {
209
- throw new sdk_core_1.NotImplementedError('isValidSignature not implemented');
210
- }
211
- /** @inheritdoc */
212
- isValidTransactionId(txId) {
213
- throw new sdk_core_1.NotImplementedError('isValidTransactionId not implemented');
214
- }
215
- /**
216
- * FlareJS wrapper to create signature and return it for credentials
217
- * @param network
218
- * @param message
219
- * @param prv
220
- * @return signature
159
+ * Creates a signature using the Flare network parameters
160
+ * Returns a 65-byte signature (64 bytes signature + 1 byte recovery parameter)
221
161
  */
222
162
  createSignature(network, message, prv) {
223
- // Use BitGo secp256k1 since FlareJS may not expose KeyPair in the same way
224
- try {
225
- const signature = secp256k1_1.ecc.sign(message, prv);
226
- return Buffer.from(signature);
163
+ const messageHash = this.sha256(message);
164
+ const signature = secp256k1_1.ecc.sign(messageHash, prv);
165
+ // Get the public key from the private key for recovery parameter determination
166
+ const publicKey = secp256k1_1.ecc.pointFromScalar(prv, true);
167
+ if (!publicKey) {
168
+ throw new Error('Failed to derive public key from private key');
227
169
  }
228
- catch (error) {
229
- throw new Error(`Failed to create signature: ${error}`);
170
+ // Try recovery with param 0 and 1 to find the correct one
171
+ let recoveryParam = 0;
172
+ for (let i = 0; i <= 1; i++) {
173
+ const recovered = secp256k1_1.ecc.recoverPublicKey(messageHash, signature, i, true);
174
+ if (recovered && buffer_1.Buffer.from(recovered).equals(buffer_1.Buffer.from(publicKey))) {
175
+ recoveryParam = i;
176
+ break;
177
+ }
230
178
  }
179
+ // Append recovery parameter to create 65-byte signature
180
+ const sigWithRecovery = buffer_1.Buffer.alloc(65);
181
+ buffer_1.Buffer.from(signature).copy(sigWithRecovery, 0);
182
+ sigWithRecovery[64] = recoveryParam;
183
+ return sigWithRecovery;
231
184
  }
232
185
  /**
233
- * FlareJS wrapper to verify signature
234
- * @param network
235
- * @param message
236
- * @param signature
237
- * @param publicKey - public key instead of private key for verification
238
- * @return true if it's verify successful
186
+ * Verifies a signature
239
187
  */
240
188
  verifySignature(network, message, signature, publicKey) {
241
189
  try {
242
- return secp256k1_1.ecc.verify(message, publicKey, signature);
190
+ const messageHash = this.sha256(message);
191
+ return secp256k1_1.ecc.verify(signature, messageHash, publicKey);
243
192
  }
244
- catch (error) {
193
+ catch (e) {
245
194
  return false;
246
195
  }
247
196
  }
248
197
  /**
249
- * FlareJS wrapper to recover signature
250
- * @param network
251
- * @param message
252
- * @param signature
253
- * @return recovered public key
198
+ * Creates a new signature object
254
199
  */
255
- recoverySignature(network, message, signature) {
256
- try {
257
- // This would need to be implemented with secp256k1 recovery
258
- // For now, throwing error since recovery logic would need to be adapted
259
- throw new sdk_core_1.NotImplementedError('recoverySignature not fully implemented for FlareJS');
260
- }
261
- catch (error) {
262
- throw new Error(`Failed to recover signature: ${error}`);
263
- }
200
+ createNewSig(sigHex) {
201
+ const buffer = buffer_1.Buffer.from(sigHex.padStart(130, '0'), 'hex');
202
+ return new flarejs_1.Signature(buffer);
264
203
  }
204
+ /**
205
+ * Computes SHA256 hash
206
+ */
265
207
  sha256(buf) {
266
208
  return (0, crypto_1.createHash)('sha256').update(buf).digest();
267
209
  }
268
210
  /**
269
- * Check the raw transaction has a valid format in the blockchain context, throw otherwise.
270
- * It's to reuse in TransactionBuilder and TransactionBuilderFactory
271
- *
272
- * @param rawTransaction Transaction as hex string
211
+ * Validates raw transaction format
273
212
  */
274
213
  validateRawTransaction(rawTransaction) {
275
214
  if (!rawTransaction) {
276
215
  throw new sdk_core_1.InvalidTransactionError('Raw transaction is empty');
277
216
  }
278
- if (!utils.allHexChars(rawTransaction)) {
217
+ if (!this.allHexChars(rawTransaction)) {
279
218
  throw new sdk_core_1.ParseTransactionError('Raw transaction is not hex string');
280
219
  }
281
220
  }
282
221
  /**
283
- * Check if tx is for the blockchainId
284
- *
285
- * @param {DeprecatedTx} tx
286
- * @param {string} blockchainId
287
- * @returns true if tx is for blockchainId
288
- */
289
- isTransactionOf(tx, blockchainId) {
290
- // FlareJS equivalent - this would need proper CB58 encoding implementation
291
- try {
292
- const txRecord = tx;
293
- const unsignedTx = txRecord.getUnsignedTx();
294
- const transaction = unsignedTx.getTransaction();
295
- const txBlockchainId = transaction.getBlockchainID();
296
- return Buffer.from(txBlockchainId).toString('hex') === blockchainId;
297
- }
298
- catch (error) {
299
- return false;
300
- }
301
- }
302
- /**
303
- * Check if Output is from PVM.
304
- * Output could be EVM or PVM output.
305
- * @param {DeprecatedOutput} output
306
- * @returns {boolean} output has transferable output structure
307
- */
308
- deprecatedIsTransferableOutput(output) {
309
- return 'getOutput' in output;
310
- }
311
- /**
312
- * Check if Output is from PVM.
313
- * Output could be EVM or PVM output.
314
- * @param {Output} output
315
- * @returns {boolean} output is TransferableOutput
222
+ * Checks if output is TransferableOutput type
316
223
  */
317
224
  isTransferableOutput(output) {
318
- return typeof output.getOutput === 'function';
319
- }
320
- /**
321
- * Return a mapper function to that network address representation.
322
- * @param network required to stringify addresses
323
- * @return mapper function
324
- */
325
- deprecatedMapOutputToEntry(network) {
326
- return (output) => {
327
- if (this.deprecatedIsTransferableOutput(output)) {
328
- // Simplified implementation for FlareJS
329
- try {
330
- const transferableOutput = output;
331
- const amount = transferableOutput.amount();
332
- // Simplified address handling - would need proper FlareJS address utilities
333
- const address = 'flare-address-placeholder'; // TODO: implement proper address conversion
334
- return {
335
- value: amount.toString(),
336
- address,
337
- };
338
- }
339
- catch (error) {
340
- throw new Error(`Failed to map output: ${error}`);
341
- }
342
- }
343
- else {
344
- // Handle EVM output case - simplified
345
- return {
346
- value: '0', // TODO: implement proper amount extraction
347
- address: '0x0000000000000000000000000000000000000000', // TODO: implement proper address extraction
348
- };
349
- }
350
- };
225
+ return output?._type === flarejs_1.TypeSymbols.TransferableOutput;
351
226
  }
352
227
  /**
353
- * Return a mapper function to that network address representation.
354
- * @param network required to stringify addresses
355
- * @return mapper function
228
+ * Maps outputs to entry format
356
229
  */
357
230
  mapOutputToEntry(network) {
358
231
  return (output) => {
359
232
  if (this.isTransferableOutput(output)) {
360
- const transferableOutput = output;
361
- const outputAmount = transferableOutput.amount();
362
- // Simplified address handling for FlareJS
363
- const address = 'flare-address-placeholder'; // TODO: implement proper address conversion
233
+ const outputAmount = output.amount();
234
+ const address = output.output
235
+ .getOwners()
236
+ .map((a) => this.addressToString(network.hrp, network.alias, buffer_1.Buffer.from(a)))
237
+ .sort()
238
+ .join(iface_1.ADDRESS_SEPARATOR);
364
239
  return {
365
240
  value: outputAmount.toString(),
366
241
  address,
@@ -372,116 +247,119 @@ class Utils {
372
247
  };
373
248
  }
374
249
  /**
375
- * remove hex prefix (0x)
376
- * @param hex string
377
- * @returns hex without 0x
250
+ * Removes 0x prefix from hex string
378
251
  */
379
252
  removeHexPrefix(hex) {
380
- if (hex.startsWith('0x')) {
381
- return hex.substring(2);
382
- }
383
- return hex;
253
+ return hex.startsWith('0x') ? hex.substring(2) : hex;
384
254
  }
385
255
  /**
386
- * Outputidx convert from number (as string) to buffer.
387
- * @param {string} outputidx number
388
- * @return {Buffer} buffer of size 4 with that number value
256
+ * Converts output index to buffer
389
257
  */
390
258
  outputidxNumberToBuffer(outputidx) {
391
- return Buffer.from(Number(outputidx).toString(16).padStart(constants_1.OUTPUT_INDEX_HEX_LENGTH, '0'), 'hex');
259
+ return buffer_1.Buffer.from(Number(outputidx).toString(16).padStart(8, '0'), 'hex');
392
260
  }
393
261
  /**
394
- * Outputidx buffer to number (as string)
395
- * @param {Buffer} outputidx
396
- * @return {string} outputidx number
262
+ * Converts output index buffer to number string
397
263
  */
398
264
  outputidxBufferToNumber(outputidx) {
399
265
  return parseInt(outputidx.toString('hex'), 16).toString();
400
266
  }
267
+ // Required by BaseUtils interface but not implemented
268
+ isValidSignature(signature) {
269
+ throw new sdk_core_1.NotImplementedError('isValidSignature not implemented');
270
+ }
271
+ isValidTransactionId(txId) {
272
+ throw new sdk_core_1.NotImplementedError('isValidTransactionId not implemented');
273
+ }
401
274
  /**
402
- * CB58 decode function - simple Base58 decode implementation
403
- * @param {string} data - CB58 encoded string
404
- * @returns {Buffer} decoded buffer
275
+ * Decodes a base58 string with checksum to a Buffer
405
276
  */
406
- cb58Decode(data) {
407
- // For now, use a simple hex decode as placeholder
408
- // In a full implementation, this would be proper CB58 decoding
409
- try {
410
- return Buffer.from(data, 'hex');
411
- }
412
- catch {
413
- // Fallback to buffer from string
414
- return Buffer.from(data);
277
+ cb58Decode(str) {
278
+ const decoded = bs58_1.default.decode(str);
279
+ if (!this.validateChecksum(buffer_1.Buffer.from(decoded))) {
280
+ throw new Error('Invalid checksum');
415
281
  }
282
+ return buffer_1.Buffer.from(decoded.slice(0, decoded.length - 4));
416
283
  }
417
284
  /**
418
- * Convert address buffer to bech32 string
419
- * @param {string} hrp - Human readable part
420
- * @param {string} chainid - Chain identifier
421
- * @param {Buffer} addressBuffer - Address buffer
422
- * @returns {string} Address string
285
+ * Validates a checksum on a Buffer and returns true if valid, false if not
423
286
  */
424
- addressToString(hrp, chainid, addressBuffer) {
425
- // Simple implementation - in practice this would use bech32 encoding
426
- return `${chainid}-${addressBuffer.toString('hex')}`;
287
+ validateChecksum(buff) {
288
+ const hashSlice = buff.slice(buff.length - 4);
289
+ const calculatedHashSlice = (0, crypto_1.createHash)('sha256')
290
+ .update(buff.slice(0, buff.length - 4))
291
+ .digest()
292
+ .slice(28);
293
+ return hashSlice.toString('hex') === calculatedHashSlice.toString('hex');
427
294
  }
428
295
  /**
429
- * Convert string to bytes for FlareJS memo
430
- * Follows FlareJS utils.stringToBytes pattern
431
- * @param {string} text - Text to convert
432
- * @returns {Uint8Array} Byte array
296
+ * Encodes a Buffer as a base58 string with checksum
433
297
  */
434
- stringToBytes(text) {
435
- return new TextEncoder().encode(text);
298
+ cb58Encode(bytes) {
299
+ const withChecksum = this.addChecksum(bytes);
300
+ return bs58_1.default.encode(withChecksum);
436
301
  }
437
302
  /**
438
- * Convert bytes to string from FlareJS memo
439
- * @param {Uint8Array} bytes - Bytes to convert
440
- * @returns {string} Decoded string
303
+ * Adds a checksum to a Buffer and returns the concatenated result
441
304
  */
442
- bytesToString(bytes) {
443
- return new TextDecoder().decode(bytes);
305
+ addChecksum(buff) {
306
+ const hashSlice = (0, crypto_1.createHash)('sha256').update(buff).digest().slice(28);
307
+ return buffer_1.Buffer.concat([buff, hashSlice]);
444
308
  }
445
309
  /**
446
- * Create memo bytes from various input formats
447
- * Supports string, JSON object, or raw bytes
448
- * @param {string | Record<string, unknown> | Uint8Array} memo - Memo data
449
- * @returns {Uint8Array} Memo bytes for FlareJS
310
+ * Check if tx is for the blockchainId
311
+ *
312
+ * @param {DeprecatedTx} tx
313
+ * @param {string} blockchainId
314
+ * @returns true if tx is for blockchainId
450
315
  */
451
- createMemoBytes(memo) {
452
- if (memo instanceof Uint8Array) {
453
- return memo;
454
- }
455
- if (typeof memo === 'string') {
456
- return this.stringToBytes(memo);
316
+ // TODO: remove DeprecatedTx usage
317
+ isTransactionOf(tx, blockchainId) {
318
+ // FlareJS equivalent - this would need proper CB58 encoding implementation
319
+ try {
320
+ const txRecord = tx;
321
+ const unsignedTx = txRecord.getUnsignedTx();
322
+ const transaction = unsignedTx.getTransaction();
323
+ const txBlockchainId = transaction.getBlockchainID();
324
+ return buffer_1.Buffer.from(txBlockchainId).toString('hex') === blockchainId;
457
325
  }
458
- if (typeof memo === 'object') {
459
- return this.stringToBytes(JSON.stringify(memo));
326
+ catch (error) {
327
+ return false;
460
328
  }
461
- throw new sdk_core_1.InvalidTransactionError('Invalid memo format');
462
329
  }
463
- /**
464
- * Parse memo bytes to string
465
- * @param {Uint8Array} memoBytes - Memo bytes from FlareJS transaction
466
- * @returns {string} Decoded memo string
467
- */
468
- parseMemoBytes(memoBytes) {
469
- if (memoBytes.length === 0) {
470
- return '';
471
- }
472
- return this.bytesToString(memoBytes);
330
+ flareIdString(value) {
331
+ return new flarejs_1.Id(buffer_1.Buffer.from(value, 'hex'));
473
332
  }
474
333
  /**
475
- * Validate memo size (FlareJS has transaction size limits)
476
- * @param {Uint8Array} memoBytes - Memo bytes
477
- * @param {number} maxSize - Maximum size in bytes (default 4KB)
478
- * @returns {boolean} Whether memo is within size limits
334
+ * FlareJS wrapper to recover signature
335
+ * @param network
336
+ * @param message
337
+ * @param signature
338
+ * @return recovered public key
479
339
  */
480
- validateMemoSize(memoBytes, maxSize = 4096) {
481
- return memoBytes.length <= maxSize;
340
+ recoverySignature(network, message, signature) {
341
+ try {
342
+ // Hash the message first - must match the hash used in signing
343
+ const messageHash = (0, crypto_1.createHash)('sha256').update(message).digest();
344
+ // Extract recovery parameter and signature
345
+ if (signature.length !== 65) {
346
+ throw new Error('Invalid signature length - expected 65 bytes (64 bytes signature + 1 byte recovery)');
347
+ }
348
+ const recoveryParam = signature[64];
349
+ const sigOnly = signature.slice(0, 64);
350
+ // Recover public key using the provided recovery parameter
351
+ const recovered = secp256k1_1.ecc.recoverPublicKey(messageHash, sigOnly, recoveryParam, true);
352
+ if (!recovered) {
353
+ throw new Error('Failed to recover public key');
354
+ }
355
+ return buffer_1.Buffer.from(recovered);
356
+ }
357
+ catch (error) {
358
+ throw new Error(`Failed to recover signature: ${error}`);
359
+ }
482
360
  }
483
361
  }
484
362
  exports.Utils = Utils;
485
363
  const utils = new Utils();
486
364
  exports.default = utils;
487
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLG1EQVE4QjtBQUU5QixxREFBNEM7QUFDNUMsbUNBQW9DO0FBRXBDLDJDQVdxQjtBQUVyQixNQUFhLEtBQUs7SUFBbEI7UUE0RlMsaUJBQVksR0FBRyxDQUFDLEdBQVcsRUFBVSxFQUFFO1lBQzVDLHlDQUF5QztZQUN6QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsNEJBQTRCO1FBQzlELENBQUMsQ0FBQztJQThaSixDQUFDO0lBNWZRLFNBQVMsQ0FBQyxlQUF5QixFQUFFLG1CQUE2QjtRQUN2RSxPQUFPLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsa0JBQWtCO0lBQ2xCLGNBQWMsQ0FBQyxPQUEwQjtRQUN2QyxNQUFNLFVBQVUsR0FBYSxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbkYsS0FBSyxNQUFNLE9BQU8sSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZDLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxt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QUM7UUFDbEMsQ0FBQztRQUVELElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDN0IsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsTUFBTSxJQUFJLGtDQUF1QixDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxjQUFjLENBQUMsU0FBcUI7UUFDbEMsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzNCLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxnQkFBZ0IsQ0FBQyxTQUFxQixFQUFFLE9BQU8sR0FBRyxJQUFJO1FBQ3BELE9BQU8sU0FBUyxDQUFDLE1BQU0sSUFBSSxPQUFPLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBN2ZELHNCQTZmQztBQUVELE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7QUFFMUIsa0JBQWUsS0FBSyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVHJhbnNmZXJhYmxlT3V0cHV0IH0gZnJvbSAnQGZsYXJlbmV0d29yay9mbGFyZWpzJztcbmltcG9ydCB7XG4gIEJhc2VVdGlscyxcbiAgRW50cnksXG4gIEludmFsaWRUcmFuc2FjdGlvbkVycm9yLFxuICBpc1ZhbGlkWHBydixcbiAgaXNWYWxpZFhwdWIsXG4gIE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIFBhcnNlVHJhbnNhY3Rpb25FcnJvcixcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgRmxhcmVOZXR3b3JrIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBlY2MgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBEZXByZWNhdGVkT3V0cHV0LCBEZXByZWNhdGVkVHgsIE91dHB1dCB9IGZyb20gJy4vaWZhY2UnO1xuaW1wb3J0IHtcbiAgREVDT0RFRF9CTE9DS19JRF9MRU5HVEgsXG4gIFNIT1JUX1BVQl9LRVlfTEVOR1RILFxuICBDT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RILFxuICBVTkNPTVBSRVNTRURfUFVCTElDX0tFWV9MRU5HVEgsXG4gIFJBV19QUklWQVRFX0tFWV9MRU5HVEgsXG4gIFNVRkZJWEVEX1BSSVZBVEVfS0VZX0xFTkdUSCxcbiAgUFJJVkFURV9LRVlfQ09NUFJFU1NFRF9TVUZGSVgsXG4gIE9VVFBVVF9JTkRFWF9IRVhfTEVOR1RILFxuICBBRERSRVNTX1JFR0VYLFxuICBIRVhfUkVHRVgsXG59IGZyb20gJy4vY29uc3RhbnRzJztcblxuZXhwb3J0IGNsYXNzIFV0aWxzIGltcGxlbWVudHMgQmFzZVV0aWxzIHtcbiAgcHVibGljIGluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXM6IHN0cmluZ1tdLCBvdHhvT3V0cHV0QWRkcmVzc2VzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB3YWxsZXRBZGRyZXNzZXMubWFwKChhKSA9PiBvdHhvT3V0cHV0QWRkcmVzc2VzLmluY2x1ZGVzKGEpKS5yZWR1Y2UoKGEsIGIpID0+IGEgJiYgYiwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGl0IGlzIGEgdmFsaWQgYWRkcmVzcyBubyBpbGxlZ2FsIGNoYXJhY3RlcnNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBhZGRyZXNzIHRvIGJlIHZhbGlkYXRlZFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGFkZHJlc3NBcnI6IHN0cmluZ1tdID0gQXJyYXkuaXNBcnJheShhZGRyZXNzKSA/IGFkZHJlc3MgOiBhZGRyZXNzLnNwbGl0KCd+Jyk7XG5cbiAgICBmb3IgKGNvbnN0IGFkZHJlc3Mgb2YgYWRkcmVzc0Fycikge1xuICAgICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzUmVnZXgoYWRkcmVzcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkQWRkcmVzc1JlZ2V4KGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBBRERSRVNTX1JFR0VYLnRlc3QoYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGl0IGlzIGEgdmFsaWQgYmxvY2tJZCB3aXRoIGxlbmd0aCA2NiBpbmNsdWRpbmcgMHhcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhhc2ggLSBibG9ja0lkIHRvIGJlIHZhbGlkYXRlZFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkQmxvY2tJZChoYXNoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyBGbGFyZUpTIGVxdWl2YWxlbnQgLSBjaGVjayBpZiBpdCdzIGEgdmFsaWQgQ0I1OCBoYXNoIHdpdGggY29ycmVjdCBsZW5ndGhcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGVjb2RlZCA9IEJ1ZmZlci5mcm9tKGhhc2gpOyAvLyBGbGFyZUpTIHNob3VsZCBwcm92aWRlIENCNTggdXRpbGl0aWVzXG4gICAgICByZXR1cm4gZGVjb2RlZC5sZW5ndGggPT09IERFQ09ERURfQkxPQ0tfSURfTEVOR1RIO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHN0cmluZyBpcyBhIHZhbGlkIHByb3RvY29sIHB1YmxpYyBrZXkgb3JcbiAgICogZXh0ZW5kZWQgcHVibGljIGtleS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHB1YiAtIHRoZSAgcHVibGljIGtleSB0byBiZSB2YWxpZGF0ZWRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkUHVibGljS2V5KHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzVmFsaWRYcHViKHB1YikpIHJldHVybiB0cnVlO1xuXG4gICAgbGV0IHB1YkJ1ZjogQnVmZmVyO1xuICAgIGlmIChwdWIubGVuZ3RoID09PSBTSE9SVF9QVUJfS0VZX0xFTkdUSCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gRm9yIEZsYXJlSlMsIHdlJ2xsIG5lZWQgdG8gaW1wbGVtZW50IENCNTggZGVjb2RlIGZ1bmN0aW9uYWxpdHlcbiAgICAgICAgcHViQnVmID0gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7IC8vIFRlbXBvcmFyeSBwbGFjZWhvbGRlclxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHB1Yi5sZW5ndGggIT09IENPTVBSRVNTRURfUFVCTElDX0tFWV9MRU5HVEggJiYgcHViLmxlbmd0aCAhPT0gVU5DT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RIKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlyc3RCeXRlID0gcHViLnNsaWNlKDAsIDIpO1xuXG4gICAgICAvLyB1bmNvbXByZXNzZWQgcHVibGljIGtleVxuICAgICAgaWYgKHB1Yi5sZW5ndGggPT09IFVOQ09NUFJFU1NFRF9QVUJMSUNfS0VZX0xFTkdUSCAmJiBmaXJzdEJ5dGUgIT09ICcwNCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb21wcmVzc2VkIHB1YmxpYyBrZXlcbiAgICAgIGlmIChwdWIubGVuZ3RoID09PSBDT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RIICYmIGZpcnN0Qnl0ZSAhPT0gJzAyJyAmJiBmaXJzdEJ5dGUgIT09ICcwMycpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuYWxsSGV4Q2hhcnMocHViKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgcHViQnVmID0gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBwdWJsaWMga2V5IHVzaW5nIEJpdEdvIHNlY3AyNTZrMVxuICAgIHRyeSB7XG4gICAgICBlY2MuaXNQb2ludChwdWJCdWYpOyAvLyBDaGVjayBpZiBpdCdzIGEgdmFsaWQgcG9pbnRcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgcGFyc2VBZGRyZXNzID0gKHB1Yjogc3RyaW5nKTogQnVmZmVyID0+IHtcbiAgICAvLyBGbGFyZUpTIGVxdWl2YWxlbnQgZm9yIGFkZHJlc3MgcGFyc2luZ1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShwdWIsICdoZXgnKTsgLy8gU2ltcGxpZmllZCBpbXBsZW1lbnRhdGlvblxuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBzdHJpbmcgaXMgYSB2YWxpZCBwcm90b2NvbCBwcml2YXRlIGtleSwgb3IgZXh0ZW5kZWRcbiAgICogcHJpdmF0ZSBrZXkuXG4gICAqXG4gICAqIFRoZSBwcm90b2NvbCBrZXkgZm9ybWF0IGlzIGRlc2NyaWJlZCBpbiB0aGUgQHN0YWNrcy90cmFuc2FjdGlvbnMgbnBtIHBhY2thZ2UsIGluIHRoZVxuICAgKiBjcmVhdGVTdGFja3NQcml2YXRlS2V5IGZ1bmN0aW9uOlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vYmxvY2tzdGFjay9zdGFja3MuanMvYmxvYi9tYXN0ZXIvcGFja2FnZXMvdHJhbnNhY3Rpb25zL3NyYy9rZXlzLnRzI0wxMjVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBydiAtIHRoZSBwcml2YXRlIGtleSAob3IgZXh0ZW5kZWQgcHJpdmF0ZSBrZXkpIHRvIGJlIHZhbGlkYXRlZFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIGlzVmFsaWRQcml2YXRlS2V5KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzVmFsaWRYcHJ2KHBydikpIHJldHVybiB0cnVlO1xuXG4gICAgaWYgKHBydi5sZW5ndGggIT09IFJBV19QUklWQVRFX0tFWV9MRU5HVEggJiYgcHJ2Lmxlbmd0aCAhPT0gU1VGRklYRURfUFJJVkFURV9LRVlfTEVOR1RIKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcHJ2Lmxlbmd0aCA9PT0gU1VGRklYRURfUFJJVkFURV9LRVlfTEVOR1RIICYmXG4gICAgICBwcnYuc2xpY2UoUkFXX1BSSVZBVEVfS0VZX0xFTkdUSCkgIT09IFBSSVZBVEVfS0VZX0NPTVBSRVNTRURfU1VGRklYXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWxsSGV4Q2hhcnMocHJ2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBzdHJpbmcgaXMgYSBjb21wb3NlZCBvZiBoZXggY2hhcnMgb25seVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWF5YmUgLSB0aGUgIHN0cmluZyB0byBiZSB2YWxpZGF0ZWRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBhbGxIZXhDaGFycyhtYXliZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEhFWF9SRUdFWC50ZXN0KG1heWJlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWdodHdlaWdodCBFdGhlcmV1bSBhZGRyZXNzIHZhbGlkYXRpb25cbiAgICogVmFsaWRhdGVzIHRoYXQgYW4gYWRkcmVzcyBpcyBhIDQwLWNoYXJhY3RlciBoZXggc3RyaW5nIChvcHRpb25hbGx5IHByZWZpeGVkIHdpdGggMHgpXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gdGhlIEV0aGVyZXVtIGFkZHJlc3MgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdHJ1ZSBpZiB2YWxpZCBFdGhlcmV1bSBhZGRyZXNzIGZvcm1hdFxuICAgKi9cbiAgaXNWYWxpZEV0aGVyZXVtQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIWFkZHJlc3MgfHwgdHlwZW9mIGFkZHJlc3MgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIDB4IHByZWZpeCBpZiBwcmVzZW50XG4gICAgY29uc3QgY2xlYW5BZGRyZXNzID0gYWRkcmVzcy5zdGFydHNXaXRoKCcweCcpID8gYWRkcmVzcy5zbGljZSgyKSA6IGFkZHJlc3M7XG5cbiAgICAvLyBDaGVjayBpZiBpdCdzIGV4YWN0bHkgNDAgaGV4IGNoYXJhY3RlcnNcbiAgICByZXR1cm4gY2xlYW5BZGRyZXNzLmxlbmd0aCA9PT0gNDAgJiYgL15bMC05YS1mQS1GXXs0MH0kLy50ZXN0KGNsZWFuQWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogUGljayBzcGVjaWZpYyBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0IChyZXBsYWNlcyBsb2Rhc2gucGljaylcbiAgICpcbiAgICogQHBhcmFtIHtUfSBvYmogLSB0aGUgc291cmNlIG9iamVjdFxuICAgKiBAcGFyYW0ge0tbXX0ga2V5cyAtIGFycmF5IG9mIHByb3BlcnR5IGtleXMgdG8gcGlja1xuICAgKiBAcmV0dXJucyB7UGljazxULCBLPn0gLSBuZXcgb2JqZWN0IHdpdGggb25seSB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXNcbiAgICovXG4gIHBpY2s8VCwgSyBleHRlbmRzIGtleW9mIFQ+KG9iajogVCwga2V5czogS1tdKTogUGljazxULCBLPiB7XG4gICAgY29uc3QgcmVzdWx0ID0ge30gYXMgUGljazxULCBLPjtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICByZXN1bHRba2V5XSA9IG9ialtrZXldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIERlZXAgZXF1YWxpdHkgY29tcGFyaXNvbiAocmVwbGFjZXMgbG9kYXNoLmlzRXF1YWwpXG4gICAqXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gYSAtIGZpcnN0IHZhbHVlIHRvIGNvbXBhcmVcbiAgICogQHBhcmFtIHt1bmtub3dufSBiIC0gc2Vjb25kIHZhbHVlIHRvIGNvbXBhcmVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdHJ1ZSBpZiB2YWx1ZXMgYXJlIGRlZXBseSBlcXVhbFxuICAgKi9cbiAgaXNFcXVhbChhOiB1bmtub3duLCBiOiB1bmtub3duKTogYm9vbGVhbiB7XG4gICAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlO1xuXG4gICAgaWYgKGEgPT09IG51bGwgfHwgYSA9PT0gdW5kZWZpbmVkIHx8IGIgPT09IG51bGwgfHwgYiA9PT0gdW5kZWZpbmVkKSByZXR1cm4gYSA9PT0gYjtcblxuICAgIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGEpICE9PSBBcnJheS5pc0FycmF5KGIpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGEpKSB7XG4gICAgICAgIGNvbnN0IGFyckIgPSBiIGFzIHVua25vd25bXTtcbiAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBhcnJCLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoIXRoaXMuaXNFcXVhbChhW2ldLCBhcnJCW2ldKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvYmpBID0gYSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIGNvbnN0IG9iakIgPSBiIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgY29uc3Qga2V5c0EgPSBPYmplY3Qua2V5cyhvYmpBKTtcbiAgICAgIGNvbnN0IGtleXNCID0gT2JqZWN0LmtleXMob2JqQik7XG4gICAgICBpZiAoa2V5c0EubGVuZ3RoICE9PSBrZXlzQi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICAgICAgZm9yIChjb25zdCBrZXkgb2Yga2V5c0EpIHtcbiAgICAgICAgaWYgKCFrZXlzQi5pbmNsdWRlcyhrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICghdGhpcy5pc0VxdWFsKG9iakFba2V5XSwgb2JqQltrZXldKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRTaWduYXR1cmUoc2lnbmF0dXJlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcignaXNWYWxpZFNpZ25hdHVyZSBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkVHJhbnNhY3Rpb25JZCh0eElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcignaXNWYWxpZFRyYW5zYWN0aW9uSWQgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvKipcbiAgICogRmxhcmVKUyB3cmFwcGVyIHRvIGNyZWF0ZSBzaWduYXR1cmUgYW5kIHJldHVybiBpdCBmb3IgY3JlZGVudGlhbHNcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICogQHBhcmFtIHBydlxuICAgKiBAcmV0dXJuIHNpZ25hdHVyZVxuICAgKi9cbiAgY3JlYXRlU2lnbmF0dXJlKG5ldHdvcms6IEZsYXJlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyLCBwcnY6IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gICAgLy8gVXNlIEJpdEdvIHNlY3AyNTZrMSBzaW5jZSBGbGFyZUpTIG1heSBub3QgZXhwb3NlIEtleVBhaXIgaW4gdGhlIHNhbWUgd2F5XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGVjYy5zaWduKG1lc3NhZ2UsIHBydik7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20oc2lnbmF0dXJlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIHNpZ25hdHVyZTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmxhcmVKUyB3cmFwcGVyIHRvIHZlcmlmeSBzaWduYXR1cmVcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICogQHBhcmFtIHNpZ25hdHVyZVxuICAgKiBAcGFyYW0gcHVibGljS2V5IC0gcHVibGljIGtleSBpbnN0ZWFkIG9mIHByaXZhdGUga2V5IGZvciB2ZXJpZmljYXRpb25cbiAgICogQHJldHVybiB0cnVlIGlmIGl0J3MgdmVyaWZ5IHN1Y2Nlc3NmdWxcbiAgICovXG4gIHZlcmlmeVNpZ25hdHVyZShuZXR3b3JrOiBGbGFyZU5ldHdvcmssIG1lc3NhZ2U6IEJ1ZmZlciwgc2lnbmF0dXJlOiBCdWZmZXIsIHB1YmxpY0tleTogQnVmZmVyKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBlY2MudmVyaWZ5KG1lc3NhZ2UsIHB1YmxpY0tleSwgc2lnbmF0dXJlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFyZUpTIHdyYXBwZXIgdG8gcmVjb3ZlciBzaWduYXR1cmVcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICogQHBhcmFtIHNpZ25hdHVyZVxuICAgKiBAcmV0dXJuIHJlY292ZXJlZCBwdWJsaWMga2V5XG4gICAqL1xuICByZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrOiBGbGFyZU5ldHdvcmssIG1lc3NhZ2U6IEJ1ZmZlciwgc2lnbmF0dXJlOiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIHRyeSB7XG4gICAgICAvLyBUaGlzIHdvdWxkIG5lZWQgdG8gYmUgaW1wbGVtZW50ZWQgd2l0aCBzZWNwMjU2azEgcmVjb3ZlcnlcbiAgICAgIC8vIEZvciBub3csIHRocm93aW5nIGVycm9yIHNpbmNlIHJlY292ZXJ5IGxvZ2ljIHdvdWxkIG5lZWQgdG8gYmUgYWRhcHRlZFxuICAgICAgdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoJ3JlY292ZXJ5U2lnbmF0dXJlIG5vdCBmdWxseSBpbXBsZW1lbnRlZCBmb3IgRmxhcmVKUycpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byByZWNvdmVyIHNpZ25hdHVyZTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cblxuICBzaGEyNTYoYnVmOiBVaW50OEFycmF5KTogQnVmZmVyIHtcbiAgICByZXR1cm4gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKGJ1ZikuZGlnZXN0KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhlIHJhdyB0cmFuc2FjdGlvbiBoYXMgYSB2YWxpZCBmb3JtYXQgaW4gdGhlIGJsb2NrY2hhaW4gY29udGV4dCwgdGhyb3cgb3RoZXJ3aXNlLlxuICAgKiBJdCdzIHRvIHJldXNlIGluIFRyYW5zYWN0aW9uQnVpbGRlciBhbmQgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeVxuICAgKlxuICAgKiBAcGFyYW0gcmF3VHJhbnNhY3Rpb24gVHJhbnNhY3Rpb24gYXMgaGV4IHN0cmluZ1xuICAgKi9cbiAgdmFsaWRhdGVSYXdUcmFuc2FjdGlvbihyYXdUcmFuc2FjdGlvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFyYXdUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdSYXcgdHJhbnNhY3Rpb24gaXMgZW1wdHknKTtcbiAgICB9XG4gICAgaWYgKCF1dGlscy5hbGxIZXhDaGFycyhyYXdUcmFuc2FjdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ1JhdyB0cmFuc2FjdGlvbiBpcyBub3QgaGV4IHN0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0eCBpcyBmb3IgdGhlIGJsb2NrY2hhaW5JZFxuICAgKlxuICAgKiBAcGFyYW0ge0RlcHJlY2F0ZWRUeH0gdHhcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJsb2NrY2hhaW5JZFxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHR4IGlzIGZvciBibG9ja2NoYWluSWRcbiAgICovXG4gIGlzVHJhbnNhY3Rpb25PZih0eDogRGVwcmVjYXRlZFR4LCBibG9ja2NoYWluSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIC8vIEZsYXJlSlMgZXF1aXZhbGVudCAtIHRoaXMgd291bGQgbmVlZCBwcm9wZXIgQ0I1OCBlbmNvZGluZyBpbXBsZW1lbnRhdGlvblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0eFJlY29yZCA9IHR4IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID0gKHR4UmVjb3JkLmdldFVuc2lnbmVkVHggYXMgKCkgPT4gUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKCk7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9ICh1bnNpZ25lZFR4LmdldFRyYW5zYWN0aW9uIGFzICgpID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSgpO1xuICAgICAgY29uc3QgdHhCbG9ja2NoYWluSWQgPSAodHJhbnNhY3Rpb24uZ2V0QmxvY2tjaGFpbklEIGFzICgpID0+IHVua25vd24pKCk7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20odHhCbG9ja2NoYWluSWQgYXMgc3RyaW5nKS50b1N0cmluZygnaGV4JykgPT09IGJsb2NrY2hhaW5JZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBPdXRwdXQgaXMgZnJvbSBQVk0uXG4gICAqIE91dHB1dCBjb3VsZCBiZSBFVk0gb3IgUFZNIG91dHB1dC5cbiAgICogQHBhcmFtIHtEZXByZWNhdGVkT3V0cHV0fSBvdXRwdXRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IG91dHB1dCBoYXMgdHJhbnNmZXJhYmxlIG91dHB1dCBzdHJ1Y3R1cmVcbiAgICovXG4gIGRlcHJlY2F0ZWRJc1RyYW5zZmVyYWJsZU91dHB1dChvdXRwdXQ6IERlcHJlY2F0ZWRPdXRwdXQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gJ2dldE91dHB1dCcgaW4gKG91dHB1dCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgT3V0cHV0IGlzIGZyb20gUFZNLlxuICAgKiBPdXRwdXQgY291bGQgYmUgRVZNIG9yIFBWTSBvdXRwdXQuXG4gICAqIEBwYXJhbSB7T3V0cHV0fSBvdXRwdXRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IG91dHB1dCBpcyBUcmFuc2ZlcmFibGVPdXRwdXRcbiAgICovXG4gIGlzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dDogT3V0cHV0KTogb3V0cHV0IGlzIFRyYW5zZmVyYWJsZU91dHB1dCB7XG4gICAgcmV0dXJuIHR5cGVvZiAob3V0cHV0IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmdldE91dHB1dCA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBtYXBwZXIgZnVuY3Rpb24gdG8gdGhhdCBuZXR3b3JrIGFkZHJlc3MgcmVwcmVzZW50YXRpb24uXG4gICAqIEBwYXJhbSBuZXR3b3JrIHJlcXVpcmVkIHRvIHN0cmluZ2lmeSBhZGRyZXNzZXNcbiAgICogQHJldHVybiBtYXBwZXIgZnVuY3Rpb25cbiAgICovXG4gIGRlcHJlY2F0ZWRNYXBPdXRwdXRUb0VudHJ5KG5ldHdvcms6IEZsYXJlTmV0d29yayk6IChvdXRwdXQ6IERlcHJlY2F0ZWRPdXRwdXQpID0+IEVudHJ5IHtcbiAgICByZXR1cm4gKG91dHB1dDogRGVwcmVjYXRlZE91dHB1dCkgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVwcmVjYXRlZElzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dCkpIHtcbiAgICAgICAgLy8gU2ltcGxpZmllZCBpbXBsZW1lbnRhdGlvbiBmb3IgRmxhcmVKU1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRyYW5zZmVyYWJsZU91dHB1dCA9IG91dHB1dCBhcyB1bmtub3duIGFzIFRyYW5zZmVyYWJsZU91dHB1dDtcbiAgICAgICAgICBjb25zdCBhbW91bnQgPSB0cmFuc2ZlcmFibGVPdXRwdXQuYW1vdW50KCk7XG5cbiAgICAgICAgICAvLyBTaW1wbGlmaWVkIGFkZHJlc3MgaGFuZGxpbmcgLSB3b3VsZCBuZWVkIHByb3BlciBGbGFyZUpTIGFkZHJlc3MgdXRpbGl0aWVzXG4gICAgICAgICAgY29uc3QgYWRkcmVzcyA9ICdmbGFyZS1hZGRyZXNzLXBsYWNlaG9sZGVyJzsgLy8gVE9ETzogaW1wbGVtZW50IHByb3BlciBhZGRyZXNzIGNvbnZlcnNpb25cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbWFwIG91dHB1dDogJHtlcnJvcn1gKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSGFuZGxlIEVWTSBvdXRwdXQgY2FzZSAtIHNpbXBsaWZpZWRcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2YWx1ZTogJzAnLCAvLyBUT0RPOiBpbXBsZW1lbnQgcHJvcGVyIGFtb3VudCBleHRyYWN0aW9uXG4gICAgICAgICAgYWRkcmVzczogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsIC8vIFRPRE86IGltcGxlbWVudCBwcm9wZXIgYWRkcmVzcyBleHRyYWN0aW9uXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBtYXBwZXIgZnVuY3Rpb24gdG8gdGhhdCBuZXR3b3JrIGFkZHJlc3MgcmVwcmVzZW50YXRpb24uXG4gICAqIEBwYXJhbSBuZXR3b3JrIHJlcXVpcmVkIHRvIHN0cmluZ2lmeSBhZGRyZXNzZXNcbiAgICogQHJldHVybiBtYXBwZXIgZnVuY3Rpb25cbiAgICovXG4gIG1hcE91dHB1dFRvRW50cnkobmV0d29yazogRmxhcmVOZXR3b3JrKTogKE91dHB1dCkgPT4gRW50cnkge1xuICAgIHJldHVybiAob3V0cHV0OiBPdXRwdXQpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dCkpIHtcbiAgICAgICAgY29uc3QgdHJhbnNmZXJhYmxlT3V0cHV0ID0gb3V0cHV0IGFzIFRyYW5zZmVyYWJsZU91dHB1dDtcbiAgICAgICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gdHJhbnNmZXJhYmxlT3V0cHV0LmFtb3VudCgpO1xuXG4gICAgICAgIC8vIFNpbXBsaWZpZWQgYWRkcmVzcyBoYW5kbGluZyBmb3IgRmxhcmVKU1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gJ2ZsYXJlLWFkZHJlc3MtcGxhY2Vob2xkZXInOyAvLyBUT0RPOiBpbXBsZW1lbnQgcHJvcGVyIGFkZHJlc3MgY29udmVyc2lvblxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsdWU6IG91dHB1dEFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIGFkZHJlc3MsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgb3V0cHV0IHR5cGUnKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIHJlbW92ZSBoZXggcHJlZml4ICgweClcbiAgICogQHBhcmFtIGhleCBzdHJpbmdcbiAgICogQHJldHVybnMgaGV4IHdpdGhvdXQgMHhcbiAgICovXG4gIHJlbW92ZUhleFByZWZpeChoZXg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKGhleC5zdGFydHNXaXRoKCcweCcpKSB7XG4gICAgICByZXR1cm4gaGV4LnN1YnN0cmluZygyKTtcbiAgICB9XG4gICAgcmV0dXJuIGhleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdXRwdXRpZHggY29udmVydCBmcm9tIG51bWJlciAoYXMgc3RyaW5nKSB0byBidWZmZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvdXRwdXRpZHggbnVtYmVyXG4gICAqIEByZXR1cm4ge0J1ZmZlcn0gYnVmZmVyIG9mIHNpemUgNCB3aXRoIHRoYXQgbnVtYmVyIHZhbHVlXG4gICAqL1xuICBvdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcihvdXRwdXRpZHg6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKE51bWJlcihvdXRwdXRpZHgpLnRvU3RyaW5nKDE2KS5wYWRTdGFydChPVVRQVVRfSU5ERVhfSEVYX0xFTkdUSCwgJzAnKSwgJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIE91dHB1dGlkeCBidWZmZXIgdG8gbnVtYmVyIChhcyBzdHJpbmcpXG4gICAqIEBwYXJhbSB7QnVmZmVyfSBvdXRwdXRpZHhcbiAgICogQHJldHVybiB7c3RyaW5nfSBvdXRwdXRpZHggbnVtYmVyXG4gICAqL1xuICBvdXRwdXRpZHhCdWZmZXJUb051bWJlcihvdXRwdXRpZHg6IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBhcnNlSW50KG91dHB1dGlkeC50b1N0cmluZygnaGV4JyksIDE2KS50b1N0cmluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENCNTggZGVjb2RlIGZ1bmN0aW9uIC0gc2ltcGxlIEJhc2U1OCBkZWNvZGUgaW1wbGVtZW50YXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEgLSBDQjU4IGVuY29kZWQgc3RyaW5nXG4gICAqIEByZXR1cm5zIHtCdWZmZXJ9IGRlY29kZWQgYnVmZmVyXG4gICAqL1xuICBjYjU4RGVjb2RlKGRhdGE6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgLy8gRm9yIG5vdywgdXNlIGEgc2ltcGxlIGhleCBkZWNvZGUgYXMgcGxhY2Vob2xkZXJcbiAgICAvLyBJbiBhIGZ1bGwgaW1wbGVtZW50YXRpb24sIHRoaXMgd291bGQgYmUgcHJvcGVyIENCNTggZGVjb2RpbmdcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRhdGEsICdoZXgnKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEZhbGxiYWNrIHRvIGJ1ZmZlciBmcm9tIHN0cmluZ1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFkZHJlc3MgYnVmZmVyIHRvIGJlY2gzMiBzdHJpbmdcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhycCAtIEh1bWFuIHJlYWRhYmxlIHBhcnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNoYWluaWQgLSBDaGFpbiBpZGVudGlmaWVyXG4gICAqIEBwYXJhbSB7QnVmZmVyfSBhZGRyZXNzQnVmZmVyIC0gQWRkcmVzcyBidWZmZXJcbiAgICogQHJldHVybnMge3N0cmluZ30gQWRkcmVzcyBzdHJpbmdcbiAgICovXG4gIGFkZHJlc3NUb1N0cmluZyhocnA6IHN0cmluZywgY2hhaW5pZDogc3RyaW5nLCBhZGRyZXNzQnVmZmVyOiBCdWZmZXIpOiBzdHJpbmcge1xuICAgIC8vIFNpbXBsZSBpbXBsZW1lbnRhdGlvbiAtIGluIHByYWN0aWNlIHRoaXMgd291bGQgdXNlIGJlY2gzMiBlbmNvZGluZ1xuICAgIHJldHVybiBgJHtjaGFpbmlkfS0ke2FkZHJlc3NCdWZmZXIudG9TdHJpbmcoJ2hleCcpfWA7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBzdHJpbmcgdG8gYnl0ZXMgZm9yIEZsYXJlSlMgbWVtb1xuICAgKiBGb2xsb3dzIEZsYXJlSlMgdXRpbHMuc3RyaW5nVG9CeXRlcyBwYXR0ZXJuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IC0gVGV4dCB0byBjb252ZXJ0XG4gICAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCeXRlIGFycmF5XG4gICAqL1xuICBzdHJpbmdUb0J5dGVzKHRleHQ6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICAgIHJldHVybiBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUodGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCBieXRlcyB0byBzdHJpbmcgZnJvbSBGbGFyZUpTIG1lbW9cbiAgICogQHBhcmFtIHtVaW50OEFycmF5fSBieXRlcyAtIEJ5dGVzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybnMge3N0cmluZ30gRGVjb2RlZCBzdHJpbmdcbiAgICovXG4gIGJ5dGVzVG9TdHJpbmcoYnl0ZXM6IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICAgIHJldHVybiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYnl0ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBtZW1vIGJ5dGVzIGZyb20gdmFyaW91cyBpbnB1dCBmb3JtYXRzXG4gICAqIFN1cHBvcnRzIHN0cmluZywgSlNPTiBvYmplY3QsIG9yIHJhdyBieXRlc1xuICAgKiBAcGFyYW0ge3N0cmluZyB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgVWludDhBcnJheX0gbWVtbyAtIE1lbW8gZGF0YVxuICAgKiBAcmV0dXJucyB7VWludDhBcnJheX0gTWVtbyBieXRlcyBmb3IgRmxhcmVKU1xuICAgKi9cbiAgY3JlYXRlTWVtb0J5dGVzKG1lbW86IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgVWludDhBcnJheSk6IFVpbnQ4QXJyYXkge1xuICAgIGlmIChtZW1vIGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgcmV0dXJuIG1lbW87XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBtZW1vID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMuc3RyaW5nVG9CeXRlcyhtZW1vKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIG1lbW8gPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdHJpbmdUb0J5dGVzKEpTT04uc3RyaW5naWZ5KG1lbW8pKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgbWVtbyBmb3JtYXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBtZW1vIGJ5dGVzIHRvIHN0cmluZ1xuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IG1lbW9CeXRlcyAtIE1lbW8gYnl0ZXMgZnJvbSBGbGFyZUpTIHRyYW5zYWN0aW9uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IERlY29kZWQgbWVtbyBzdHJpbmdcbiAgICovXG4gIHBhcnNlTWVtb0J5dGVzKG1lbW9CeXRlczogVWludDhBcnJheSk6IHN0cmluZyB7XG4gICAgaWYgKG1lbW9CeXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYnl0ZXNUb1N0cmluZyhtZW1vQnl0ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIG1lbW8gc2l6ZSAoRmxhcmVKUyBoYXMgdHJhbnNhY3Rpb24gc2l6ZSBsaW1pdHMpXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gbWVtb0J5dGVzIC0gTWVtbyBieXRlc1xuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4U2l6ZSAtIE1heGltdW0gc2l6ZSBpbiBieXRlcyAoZGVmYXVsdCA0S0IpXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIG1lbW8gaXMgd2l0aGluIHNpemUgbGltaXRzXG4gICAqL1xuICB2YWxpZGF0ZU1lbW9TaXplKG1lbW9CeXRlczogVWludDhBcnJheSwgbWF4U2l6ZSA9IDQwOTYpOiBib29sZWFuIHtcbiAgICByZXR1cm4gbWVtb0J5dGVzLmxlbmd0aCA8PSBtYXhTaXplO1xuICB9XG59XG5cbmNvbnN0IHV0aWxzID0gbmV3IFV0aWxzKCk7XG5cbmV4cG9ydCBkZWZhdWx0IHV0aWxzO1xuIl19
365
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG1EQUF1RztBQUN2RyxtREFROEI7QUFFOUIsbUNBQWdDO0FBQ2hDLG1DQUFvQztBQUNwQyxxREFBNEM7QUFDNUMsbUNBQWtFO0FBQ2xFLGdEQUF3QjtBQUN4QixtQ0FBZ0M7QUFFaEMsTUFBYSxLQUFLO0lBQWxCO1FBc09FOztXQUVHO1FBQ0ksb0JBQWUsR0FBRyxDQUFDLEdBQVcsRUFBRSxNQUFjLEVBQUUsT0FBZSxFQUFVLEVBQUU7WUFDaEYsK0RBQStEO1lBQy9ELE1BQU0sS0FBSyxHQUFHLGVBQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEMsK0VBQStFO1lBQy9FLE9BQU8sR0FBRyxNQUFNLElBQUksZUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNsRCxDQUFDLENBQUM7UUF5Q0YsbURBQW1EO1FBRW5EOzs7O1dBSUc7UUFDSCwyQ0FBMkM7UUFDcEMsaUJBQVksR0FBRyxDQUFDLE9BQWUsRUFBVSxFQUFFO1lBQ2hELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUM7UUFFSyxvQkFBZSxHQUFHLENBQUMsT0FBZSxFQUFFLEdBQVksRUFBVSxFQUFFO1lBQ2pFLHVCQUF1QjtZQUN2QixJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDN0IsT0FBTyxlQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDOUMsQ0FBQztZQUVELG1DQUFtQztZQUNuQyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUN0QyxPQUFP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M0QsTUFBTSxTQUFTLEdBQUcsZUFBRyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDZixNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFDbEQsQ0FBQztZQUVELE9BQU8sZUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7Q0FDRjtBQXpYRCxzQkF5WEM7QUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0FBQzFCLGtCQUFlLEtBQUssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNpZ25hdHVyZSwgVHJhbnNmZXJhYmxlT3V0cHV0LCBUcmFuc2Zlck91dHB1dCwgVHlwZVN5bWJvbHMsIElkIH0gZnJvbSAnQGZsYXJlbmV0d29yay9mbGFyZWpzJztcbmltcG9ydCB7XG4gIEJhc2VVdGlscyxcbiAgRW50cnksXG4gIEludmFsaWRUcmFuc2FjdGlvbkVycm9yLFxuICBpc1ZhbGlkWHBydixcbiAgaXNWYWxpZFhwdWIsXG4gIE5vdEltcGxlbWVudGVkRXJyb3IsXG4gIFBhcnNlVHJhbnNhY3Rpb25FcnJvcixcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgRmxhcmVOZXR3b3JrIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBCdWZmZXIgfSBmcm9tICdidWZmZXInO1xuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBlY2MgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0IHsgQUREUkVTU19TRVBBUkFUT1IsIE91dHB1dCwgRGVwcmVjYXRlZFR4IH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQgYnM1OCBmcm9tICdiczU4JztcbmltcG9ydCB7IGJlY2gzMiB9IGZyb20gJ2JlY2gzMic7XG5cbmV4cG9ydCBjbGFzcyBVdGlscyBpbXBsZW1lbnRzIEJhc2VVdGlscyB7XG4gIC8qKlxuICAgKiBDaGVjayBpZiBhZGRyZXNzZXMgaW4gd2FsbGV0IG1hdGNoIFVUWE8gb3V0cHV0IGFkZHJlc3Nlc1xuICAgKi9cbiAgcHVibGljIGluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXM6IHN0cmluZ1tdLCBvdHhvT3V0cHV0QWRkcmVzc2VzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB3YWxsZXRBZGRyZXNzZXMubWFwKChhKSA9PiBvdHhvT3V0cHV0QWRkcmVzc2VzLmluY2x1ZGVzKGEpKS5yZWR1Y2UoKGEsIGIpID0+IGEgJiYgYiwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgRmxhcmUgYWRkcmVzcyBvciBhcnJheSBvZiBhZGRyZXNzZXNcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBzdHJpbmdbXX0gYWRkcmVzcyAtIGFkZHJlc3MoZXMpIHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGFkZHJlc3NBcnI6IHN0cmluZ1tdID0gQXJyYXkuaXNBcnJheShhZGRyZXNzKSA/IGFkZHJlc3MgOiBhZGRyZXNzLnNwbGl0KCd+Jyk7XG5cbiAgICBmb3IgKGNvbnN0IGFkZHJlc3Mgb2YgYWRkcmVzc0Fycikge1xuICAgICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzUmVnZXgoYWRkcmVzcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gUmVnZXggcGF0dGVybnNcbiAgLy8gZXhwb3J0IGNvbnN0IEFERFJFU1NfUkVHRVggPSAvXiheUHx8Tm9kZUlEKS1bYS16QS1aMC05XSskLztcbiAgLy8gZXhwb3J0IGNvbnN0IEhFWF9SRUdFWCA9IC9eKDB4KXswLDF9KFswLTlhLWZdKSskL2k7XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkQWRkcmVzc1JlZ2V4KGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAvXiheUHx8Tm9kZUlEKS1bYS16QS1aMC05XSskLy50ZXN0KGFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIGJsb2NrIElEXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBoYXNoIC0gYmxvY2sgSUQgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIGlzVmFsaWRCbG9ja0lkKGhhc2g6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gQnVmZmVyLmZyb20oaGFzaCwgJ2hleCcpO1xuICAgICAgcmV0dXJuIGRlY29kZWQubGVuZ3RoID09PSAzMjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgcHVibGljIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHViIC0gcHVibGljIGtleSB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZFB1YmxpY0tleShwdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmIChpc1ZhbGlkWHB1YihwdWIpKSByZXR1cm4gdHJ1ZTtcblxuICAgIGxldCBwdWJCdWY6IEJ1ZmZlcjtcbiAgICBpZiAocHViLmxlbmd0aCA9PT0gNTApIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHB1YkJ1ZiA9IEJ1ZmZlci5mcm9tKHB1YiwgJ2hleCcpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHB1Yi5sZW5ndGggIT09IDY2ICYmIHB1Yi5sZW5ndGggIT09IDEzMCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBjb25zdCBmaXJzdEJ5dGUgPSBwdWIuc2xpY2UoMCwgMik7XG4gICAgICBpZiAocHViLmxlbmd0aCA9PT0gMTMwICYmIGZpcnN0Qnl0ZSAhPT0gJzA0JykgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKHB1Yi5sZW5ndGggPT09IDY2ICYmIGZpcnN0Qnl0ZSAhPT0gJzAyJyAmJiBmaXJzdEJ5dGUgIT09ICcwMycpIHJldHVybiBmYWxzZTtcbiAgICAgIGlmICghdGhpcy5hbGxIZXhDaGFycyhwdWIpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIHB1YkJ1ZiA9IEJ1ZmZlci5mcm9tKHB1YiwgJ2hleCcpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBlY2MuaXNQb2ludChwdWJCdWYpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJ2IC0gcHJpdmF0ZSBrZXkgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIGlzVmFsaWRQcml2YXRlS2V5KHBydjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzVmFsaWRYcHJ2KHBydikpIHJldHVybiB0cnVlO1xuICAgIGlmIChwcnYubGVuZ3RoICE9PSA2NCAmJiBwcnYubGVuZ3RoICE9PSA2NikgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChwcnYubGVuZ3RoID09PSA2NiAmJiBwcnYuc2xpY2UoNjQpICE9PSAnMDEnKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXMuYWxsSGV4Q2hhcnMocHJ2KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYSBzdHJpbmcgY29udGFpbnMgb25seSBoZXggY2hhcmFjdGVyc1xuICAgKi9cbiAgYWxsSGV4Q2hhcnMoc3RyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gL14oMHgpezAsMX0oWzAtOWEtZl0pKyQvaS50ZXN0KHN0cik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHNpZ25hdHVyZSB1c2luZyB0aGUgRmxhcmUgbmV0d29yayBwYXJhbWV0ZXJzXG4gICAqIFJldHVybnMgYSA2NS1ieXRlIHNpZ25hdHVyZSAoNjQgYnl0ZXMgc2lnbmF0dXJlICsgMSBieXRlIHJlY292ZXJ5IHBhcmFtZXRlcilcbiAgICovXG4gIGNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrOiBGbGFyZU5ldHdvcmssIG1lc3NhZ2U6IEJ1ZmZlciwgcHJ2OiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIGNvbnN0IG1lc3NhZ2VIYXNoID0gdGhpcy5zaGEyNTYobWVzc2FnZSk7XG4gICAgY29uc3Qgc2lnbmF0dXJlID0gZWNjLnNpZ24obWVzc2FnZUhhc2gsIHBydik7XG5cbiAgICAvLyBHZXQgdGhlIHB1YmxpYyBrZXkgZnJvbSB0aGUgcHJpdmF0ZSBrZXkgZm9yIHJlY292ZXJ5IHBhcmFtZXRlciBkZXRlcm1pbmF0aW9uXG4gICAgY29uc3QgcHVibGljS2V5ID0gZWNjLnBvaW50RnJvbVNjYWxhcihwcnYsIHRydWUpO1xuICAgIGlmICghcHVibGljS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBkZXJpdmUgcHVibGljIGtleSBmcm9tIHByaXZhdGUga2V5Jyk7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHJlY292ZXJ5IHdpdGggcGFyYW0gMCBhbmQgMSB0byBmaW5kIHRoZSBjb3JyZWN0IG9uZVxuICAgIGxldCByZWNvdmVyeVBhcmFtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8PSAxOyBpKyspIHtcbiAgICAgIGNvbnN0IHJlY292ZXJlZCA9IGVjYy5yZWNvdmVyUHVibGljS2V5KG1lc3NhZ2VIYXNoLCBzaWduYXR1cmUsIGksIHRydWUpO1xuICAgICAgaWYgKHJlY292ZXJlZCAmJiBCdWZmZXIuZnJvbShyZWNvdmVyZWQpLmVxdWFscyhCdWZmZXIuZnJvbShwdWJsaWNLZXkpKSkge1xuICAgICAgICByZWNvdmVyeVBhcmFtID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQXBwZW5kIHJlY292ZXJ5IHBhcmFtZXRlciB0byBjcmVhdGUgNjUtYnl0ZSBzaWduYXR1cmVcbiAgICBjb25zdCBzaWdXaXRoUmVjb3ZlcnkgPSBCdWZmZXIuYWxsb2MoNjUpO1xuICAgIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZSkuY29weShzaWdXaXRoUmVjb3ZlcnksIDApO1xuICAgIHNpZ1dpdGhSZWNvdmVyeVs2NF0gPSByZWNvdmVyeVBhcmFtO1xuXG4gICAgcmV0dXJuIHNpZ1dpdGhSZWNvdmVyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhIHNpZ25hdHVyZVxuICAgKi9cbiAgdmVyaWZ5U2lnbmF0dXJlKG5ldHdvcms6IEZsYXJlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyLCBzaWduYXR1cmU6IEJ1ZmZlciwgcHVibGljS2V5OiBCdWZmZXIpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbWVzc2FnZUhhc2ggPSB0aGlzLnNoYTI1NihtZXNzYWdlKTtcbiAgICAgIHJldHVybiBlY2MudmVyaWZ5KHNpZ25hdHVyZSwgbWVzc2FnZUhhc2gsIHB1YmxpY0tleSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHNpZ25hdHVyZSBvYmplY3RcbiAgICovXG4gIGNyZWF0ZU5ld1NpZyhzaWdIZXg6IHN0cmluZyk6IFNpZ25hdHVyZSB7XG4gICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oc2lnSGV4LnBhZFN0YXJ0KDEzMCwgJzAnKSwgJ2hleCcpO1xuICAgIHJldHVybiBuZXcgU2lnbmF0dXJlKGJ1ZmZlcik7XG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgU0hBMjU2IGhhc2hcbiAgICovXG4gIHNoYTI1NihidWY6IFVpbnQ4QXJyYXkpOiBCdWZmZXIge1xuICAgIHJldHVybiBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoYnVmKS5kaWdlc3QoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgcmF3IHRyYW5zYWN0aW9uIGZvcm1hdFxuICAgKi9cbiAgdmFsaWRhdGVSYXdUcmFuc2FjdGlvbihyYXdUcmFuc2FjdGlvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFyYXdUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdSYXcgdHJhbnNhY3Rpb24gaXMgZW1wdHknKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmFsbEhleENoYXJzKHJhd1RyYW5zYWN0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlVHJhbnNhY3Rpb25FcnJvcignUmF3IHRyYW5zYWN0aW9uIGlzIG5vdCBoZXggc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBvdXRwdXQgaXMgVHJhbnNmZXJhYmxlT3V0cHV0IHR5cGVcbiAgICovXG4gIGlzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dDogT3V0cHV0KTogb3V0cHV0IGlzIFRyYW5zZmVyYWJsZU91dHB1dCB7XG4gICAgcmV0dXJuIG91dHB1dD8uX3R5cGUgPT09IFR5cGVTeW1ib2xzLlRyYW5zZmVyYWJsZU91dHB1dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXBzIG91dHB1dHMgdG8gZW50cnkgZm9ybWF0XG4gICAqL1xuICBtYXBPdXRwdXRUb0VudHJ5KG5ldHdvcms6IEZsYXJlTmV0d29yayk6IChPdXRwdXQpID0+IEVudHJ5IHtcbiAgICByZXR1cm4gKG91dHB1dDogT3V0cHV0KSA9PiB7XG4gICAgICBpZiAodGhpcy5pc1RyYW5zZmVyYWJsZU91dHB1dChvdXRwdXQpKSB7XG4gICAgICAgIGNvbnN0IG91dHB1dEFtb3VudCA9IG91dHB1dC5hbW91bnQoKTtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IChvdXRwdXQub3V0cHV0IGFzIFRyYW5zZmVyT3V0cHV0KVxuICAgICAgICAgIC5nZXRPd25lcnMoKVxuICAgICAgICAgIC5tYXAoKGEpID0+IHRoaXMuYWRkcmVzc1RvU3RyaW5nKG5ldHdvcmsuaHJwLCBuZXR3b3JrLmFsaWFzLCBCdWZmZXIuZnJvbShhKSkpXG4gICAgICAgICAgLnNvcnQoKVxuICAgICAgICAgIC5qb2luKEFERFJFU1NfU0VQQVJBVE9SKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2YWx1ZTogb3V0cHV0QW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgYWRkcmVzcyxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBvdXRwdXQgdHlwZScpO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyAweCBwcmVmaXggZnJvbSBoZXggc3RyaW5nXG4gICAqL1xuICByZW1vdmVIZXhQcmVmaXgoaGV4OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBoZXguc3RhcnRzV2l0aCgnMHgnKSA/IGhleC5zdWJzdHJpbmcoMikgOiBoZXg7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb3V0cHV0IGluZGV4IHRvIGJ1ZmZlclxuICAgKi9cbiAgb3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIob3V0cHV0aWR4OiBzdHJpbmcpOiBCdWZmZXIge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShOdW1iZXIob3V0cHV0aWR4KS50b1N0cmluZygxNikucGFkU3RhcnQoOCwgJzAnKSwgJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG91dHB1dCBpbmRleCBidWZmZXIgdG8gbnVtYmVyIHN0cmluZ1xuICAgKi9cbiAgb3V0cHV0aWR4QnVmZmVyVG9OdW1iZXIob3V0cHV0aWR4OiBCdWZmZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBwYXJzZUludChvdXRwdXRpZHgudG9TdHJpbmcoJ2hleCcpLCAxNikudG9TdHJpbmcoKTtcbiAgfVxuXG4gIC8vIFJlcXVpcmVkIGJ5IEJhc2VVdGlscyBpbnRlcmZhY2UgYnV0IG5vdCBpbXBsZW1lbnRlZFxuICBpc1ZhbGlkU2lnbmF0dXJlKHNpZ25hdHVyZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IE5vdEltcGxlbWVudGVkRXJyb3IoJ2lzVmFsaWRTaWduYXR1cmUgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICBpc1ZhbGlkVHJhbnNhY3Rpb25JZCh0eElkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgTm90SW1wbGVtZW50ZWRFcnJvcignaXNWYWxpZFRyYW5zYWN0aW9uSWQgbm90IGltcGxlbWVudGVkJyk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIG1ldGhvZCB0byBjb252ZXJ0IGFkZHJlc3MgY29tcG9uZW50cyB0byBzdHJpbmdcbiAgICovXG4gIHB1YmxpYyBhZGRyZXNzVG9TdHJpbmcgPSAoaHJwOiBzdHJpbmcsIHByZWZpeDogc3RyaW5nLCBhZGRyZXNzOiBCdWZmZXIpOiBzdHJpbmcgPT4ge1xuICAgIC8vIENvbnZlcnQgdGhlIGFkZHJlc3MgYnl0ZXMgdG8gNS1iaXQgd29yZHMgZm9yIGJlY2gzMiBlbmNvZGluZ1xuICAgIGNvbnN0IHdvcmRzID0gYmVjaDMyLnRvV29yZHMoYWRkcmVzcyk7XG4gICAgLy8gQ3JlYXRlIHRoZSBmdWxsIGJlY2gzMiBhZGRyZXNzIHdpdGggZm9ybWF0OiBQLXtocnB9MXtiZWNoMzJfZW5jb2RlZF9hZGRyZXNzfVxuICAgIHJldHVybiBgJHtwcmVmaXh9LSR7YmVjaDMyLmVuY29kZShocnAsIHdvcmRzKX1gO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGVzIGEgYmFzZTU4IHN0cmluZyB3aXRoIGNoZWNrc3VtIHRvIGEgQnVmZmVyXG4gICAqL1xuICBwdWJsaWMgY2I1OERlY29kZShzdHI6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgY29uc3QgZGVjb2RlZCA9IGJzNTguZGVjb2RlKHN0cik7XG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlQ2hlY2tzdW0oQnVmZmVyLmZyb20oZGVjb2RlZCkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2hlY2tzdW0nKTtcbiAgICB9XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlY29kZWQuc2xpY2UoMCwgZGVjb2RlZC5sZW5ndGggLSA0KSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgY2hlY2tzdW0gb24gYSBCdWZmZXIgYW5kIHJldHVybnMgdHJ1ZSBpZiB2YWxpZCwgZmFsc2UgaWYgbm90XG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlQ2hlY2tzdW0oYnVmZjogQnVmZmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaGFzaFNsaWNlID0gYnVmZi5zbGljZShidWZmLmxlbmd0aCAtIDQpO1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRIYXNoU2xpY2UgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKVxuICAgICAgLnVwZGF0ZShidWZmLnNsaWNlKDAsIGJ1ZmYubGVuZ3RoIC0gNCkpXG4gICAgICAuZGlnZXN0KClcbiAgICAgIC5zbGljZSgyOCk7XG4gICAgcmV0dXJuIGhhc2hTbGljZS50b1N0cmluZygnaGV4JykgPT09IGNhbGN1bGF0ZWRIYXNoU2xpY2UudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZXMgYSBCdWZmZXIgYXMgYSBiYXNlNTggc3RyaW5nIHdpdGggY2hlY2tzdW1cbiAgICovXG4gIHB1YmxpYyBjYjU4RW5jb2RlKGJ5dGVzOiBCdWZmZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHdpdGhDaGVja3N1bSA9IHRoaXMuYWRkQ2hlY2tzdW0oYnl0ZXMpO1xuICAgIHJldHVybiBiczU4LmVuY29kZSh3aXRoQ2hlY2tzdW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjaGVja3N1bSB0byBhIEJ1ZmZlciBhbmQgcmV0dXJucyB0aGUgY29uY2F0ZW5hdGVkIHJlc3VsdFxuICAgKi9cbiAgcHJpdmF0ZSBhZGRDaGVja3N1bShidWZmOiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIGNvbnN0IGhhc2hTbGljZSA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShidWZmKS5kaWdlc3QoKS5zbGljZSgyOCk7XG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW2J1ZmYsIGhhc2hTbGljZV0pO1xuICB9XG5cbiAgLy8gSW4gdXRpbHMudHMsIGFkZCB0aGlzIG1ldGhvZCB0byB0aGUgVXRpbHMgY2xhc3M6XG5cbiAgLyoqXG4gICAqIFBhcnNlIGFuIGFkZHJlc3Mgc3RyaW5nIGludG8gYSBCdWZmZXJcbiAgICogQHBhcmFtIGFkZHJlc3MgLSBUaGUgYWRkcmVzcyB0byBwYXJzZVxuICAgKiBAcmV0dXJucyBCdWZmZXIgY29udGFpbmluZyB0aGUgcGFyc2VkIGFkZHJlc3NcbiAgICovXG4gIC8vVE9ETzogbmVlZCBjaGVjayBhbmQgdmFsaWRhdGUgdGhpcyBtZXRob2RcbiAgcHVibGljIHBhcnNlQWRkcmVzcyA9IChhZGRyZXNzOiBzdHJpbmcpOiBCdWZmZXIgPT4ge1xuICAgIHJldHVybiB0aGlzLnN0cmluZ1RvQWRkcmVzcyhhZGRyZXNzKTtcbiAgfTtcblxuICBwdWJsaWMgc3RyaW5nVG9BZGRyZXNzID0gKGFkZHJlc3M6IHN0cmluZywgaHJwPzogc3RyaW5nKTogQnVmZmVyID0+IHtcbiAgICAvLyBIYW5kbGUgaGV4IGFkZHJlc3Nlc1xuICAgIGlmIChhZGRyZXNzLnN0YXJ0c1dpdGgoJzB4JykpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbShhZGRyZXNzLnNsaWNlKDIpLCAnaGV4Jyk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHJhdyBoZXggd2l0aG91dCAweCBwcmVmaXhcbiAgICBpZiAoL15bMC05YS1mQS1GXXs0MH0kLy50ZXN0KGFkZHJlc3MpKSB7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20oYWRkcmVzcywgJ2hleCcpO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBCZWNoMzIgYWRkcmVzc2VzXG4gICAgY29uc3QgcGFydHMgPSBhZGRyZXNzLnRyaW0oKS5zcGxpdCgnLScpO1xuICAgIGlmIChwYXJ0cy5sZW5ndGggPCAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIC0gVmFsaWQgYWRkcmVzcyBzaG91bGQgaW5jbHVkZSAtJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3BsaXQgPSBwYXJ0c1sxXS5sYXN0SW5kZXhPZignMScpO1xuICAgIGlmIChzcGxpdCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXJyb3IgLSBWYWxpZCBiZWNoMzIgYWRkcmVzcyBtdXN0IGluY2x1ZGUgc2VwYXJhdG9yICgxKScpO1xuICAgIH1cblxuICAgIGNvbnN0IGh1bWFuUmVhZGFibGVQYXJ0ID0gcGFydHNbMV0uc2xpY2UoMCwgc3BsaXQpO1xuICAgIGlmIChodW1hblJlYWRhYmxlUGFydCAhPT0gJ2ZsYXJlJyAmJiBodW1hblJlYWRhYmxlUGFydCAhPT0gJ2Nvc3R3bycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXJyb3IgLSBJbnZhbGlkIEhSUCcpO1xuICAgIH1cblxuICAgIHJldHVybiBCdWZmZXIuZnJvbShiZWNoMzIuZnJvbVdvcmRzKGJlY2gzMi5kZWNvZGUocGFydHNbMV0pLndvcmRzKSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHR4IGlzIGZvciB0aGUgYmxvY2tjaGFpbklkXG4gICAqXG4gICAqIEBwYXJhbSB7RGVwcmVjYXRlZFR4fSB0eFxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmxvY2tjaGFpbklkXG4gICAqIEByZXR1cm5zIHRydWUgaWYgdHggaXMgZm9yIGJsb2NrY2hhaW5JZFxuICAgKi9cbiAgLy8gVE9ETzogcmVtb3ZlIERlcHJlY2F0ZWRUeCB1c2FnZVxuICBpc1RyYW5zYWN0aW9uT2YodHg6IERlcHJlY2F0ZWRUeCwgYmxvY2tjaGFpbklkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyBGbGFyZUpTIGVxdWl2YWxlbnQgLSB0aGlzIHdvdWxkIG5lZWQgcHJvcGVyIENCNTggZW5jb2RpbmcgaW1wbGVtZW50YXRpb25cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHhSZWNvcmQgPSB0eCBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgY29uc3QgdW5zaWduZWRUeCA9ICh0eFJlY29yZC5nZXRVbnNpZ25lZFR4IGFzICgpID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSgpO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAodW5zaWduZWRUeC5nZXRUcmFuc2FjdGlvbiBhcyAoKSA9PiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikoKTtcbiAgICAgIGNvbnN0IHR4QmxvY2tjaGFpbklkID0gKHRyYW5zYWN0aW9uLmdldEJsb2NrY2hhaW5JRCBhcyAoKSA9PiB1bmtub3duKSgpO1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHR4QmxvY2tjaGFpbklkIGFzIHN0cmluZykudG9TdHJpbmcoJ2hleCcpID09PSBibG9ja2NoYWluSWQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBmbGFyZUlkU3RyaW5nKHZhbHVlOiBzdHJpbmcpOiBJZCB7XG4gICAgcmV0dXJuIG5ldyBJZChCdWZmZXIuZnJvbSh2YWx1ZSwgJ2hleCcpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFyZUpTIHdyYXBwZXIgdG8gcmVjb3ZlciBzaWduYXR1cmVcbiAgICogQHBhcmFtIG5ldHdvcmtcbiAgICogQHBhcmFtIG1lc3NhZ2VcbiAgICogQHBhcmFtIHNpZ25hdHVyZVxuICAgKiBAcmV0dXJuIHJlY292ZXJlZCBwdWJsaWMga2V5XG4gICAqL1xuICByZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrOiBGbGFyZU5ldHdvcmssIG1lc3NhZ2U6IEJ1ZmZlciwgc2lnbmF0dXJlOiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIHRyeSB7XG4gICAgICAvLyBIYXNoIHRoZSBtZXNzYWdlIGZpcnN0IC0gbXVzdCBtYXRjaCB0aGUgaGFzaCB1c2VkIGluIHNpZ25pbmdcbiAgICAgIGNvbnN0IG1lc3NhZ2VIYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKG1lc3NhZ2UpLmRpZ2VzdCgpO1xuXG4gICAgICAvLyBFeHRyYWN0IHJlY292ZXJ5IHBhcmFtZXRlciBhbmQgc2lnbmF0dXJlXG4gICAgICBpZiAoc2lnbmF0dXJlLmxlbmd0aCAhPT0gNjUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBsZW5ndGggLSBleHBlY3RlZCA2NSBieXRlcyAoNjQgYnl0ZXMgc2lnbmF0dXJlICsgMSBieXRlIHJlY292ZXJ5KScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtID0gc2lnbmF0dXJlWzY0XTtcbiAgICAgIGNvbnN0IHNpZ09ubHkgPSBzaWduYXR1cmUuc2xpY2UoMCwgNjQpO1xuXG4gICAgICAvLyBSZWNvdmVyIHB1YmxpYyBrZXkgdXNpbmcgdGhlIHByb3ZpZGVkIHJlY292ZXJ5IHBhcmFtZXRlclxuICAgICAgY29uc3QgcmVjb3ZlcmVkID0gZWNjLnJlY292ZXJQdWJsaWNLZXkobWVzc2FnZUhhc2gsIHNpZ09ubHksIHJlY292ZXJ5UGFyYW0sIHRydWUpO1xuICAgICAgaWYgKCFyZWNvdmVyZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVjb3ZlciBwdWJsaWMga2V5Jyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbShyZWNvdmVyZWQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byByZWNvdmVyIHNpZ25hdHVyZTogJHtlcnJvcn1gKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgdXRpbHMgPSBuZXcgVXRpbHMoKTtcbmV4cG9ydCBkZWZhdWx0IHV0aWxzO1xuIl19