@bitgo-beta/sdk-coin-flrp 1.0.1-beta.9 → 1.0.1-beta.90

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 (91) hide show
  1. package/dist/src/flrp.d.ts +82 -61
  2. package/dist/src/flrp.d.ts.map +1 -1
  3. package/dist/src/flrp.js +293 -134
  4. package/dist/src/lib/atomicTransactionBuilder.d.ts +42 -6
  5. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
  6. package/dist/src/lib/atomicTransactionBuilder.js +233 -29
  7. package/dist/src/lib/constants.d.ts +160 -1
  8. package/dist/src/lib/constants.d.ts.map +1 -1
  9. package/dist/src/lib/constants.js +213 -3
  10. package/dist/src/lib/delegatorTxBuilder.d.ts +58 -0
  11. package/dist/src/lib/delegatorTxBuilder.d.ts.map +1 -0
  12. package/dist/src/lib/delegatorTxBuilder.js +224 -0
  13. package/dist/src/lib/exportInCTxBuilder.d.ts +1 -1
  14. package/dist/src/lib/exportInCTxBuilder.d.ts.map +1 -1
  15. package/dist/src/lib/exportInCTxBuilder.js +46 -17
  16. package/dist/src/lib/exportInPTxBuilder.d.ts +1 -1
  17. package/dist/src/lib/exportInPTxBuilder.d.ts.map +1 -1
  18. package/dist/src/lib/exportInPTxBuilder.js +70 -6
  19. package/dist/src/lib/iface.d.ts +52 -1
  20. package/dist/src/lib/iface.d.ts.map +1 -1
  21. package/dist/src/lib/iface.js +1 -1
  22. package/dist/src/lib/importInCTxBuilder.d.ts +67 -0
  23. package/dist/src/lib/importInCTxBuilder.d.ts.map +1 -0
  24. package/dist/src/lib/importInCTxBuilder.js +403 -0
  25. package/dist/src/lib/importInPTxBuilder.d.ts +73 -0
  26. package/dist/src/lib/importInPTxBuilder.d.ts.map +1 -0
  27. package/dist/src/lib/importInPTxBuilder.js +464 -0
  28. package/dist/src/lib/index.d.ts +7 -0
  29. package/dist/src/lib/index.d.ts.map +1 -1
  30. package/dist/src/lib/index.js +15 -2
  31. package/dist/src/lib/keyPair.d.ts.map +1 -1
  32. package/dist/src/lib/keyPair.js +4 -6
  33. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +81 -0
  34. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
  35. package/dist/src/lib/permissionlessValidatorTxBuilder.js +248 -0
  36. package/dist/src/lib/transaction.d.ts +111 -0
  37. package/dist/src/lib/transaction.d.ts.map +1 -0
  38. package/dist/src/lib/transaction.js +322 -0
  39. package/dist/src/lib/transactionBuilder.d.ts +85 -0
  40. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  41. package/dist/src/lib/transactionBuilder.js +167 -0
  42. package/dist/src/lib/transactionBuilderFactory.d.ts +37 -0
  43. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  44. package/dist/src/lib/transactionBuilderFactory.js +91 -0
  45. package/dist/src/lib/types.d.ts +78 -0
  46. package/dist/src/lib/types.d.ts.map +1 -0
  47. package/dist/src/lib/types.js +5 -0
  48. package/dist/src/lib/utils.d.ts +59 -0
  49. package/dist/src/lib/utils.d.ts.map +1 -1
  50. package/dist/src/lib/utils.js +160 -52
  51. package/dist/src/lib/validatorTxBuilder.d.ts +40 -0
  52. package/dist/src/lib/validatorTxBuilder.d.ts.map +1 -0
  53. package/dist/src/lib/validatorTxBuilder.js +180 -0
  54. package/dist/test/unit/delegatorTxBuilder.test.d.ts +2 -0
  55. package/dist/test/unit/delegatorTxBuilder.test.d.ts.map +1 -0
  56. package/dist/test/unit/delegatorTxBuilder.test.js +233 -0
  57. package/dist/test/unit/lib/atomicTransactionBuilder.js +37 -11
  58. package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
  59. package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
  60. package/dist/test/unit/lib/exportInCTxBuilder.js +584 -0
  61. package/dist/test/unit/lib/exportInPTxBuilder.d.ts +2 -0
  62. package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -0
  63. package/dist/test/unit/lib/exportInPTxBuilder.js +377 -0
  64. package/dist/test/unit/lib/importInCTxBuilder.d.ts +2 -0
  65. package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -0
  66. package/dist/test/unit/lib/importInCTxBuilder.js +257 -0
  67. package/dist/test/unit/lib/importInPTxBuilder.d.ts +2 -0
  68. package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -0
  69. package/dist/test/unit/lib/importInPTxBuilder.js +500 -0
  70. package/dist/test/unit/lib/transaction.d.ts +2 -0
  71. package/dist/test/unit/lib/transaction.d.ts.map +1 -0
  72. package/dist/test/unit/lib/transaction.js +460 -0
  73. package/dist/test/unit/lib/utils.js +55 -1
  74. package/dist/test/unit/permissionlessValidatorTxBuilder.test.d.ts +2 -0
  75. package/dist/test/unit/permissionlessValidatorTxBuilder.test.d.ts.map +1 -0
  76. package/dist/test/unit/permissionlessValidatorTxBuilder.test.js +271 -0
  77. package/dist/test/unit/transactionBuilder.test.d.ts +2 -0
  78. package/dist/test/unit/transactionBuilder.test.d.ts.map +1 -0
  79. package/dist/test/unit/transactionBuilder.test.js +114 -0
  80. package/dist/test/unit/validatorTxBuilder.test.d.ts +2 -0
  81. package/dist/test/unit/validatorTxBuilder.test.d.ts.map +1 -0
  82. package/dist/test/unit/validatorTxBuilder.test.js +293 -0
  83. package/dist/tsconfig.tsbuildinfo +1 -1
  84. package/package.json +11 -11
  85. package/.eslintignore +0 -5
  86. package/.eslintrc.json +0 -7
  87. package/.mocharc.yml +0 -8
  88. package/CHANGELOG.md +0 -0
  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
@@ -0,0 +1,322 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Transaction = void 0;
7
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
8
+ const buffer_1 = require("buffer");
9
+ const iface_1 = require("./iface");
10
+ const utils_1 = __importDefault(require("./utils"));
11
+ const constants_1 = require("./constants");
12
+ /**
13
+ * Flare P-chain transaction implementation using FlareJS
14
+ * Based on AVAX transaction patterns adapted for Flare network
15
+ */
16
+ class Transaction extends sdk_core_1.BaseTransaction {
17
+ constructor(coinConfig) {
18
+ super(coinConfig);
19
+ this._threshold = 2;
20
+ this._locktime = BigInt(0);
21
+ this._fromAddresses = [];
22
+ this._rewardAddresses = [];
23
+ this._utxos = [];
24
+ this._fee = {};
25
+ this._memo = new Uint8Array(); // FlareJS memo field
26
+ this._network = coinConfig.network;
27
+ this._assetId = constants_1.FLR_ASSET_ID; // Default FLR asset
28
+ this._blockchainID = this._network.blockchainID || '';
29
+ this._networkID = this._network.networkID || 0;
30
+ }
31
+ /**
32
+ * Get the base transaction from FlareJS UnsignedTx
33
+ * TODO: Implement proper FlareJS transaction extraction
34
+ */
35
+ get flareTransaction() {
36
+ return this._flareTransaction;
37
+ }
38
+ get signature() {
39
+ if (this.credentials.length === 0) {
40
+ return [];
41
+ }
42
+ // TODO: Extract signatures from FlareJS credentials
43
+ // For now, return placeholder
44
+ return [];
45
+ }
46
+ get credentials() {
47
+ // TODO: Extract credentials from FlareJS transaction
48
+ // For now, return empty array
49
+ return [];
50
+ }
51
+ get hasCredentials() {
52
+ return this.credentials !== undefined && this.credentials.length > 0;
53
+ }
54
+ /** @inheritdoc */
55
+ canSign({ key }) {
56
+ // TODO: Implement proper signing validation for FlareJS
57
+ return true;
58
+ }
59
+ /**
60
+ * Sign a Flare transaction using FlareJS
61
+ * @param {KeyPair} keyPair
62
+ */
63
+ async sign(keyPair) {
64
+ const prv = keyPair.getPrivateKey();
65
+ if (!prv) {
66
+ throw new sdk_core_1.SigningError('Missing private key');
67
+ }
68
+ if (!this.flareTransaction) {
69
+ throw new sdk_core_1.InvalidTransactionError('empty transaction to sign');
70
+ }
71
+ if (!this.hasCredentials) {
72
+ throw new sdk_core_1.InvalidTransactionError('empty credentials to sign');
73
+ }
74
+ // TODO: Implement FlareJS signing process
75
+ // This will involve:
76
+ // 1. Creating FlareJS signature using private key
77
+ // 2. Attaching signature to appropriate credential
78
+ // 3. Updating transaction with signed credentials
79
+ throw new Error('FlareJS signing not yet implemented - placeholder');
80
+ }
81
+ /**
82
+ * Set memo from string
83
+ * @param {string} memo - Memo text
84
+ */
85
+ setMemo(memo) {
86
+ this._memo = utils_1.default.stringToBytes(memo);
87
+ }
88
+ /**
89
+ * Set memo from various formats
90
+ * @param {string | Record<string, unknown> | Uint8Array} memo - Memo data
91
+ */
92
+ setMemoData(memo) {
93
+ this._memo = utils_1.default.createMemoBytes(memo);
94
+ }
95
+ /**
96
+ * Get memo as bytes (FlareJS format)
97
+ * @returns {Uint8Array} Memo bytes
98
+ */
99
+ getMemoBytes() {
100
+ return this._memo;
101
+ }
102
+ /**
103
+ * Get memo as string
104
+ * @returns {string} Memo string
105
+ */
106
+ getMemoString() {
107
+ return utils_1.default.parseMemoBytes(this._memo);
108
+ }
109
+ /**
110
+ * Check if transaction has memo
111
+ * @returns {boolean} Whether memo exists and is not empty
112
+ */
113
+ hasMemo() {
114
+ return this._memo.length > 0;
115
+ }
116
+ toHexString(byteArray) {
117
+ return buffer_1.Buffer.from(byteArray).toString(constants_1.HEX_ENCODING);
118
+ }
119
+ /** @inheritdoc */
120
+ toBroadcastFormat() {
121
+ if (!this.flareTransaction) {
122
+ throw new sdk_core_1.InvalidTransactionError('Empty transaction data');
123
+ }
124
+ // TODO: Implement FlareJS transaction serialization
125
+ // For now, return placeholder
126
+ return constants_1.FLARE_TX_HEX_PLACEHOLDER;
127
+ }
128
+ toJson() {
129
+ if (!this.flareTransaction) {
130
+ throw new sdk_core_1.InvalidTransactionError('Empty transaction data');
131
+ }
132
+ return {
133
+ id: this.id,
134
+ inputs: this.inputs,
135
+ fromAddresses: this.fromAddresses,
136
+ threshold: this._threshold,
137
+ locktime: this._locktime.toString(),
138
+ type: this.type,
139
+ signatures: this.signature,
140
+ outputs: this.outputs,
141
+ changeOutputs: this.changeOutputs,
142
+ sourceChain: this._network.blockchainID,
143
+ destinationChain: this._network.cChainBlockchainID,
144
+ memo: this.getMemoString(), // Include memo in JSON representation
145
+ };
146
+ }
147
+ setTransaction(tx) {
148
+ this._flareTransaction = tx;
149
+ }
150
+ /**
151
+ * Set the transaction type
152
+ * @param {TransactionType} transactionType The transaction type to be set
153
+ */
154
+ setTransactionType(transactionType) {
155
+ const supportedTypes = [
156
+ sdk_core_1.TransactionType.Export,
157
+ sdk_core_1.TransactionType.Import,
158
+ sdk_core_1.TransactionType.AddValidator,
159
+ sdk_core_1.TransactionType.AddDelegator,
160
+ sdk_core_1.TransactionType.AddPermissionlessValidator,
161
+ sdk_core_1.TransactionType.AddPermissionlessDelegator,
162
+ ];
163
+ if (!supportedTypes.includes(transactionType)) {
164
+ throw new Error(`Transaction type ${transactionType} is not supported`);
165
+ }
166
+ this._type = transactionType;
167
+ }
168
+ /**
169
+ * Returns the portion of the transaction that needs to be signed in Buffer format.
170
+ * Only needed for coins that support adding signatures directly (e.g. TSS).
171
+ */
172
+ get signablePayload() {
173
+ if (!this.flareTransaction) {
174
+ throw new sdk_core_1.InvalidTransactionError('Empty transaction for signing');
175
+ }
176
+ // TODO: Implement FlareJS signable payload extraction
177
+ // For now, return placeholder
178
+ return buffer_1.Buffer.from(constants_1.FLARE_SIGNABLE_PAYLOAD);
179
+ }
180
+ get id() {
181
+ if (!this.flareTransaction) {
182
+ throw new sdk_core_1.InvalidTransactionError('Empty transaction for ID generation');
183
+ }
184
+ // TODO: Implement FlareJS transaction ID generation
185
+ // For now, return placeholder
186
+ return constants_1.FLARE_TRANSACTION_ID_PLACEHOLDER;
187
+ }
188
+ get fromAddresses() {
189
+ return this._fromAddresses.map((address) => {
190
+ // TODO: Format addresses using FlareJS utilities
191
+ return address;
192
+ });
193
+ }
194
+ get rewardAddresses() {
195
+ return this._rewardAddresses.map((address) => {
196
+ // TODO: Format addresses using FlareJS utilities
197
+ return address;
198
+ });
199
+ }
200
+ /**
201
+ * Get the list of outputs. Amounts are expressed in absolute value.
202
+ */
203
+ get outputs() {
204
+ switch (this.type) {
205
+ case sdk_core_1.TransactionType.Export:
206
+ // TODO: Extract export outputs from FlareJS transaction
207
+ return [];
208
+ case sdk_core_1.TransactionType.Import:
209
+ // TODO: Extract import outputs from FlareJS transaction
210
+ return [];
211
+ case sdk_core_1.TransactionType.AddValidator:
212
+ case sdk_core_1.TransactionType.AddPermissionlessValidator:
213
+ // TODO: Extract validator outputs from FlareJS transaction
214
+ return [
215
+ {
216
+ address: this._nodeID || constants_1.PLACEHOLDER_NODE_ID,
217
+ value: this._stakeAmount?.toString() || '0',
218
+ },
219
+ ];
220
+ case sdk_core_1.TransactionType.AddDelegator:
221
+ case sdk_core_1.TransactionType.AddPermissionlessDelegator:
222
+ // TODO: Extract delegator outputs from FlareJS transaction
223
+ return [
224
+ {
225
+ address: this._nodeID || constants_1.PLACEHOLDER_NODE_ID,
226
+ value: this._stakeAmount?.toString() || '0',
227
+ },
228
+ ];
229
+ default:
230
+ return [];
231
+ }
232
+ }
233
+ get fee() {
234
+ return { fee: '0', ...this._fee };
235
+ }
236
+ get changeOutputs() {
237
+ // TODO: Extract change outputs from FlareJS transaction
238
+ // For now, return empty array
239
+ return [];
240
+ }
241
+ get inputs() {
242
+ // TODO: Extract inputs from FlareJS transaction
243
+ // For now, return placeholder based on UTXOs
244
+ return this._utxos.map((utxo) => ({
245
+ id: utxo.txid + iface_1.INPUT_SEPARATOR + utxo.outputidx,
246
+ address: this.fromAddresses.sort().join(iface_1.ADDRESS_SEPARATOR),
247
+ value: utxo.amount,
248
+ }));
249
+ }
250
+ /**
251
+ * Flare wrapper to create signature and return it for credentials
252
+ * @param prv
253
+ * @return hexstring
254
+ */
255
+ createSignature(prv) {
256
+ // TODO: Implement FlareJS signature creation
257
+ // This should use FlareJS signing utilities
258
+ const signval = utils_1.default.createSignature(this._network, this.signablePayload, prv);
259
+ return signval.toString(constants_1.HEX_ENCODING);
260
+ }
261
+ /**
262
+ * Check if transaction is for C-chain (cross-chain)
263
+ */
264
+ get isTransactionForCChain() {
265
+ return this.type === sdk_core_1.TransactionType.Export || this.type === sdk_core_1.TransactionType.Import;
266
+ }
267
+ /** @inheritdoc */
268
+ explainTransaction() {
269
+ const txJson = this.toJson();
270
+ const displayOrder = [...constants_1.DISPLAY_ORDER_BASE];
271
+ // Add memo to display order if present
272
+ if (this.hasMemo()) {
273
+ displayOrder.push(constants_1.MEMO_FIELD);
274
+ }
275
+ // Calculate total output amount
276
+ const outputAmount = txJson.outputs
277
+ .reduce((sum, output) => {
278
+ return sum + BigInt(output.value || '0');
279
+ }, BigInt(0))
280
+ .toString();
281
+ // Calculate total change amount
282
+ const changeAmount = txJson.changeOutputs
283
+ .reduce((sum, output) => {
284
+ return sum + BigInt(output.value || '0');
285
+ }, BigInt(0))
286
+ .toString();
287
+ let rewardAddresses;
288
+ const stakingTypes = [
289
+ sdk_core_1.TransactionType.AddValidator,
290
+ sdk_core_1.TransactionType.AddDelegator,
291
+ sdk_core_1.TransactionType.AddPermissionlessValidator,
292
+ sdk_core_1.TransactionType.AddPermissionlessDelegator,
293
+ ];
294
+ if (stakingTypes.includes(txJson.type)) {
295
+ rewardAddresses = this.rewardAddresses;
296
+ displayOrder.splice(6, 0, constants_1.REWARD_ADDRESSES_FIELD);
297
+ }
298
+ // Add cross-chain information for export/import
299
+ if (this.isTransactionForCChain) {
300
+ displayOrder.push(constants_1.SOURCE_CHAIN_FIELD, constants_1.DESTINATION_CHAIN_FIELD);
301
+ }
302
+ const explanation = {
303
+ displayOrder,
304
+ id: txJson.id,
305
+ inputs: txJson.inputs,
306
+ outputs: txJson.outputs.map((o) => ({ address: o.address, amount: o.value })),
307
+ outputAmount,
308
+ changeOutputs: txJson.changeOutputs.map((o) => ({ address: o.address, amount: o.value })),
309
+ changeAmount,
310
+ rewardAddresses,
311
+ fee: this.fee,
312
+ type: txJson.type,
313
+ };
314
+ // Add memo to explanation if present
315
+ if (this.hasMemo()) {
316
+ explanation.memo = this.getMemoString();
317
+ }
318
+ return explanation;
319
+ }
320
+ }
321
+ exports.Transaction = Transaction;
322
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLG1EQVE4QjtBQUU5QixtQ0FBZ0M7QUFDaEMsbUNBUWlCO0FBRWpCLG9EQUE0QjtBQUM1QiwyQ0FZcUI7QUFFckI7OztHQUdHO0FBQ0gsTUFBYSxXQUFZLFNBQVEsMEJBQWU7SUFzQjlDLFlBQVksVUFBZ0M7UUFDMUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBWmIsZUFBVSxHQUFHLENBQUMsQ0FBQztRQUNmLGNBQVMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsbUJBQWMsR0FBYSxFQUFFLENBQUM7UUFDOUIscUJBQWdCLEdBQWEsRUFBRSxDQUFDO1FBQ2hDLFdBQU0sR0FBcUIsRUFBRSxDQUFDO1FBRTlCLFNBQUksR0FBNEIsRUFBRSxDQUFDO1FBR25DLFVBQUssR0FBZSxJQUFJLFVBQVUsRUFBRSxDQUFDLENBQUMscUJBQXFCO1FBSWhFLElBQUksQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDLE9BQXVCLENBQUM7UUFDbkQsSUFBSSxDQUFDLFFBQVEsR0FBRyx3QkFBWSxDQUFDLENBQUMsb0JBQW9CO1FBQ2xELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLElBQUksRUFBRSxDQUFDO1FBQ3RELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJLGdCQUFnQjtRQUNsQixPQUFPLElBQUksQ0FBQyxpQkFBK0IsQ0FBQztJQUM5QyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxPQUFPLEVBQUUs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QUksSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDbkIsV0FBVyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDMUMsQ0FBQztRQUVELE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7Q0FDRjtBQTVXRCxrQ0E0V0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBVbnNpZ25lZFR4LCBDcmVkZW50aWFsIH0gZnJvbSAnQGZsYXJlbmV0d29yay9mbGFyZWpzJztcbmltcG9ydCB7XG4gIEJhc2VLZXksXG4gIEJhc2VUcmFuc2FjdGlvbixcbiAgRW50cnksXG4gIEludmFsaWRUcmFuc2FjdGlvbkVycm9yLFxuICBTaWduaW5nRXJyb3IsXG4gIFRyYW5zYWN0aW9uRmVlLFxuICBUcmFuc2FjdGlvblR5cGUsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEZsYXJlTmV0d29yaywgQmFzZUNvaW4gYXMgQ29pbkNvbmZpZyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnYnVmZmVyJztcbmltcG9ydCB7XG4gIEFERFJFU1NfU0VQQVJBVE9SLFxuICBEZWNvZGVkVXR4b09iaixcbiAgSU5QVVRfU0VQQVJBVE9SLFxuICBUcmFuc2FjdGlvbkV4cGxhbmF0aW9uLFxuICBUeCxcbiAgVHhEYXRhLFxuICBGbHJwRW50cnksXG59IGZyb20gJy4vaWZhY2UnO1xuaW1wb3J0IHsgS2V5UGFpciB9IGZyb20gJy4va2V5UGFpcic7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge1xuICBGTFJfQVNTRVRfSUQsXG4gIEZMQVJFX1RYX0hFWF9QTEFDRUhPTERFUixcbiAgRkxBUkVfU0lHTkFCTEVfUEFZTE9BRCxcbiAgRkxBUkVfVFJBTlNBQ1RJT05fSURfUExBQ0VIT0xERVIsXG4gIFBMQUNFSE9MREVSX05PREVfSUQsXG4gIEhFWF9FTkNPRElORyxcbiAgTUVNT19GSUVMRCxcbiAgRElTUExBWV9PUkRFUl9CQVNFLFxuICBSRVdBUkRfQUREUkVTU0VTX0ZJRUxELFxuICBTT1VSQ0VfQ0hBSU5fRklFTEQsXG4gIERFU1RJTkFUSU9OX0NIQUlOX0ZJRUxELFxufSBmcm9tICcuL2NvbnN0YW50cyc7XG5cbi8qKlxuICogRmxhcmUgUC1jaGFpbiB0cmFuc2FjdGlvbiBpbXBsZW1lbnRhdGlvbiB1c2luZyBGbGFyZUpTXG4gKiBCYXNlZCBvbiBBVkFYIHRyYW5zYWN0aW9uIHBhdHRlcm5zIGFkYXB0ZWQgZm9yIEZsYXJlIG5ldHdvcmtcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uIHtcbiAgcHJvdGVjdGVkIF9mbGFyZVRyYW5zYWN0aW9uOiBUeDtcbiAgcHVibGljIF90eXBlOiBUcmFuc2FjdGlvblR5cGU7XG4gIHB1YmxpYyBfbmV0d29yazogRmxhcmVOZXR3b3JrO1xuICBwdWJsaWMgX25ldHdvcmtJRDogbnVtYmVyO1xuICBwdWJsaWMgX2Fzc2V0SWQ6IHN0cmluZztcbiAgcHVibGljIF9ibG9ja2NoYWluSUQ6IHN0cmluZztcbiAgcHVibGljIF9ub2RlSUQ6IHN0cmluZztcbiAgcHVibGljIF9zdGFydFRpbWU6IGJpZ2ludDtcbiAgcHVibGljIF9lbmRUaW1lOiBiaWdpbnQ7XG4gIHB1YmxpYyBfc3Rha2VBbW91bnQ6IGJpZ2ludDtcbiAgcHVibGljIF90aHJlc2hvbGQgPSAyO1xuICBwdWJsaWMgX2xvY2t0aW1lID0gQmlnSW50KDApO1xuICBwdWJsaWMgX2Zyb21BZGRyZXNzZXM6IHN0cmluZ1tdID0gW107XG4gIHB1YmxpYyBfcmV3YXJkQWRkcmVzc2VzOiBzdHJpbmdbXSA9IFtdO1xuICBwdWJsaWMgX3V0eG9zOiBEZWNvZGVkVXR4b09ialtdID0gW107XG4gIHB1YmxpYyBfdG86IHN0cmluZ1tdO1xuICBwdWJsaWMgX2ZlZTogUGFydGlhbDxUcmFuc2FjdGlvbkZlZT4gPSB7fTtcbiAgcHVibGljIF9ibHNQdWJsaWNLZXk6IHN0cmluZztcbiAgcHVibGljIF9ibHNTaWduYXR1cmU6IHN0cmluZztcbiAgcHVibGljIF9tZW1vOiBVaW50OEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoKTsgLy8gRmxhcmVKUyBtZW1vIGZpZWxkXG5cbiAgY29uc3RydWN0b3IoY29pbkNvbmZpZzogUmVhZG9ubHk8Q29pbkNvbmZpZz4pIHtcbiAgICBzdXBlcihjb2luQ29uZmlnKTtcbiAgICB0aGlzLl9uZXR3b3JrID0gY29pbkNvbmZpZy5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcbiAgICB0aGlzLl9hc3NldElkID0gRkxSX0FTU0VUX0lEOyAvLyBEZWZhdWx0IEZMUiBhc3NldFxuICAgIHRoaXMuX2Jsb2NrY2hhaW5JRCA9IHRoaXMuX25ldHdvcmsuYmxvY2tjaGFpbklEIHx8ICcnO1xuICAgIHRoaXMuX25ldHdvcmtJRCA9IHRoaXMuX25ldHdvcmsubmV0d29ya0lEIHx8IDA7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBiYXNlIHRyYW5zYWN0aW9uIGZyb20gRmxhcmVKUyBVbnNpZ25lZFR4XG4gICAqIFRPRE86IEltcGxlbWVudCBwcm9wZXIgRmxhcmVKUyB0cmFuc2FjdGlvbiBleHRyYWN0aW9uXG4gICAqL1xuICBnZXQgZmxhcmVUcmFuc2FjdGlvbigpOiBVbnNpZ25lZFR4IHtcbiAgICByZXR1cm4gdGhpcy5fZmxhcmVUcmFuc2FjdGlvbiBhcyBVbnNpZ25lZFR4O1xuICB9XG5cbiAgZ2V0IHNpZ25hdHVyZSgpOiBzdHJpbmdbXSB7XG4gICAgaWYgKHRoaXMuY3JlZGVudGlhbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8vIFRPRE86IEV4dHJhY3Qgc2lnbmF0dXJlcyBmcm9tIEZsYXJlSlMgY3JlZGVudGlhbHNcbiAgICAvLyBGb3Igbm93LCByZXR1cm4gcGxhY2Vob2xkZXJcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgY3JlZGVudGlhbHMoKTogQ3JlZGVudGlhbFtdIHtcbiAgICAvLyBUT0RPOiBFeHRyYWN0IGNyZWRlbnRpYWxzIGZyb20gRmxhcmVKUyB0cmFuc2FjdGlvblxuICAgIC8vIEZvciBub3csIHJldHVybiBlbXB0eSBhcnJheVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGdldCBoYXNDcmVkZW50aWFscygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jcmVkZW50aWFscyAhPT0gdW5kZWZpbmVkICYmIHRoaXMuY3JlZGVudGlhbHMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBjYW5TaWduKHsga2V5IH06IEJhc2VLZXkpOiBib29sZWFuIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgcHJvcGVyIHNpZ25pbmcgdmFsaWRhdGlvbiBmb3IgRmxhcmVKU1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNpZ24gYSBGbGFyZSB0cmFuc2FjdGlvbiB1c2luZyBGbGFyZUpTXG4gICAqIEBwYXJhbSB7S2V5UGFpcn0ga2V5UGFpclxuICAgKi9cbiAgYXN5bmMgc2lnbihrZXlQYWlyOiBLZXlQYWlyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcHJ2ID0ga2V5UGFpci5nZXRQcml2YXRlS2V5KCkgYXMgQnVmZmVyO1xuXG4gICAgaWYgKCFwcnYpIHtcbiAgICAgIHRocm93IG5ldyBTaWduaW5nRXJyb3IoJ01pc3NpbmcgcHJpdmF0ZSBrZXknKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZmxhcmVUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdlbXB0eSB0cmFuc2FjdGlvbiB0byBzaWduJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmhhc0NyZWRlbnRpYWxzKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ2VtcHR5IGNyZWRlbnRpYWxzIHRvIHNpZ24nKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgRmxhcmVKUyBzaWduaW5nIHByb2Nlc3NcbiAgICAvLyBUaGlzIHdpbGwgaW52b2x2ZTpcbiAgICAvLyAxLiBDcmVhdGluZyBGbGFyZUpTIHNpZ25hdHVyZSB1c2luZyBwcml2YXRlIGtleVxuICAgIC8vIDIuIEF0dGFjaGluZyBzaWduYXR1cmUgdG8gYXBwcm9wcmlhdGUgY3JlZGVudGlhbFxuICAgIC8vIDMuIFVwZGF0aW5nIHRyYW5zYWN0aW9uIHdpdGggc2lnbmVkIGNyZWRlbnRpYWxzXG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXJlSlMgc2lnbmluZyBub3QgeWV0IGltcGxlbWVudGVkIC0gcGxhY2Vob2xkZXInKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgbWVtbyBmcm9tIHN0cmluZ1xuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVtbyAtIE1lbW8gdGV4dFxuICAgKi9cbiAgc2V0TWVtbyhtZW1vOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9tZW1vID0gdXRpbHMuc3RyaW5nVG9CeXRlcyhtZW1vKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgbWVtbyBmcm9tIHZhcmlvdXMgZm9ybWF0c1xuICAgKiBAcGFyYW0ge3N0cmluZyB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgVWludDhBcnJheX0gbWVtbyAtIE1lbW8gZGF0YVxuICAgKi9cbiAgc2V0TWVtb0RhdGEobWVtbzogc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBVaW50OEFycmF5KTogdm9pZCB7XG4gICAgdGhpcy5fbWVtbyA9IHV0aWxzLmNyZWF0ZU1lbW9CeXRlcyhtZW1vKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbWVtbyBhcyBieXRlcyAoRmxhcmVKUyBmb3JtYXQpXG4gICAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBNZW1vIGJ5dGVzXG4gICAqL1xuICBnZXRNZW1vQnl0ZXMoKTogVWludDhBcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuX21lbW87XG4gIH1cblxuICAvKipcbiAgICogR2V0IG1lbW8gYXMgc3RyaW5nXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IE1lbW8gc3RyaW5nXG4gICAqL1xuICBnZXRNZW1vU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHV0aWxzLnBhcnNlTWVtb0J5dGVzKHRoaXMuX21lbW8pO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRyYW5zYWN0aW9uIGhhcyBtZW1vXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIG1lbW8gZXhpc3RzIGFuZCBpcyBub3QgZW1wdHlcbiAgICovXG4gIGhhc01lbW8oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX21lbW8ubGVuZ3RoID4gMDtcbiAgfVxuXG4gIHRvSGV4U3RyaW5nKGJ5dGVBcnJheTogVWludDhBcnJheSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJ5dGVBcnJheSkudG9TdHJpbmcoSEVYX0VOQ09ESU5HKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB0b0Jyb2FkY2FzdEZvcm1hdCgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5mbGFyZVRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uIGRhdGEnKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgRmxhcmVKUyB0cmFuc2FjdGlvbiBzZXJpYWxpemF0aW9uXG4gICAgLy8gRm9yIG5vdywgcmV0dXJuIHBsYWNlaG9sZGVyXG4gICAgcmV0dXJuIEZMQVJFX1RYX0hFWF9QTEFDRUhPTERFUjtcbiAgfVxuXG4gIHRvSnNvbigpOiBUeERhdGEge1xuICAgIGlmICghdGhpcy5mbGFyZVRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uIGRhdGEnKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHRoaXMuaWQsXG4gICAgICBpbnB1dHM6IHRoaXMuaW5wdXRzLFxuICAgICAgZnJvbUFkZHJlc3NlczogdGhpcy5mcm9tQWRkcmVzc2VzLFxuICAgICAgdGhyZXNob2xkOiB0aGlzLl90aHJlc2hvbGQsXG4gICAgICBsb2NrdGltZTogdGhpcy5fbG9ja3RpbWUudG9TdHJpbmcoKSxcbiAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIHNpZ25hdHVyZXM6IHRoaXMuc2lnbmF0dXJlLFxuICAgICAgb3V0cHV0czogdGhpcy5vdXRwdXRzLFxuICAgICAgY2hhbmdlT3V0cHV0czogdGhpcy5jaGFuZ2VPdXRwdXRzLFxuICAgICAgc291cmNlQ2hhaW46IHRoaXMuX25ldHdvcmsuYmxvY2tjaGFpbklELFxuICAgICAgZGVzdGluYXRpb25DaGFpbjogdGhpcy5fbmV0d29yay5jQ2hhaW5CbG9ja2NoYWluSUQsXG4gICAgICBtZW1vOiB0aGlzLmdldE1lbW9TdHJpbmcoKSwgLy8gSW5jbHVkZSBtZW1vIGluIEpTT04gcmVwcmVzZW50YXRpb25cbiAgICB9O1xuICB9XG5cbiAgc2V0VHJhbnNhY3Rpb24odHg6IFR4KTogdm9pZCB7XG4gICAgdGhpcy5fZmxhcmVUcmFuc2FjdGlvbiA9IHR4O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgdHJhbnNhY3Rpb24gdHlwZVxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uVHlwZX0gdHJhbnNhY3Rpb25UeXBlIFRoZSB0cmFuc2FjdGlvbiB0eXBlIHRvIGJlIHNldFxuICAgKi9cbiAgc2V0VHJhbnNhY3Rpb25UeXBlKHRyYW5zYWN0aW9uVHlwZTogVHJhbnNhY3Rpb25UeXBlKTogdm9pZCB7XG4gICAgY29uc3Qgc3VwcG9ydGVkVHlwZXMgPSBbXG4gICAgICBUcmFuc2FjdGlvblR5cGUuRXhwb3J0LFxuICAgICAgVHJhbnNhY3Rpb25UeXBlLkltcG9ydCxcbiAgICAgIFRyYW5zYWN0aW9uVHlwZS5BZGRWYWxpZGF0b3IsXG4gICAgICBUcmFuc2FjdGlvblR5cGUuQWRkRGVsZWdhdG9yLFxuICAgICAgVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzVmFsaWRhdG9yLFxuICAgICAgVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzRGVsZWdhdG9yLFxuICAgIF07XG5cbiAgICBpZiAoIXN1cHBvcnRlZFR5cGVzLmluY2x1ZGVzKHRyYW5zYWN0aW9uVHlwZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVHJhbnNhY3Rpb24gdHlwZSAke3RyYW5zYWN0aW9uVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIH1cbiAgICB0aGlzLl90eXBlID0gdHJhbnNhY3Rpb25UeXBlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHBvcnRpb24gb2YgdGhlIHRyYW5zYWN0aW9uIHRoYXQgbmVlZHMgdG8gYmUgc2lnbmVkIGluIEJ1ZmZlciBmb3JtYXQuXG4gICAqIE9ubHkgbmVlZGVkIGZvciBjb2lucyB0aGF0IHN1cHBvcnQgYWRkaW5nIHNpZ25hdHVyZXMgZGlyZWN0bHkgKGUuZy4gVFNTKS5cbiAgICovXG4gIGdldCBzaWduYWJsZVBheWxvYWQoKTogQnVmZmVyIHtcbiAgICBpZiAoIXRoaXMuZmxhcmVUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdFbXB0eSB0cmFuc2FjdGlvbiBmb3Igc2lnbmluZycpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IEltcGxlbWVudCBGbGFyZUpTIHNpZ25hYmxlIHBheWxvYWQgZXh0cmFjdGlvblxuICAgIC8vIEZvciBub3csIHJldHVybiBwbGFjZWhvbGRlclxuICAgIHJldHVybiBCdWZmZXIuZnJvbShGTEFSRV9TSUdOQUJMRV9QQVlMT0FEKTtcbiAgfVxuXG4gIGdldCBpZCgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5mbGFyZVRyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ0VtcHR5IHRyYW5zYWN0aW9uIGZvciBJRCBnZW5lcmF0aW9uJyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogSW1wbGVtZW50IEZsYXJlSlMgdHJhbnNhY3Rpb24gSUQgZ2VuZXJhdGlvblxuICAgIC8vIEZvciBub3csIHJldHVybiBwbGFjZWhvbGRlclxuICAgIHJldHVybiBGTEFSRV9UUkFOU0FDVElPTl9JRF9QTEFDRUhPTERFUjtcbiAgfVxuXG4gIGdldCBmcm9tQWRkcmVzc2VzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fZnJvbUFkZHJlc3Nlcy5tYXAoKGFkZHJlc3MpID0+IHtcbiAgICAgIC8vIFRPRE86IEZvcm1hdCBhZGRyZXNzZXMgdXNpbmcgRmxhcmVKUyB1dGlsaXRpZXNcbiAgICAgIHJldHVybiBhZGRyZXNzO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHJld2FyZEFkZHJlc3NlcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3Jld2FyZEFkZHJlc3Nlcy5tYXAoKGFkZHJlc3MpID0+IHtcbiAgICAgIC8vIFRPRE86IEZvcm1hdCBhZGRyZXNzZXMgdXNpbmcgRmxhcmVKUyB1dGlsaXRpZXNcbiAgICAgIHJldHVybiBhZGRyZXNzO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbGlzdCBvZiBvdXRwdXRzLiBBbW91bnRzIGFyZSBleHByZXNzZWQgaW4gYWJzb2x1dGUgdmFsdWUuXG4gICAqL1xuICBnZXQgb3V0cHV0cygpOiBFbnRyeVtdIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRXhwb3J0OlxuICAgICAgICAvLyBUT0RPOiBFeHRyYWN0IGV4cG9ydCBvdXRwdXRzIGZyb20gRmxhcmVKUyB0cmFuc2FjdGlvblxuICAgICAgICByZXR1cm4gW107XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5JbXBvcnQ6XG4gICAgICAgIC8vIFRPRE86IEV4dHJhY3QgaW1wb3J0IG91dHB1dHMgZnJvbSBGbGFyZUpTIHRyYW5zYWN0aW9uXG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkFkZFZhbGlkYXRvcjpcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzVmFsaWRhdG9yOlxuICAgICAgICAvLyBUT0RPOiBFeHRyYWN0IHZhbGlkYXRvciBvdXRwdXRzIGZyb20gRmxhcmVKUyB0cmFuc2FjdGlvblxuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IHRoaXMuX25vZGVJRCB8fCBQTEFDRUhPTERFUl9OT0RFX0lELFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuX3N0YWtlQW1vdW50Py50b1N0cmluZygpIHx8ICcwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuQWRkRGVsZWdhdG9yOlxuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuQWRkUGVybWlzc2lvbmxlc3NEZWxlZ2F0b3I6XG4gICAgICAgIC8vIFRPRE86IEV4dHJhY3QgZGVsZWdhdG9yIG91dHB1dHMgZnJvbSBGbGFyZUpTIHRyYW5zYWN0aW9uXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogdGhpcy5fbm9kZUlEIHx8IFBMQUNFSE9MREVSX05PREVfSUQsXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5fc3Rha2VBbW91bnQ/LnRvU3RyaW5nKCkgfHwgJzAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF07XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbiAgZ2V0IGZlZSgpOiBUcmFuc2FjdGlvbkZlZSB7XG4gICAgcmV0dXJuIHsgZmVlOiAnMCcsIC4uLnRoaXMuX2ZlZSB9O1xuICB9XG5cbiAgZ2V0IGNoYW5nZU91dHB1dHMoKTogRW50cnlbXSB7XG4gICAgLy8gVE9ETzogRXh0cmFjdCBjaGFuZ2Ugb3V0cHV0cyBmcm9tIEZsYXJlSlMgdHJhbnNhY3Rpb25cbiAgICAvLyBGb3Igbm93LCByZXR1cm4gZW1wdHkgYXJyYXlcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBnZXQgaW5wdXRzKCk6IEZscnBFbnRyeVtdIHtcbiAgICAvLyBUT0RPOiBFeHRyYWN0IGlucHV0cyBmcm9tIEZsYXJlSlMgdHJhbnNhY3Rpb25cbiAgICAvLyBGb3Igbm93LCByZXR1cm4gcGxhY2Vob2xkZXIgYmFzZWQgb24gVVRYT3NcbiAgICByZXR1cm4gdGhpcy5fdXR4b3MubWFwKCh1dHhvKSA9PiAoe1xuICAgICAgaWQ6IHV0eG8udHhpZCArIElOUFVUX1NFUEFSQVRPUiArIHV0eG8ub3V0cHV0aWR4LFxuICAgICAgYWRkcmVzczogdGhpcy5mcm9tQWRkcmVzc2VzLnNvcnQoKS5qb2luKEFERFJFU1NfU0VQQVJBVE9SKSxcbiAgICAgIHZhbHVlOiB1dHhvLmFtb3VudCxcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogRmxhcmUgd3JhcHBlciB0byBjcmVhdGUgc2lnbmF0dXJlIGFuZCByZXR1cm4gaXQgZm9yIGNyZWRlbnRpYWxzXG4gICAqIEBwYXJhbSBwcnZcbiAgICogQHJldHVybiBoZXhzdHJpbmdcbiAgICovXG4gIGNyZWF0ZVNpZ25hdHVyZShwcnY6IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgLy8gVE9ETzogSW1wbGVtZW50IEZsYXJlSlMgc2lnbmF0dXJlIGNyZWF0aW9uXG4gICAgLy8gVGhpcyBzaG91bGQgdXNlIEZsYXJlSlMgc2lnbmluZyB1dGlsaXRpZXNcbiAgICBjb25zdCBzaWdudmFsID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKHRoaXMuX25ldHdvcmssIHRoaXMuc2lnbmFibGVQYXlsb2FkLCBwcnYpO1xuICAgIHJldHVybiBzaWdudmFsLnRvU3RyaW5nKEhFWF9FTkNPRElORyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdHJhbnNhY3Rpb24gaXMgZm9yIEMtY2hhaW4gKGNyb3NzLWNoYWluKVxuICAgKi9cbiAgZ2V0IGlzVHJhbnNhY3Rpb25Gb3JDQ2hhaW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLkV4cG9ydCB8fCB0aGlzLnR5cGUgPT09IFRyYW5zYWN0aW9uVHlwZS5JbXBvcnQ7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgZXhwbGFpblRyYW5zYWN0aW9uKCk6IFRyYW5zYWN0aW9uRXhwbGFuYXRpb24ge1xuICAgIGNvbnN0IHR4SnNvbiA9IHRoaXMudG9Kc29uKCk7XG4gICAgY29uc3QgZGlzcGxheU9yZGVyID0gWy4uLkRJU1BMQVlfT1JERVJfQkFTRV07XG5cbiAgICAvLyBBZGQgbWVtbyB0byBkaXNwbGF5IG9yZGVyIGlmIHByZXNlbnRcbiAgICBpZiAodGhpcy5oYXNNZW1vKCkpIHtcbiAgICAgIGRpc3BsYXlPcmRlci5wdXNoKE1FTU9fRklFTEQpO1xuICAgIH1cblxuICAgIC8vIENhbGN1bGF0ZSB0b3RhbCBvdXRwdXQgYW1vdW50XG4gICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gdHhKc29uLm91dHB1dHNcbiAgICAgIC5yZWR1Y2UoKHN1bSwgb3V0cHV0KSA9PiB7XG4gICAgICAgIHJldHVybiBzdW0gKyBCaWdJbnQob3V0cHV0LnZhbHVlIHx8ICcwJyk7XG4gICAgICB9LCBCaWdJbnQoMCkpXG4gICAgICAudG9TdHJpbmcoKTtcblxuICAgIC8vIENhbGN1bGF0ZSB0b3RhbCBjaGFuZ2UgYW1vdW50XG4gICAgY29uc3QgY2hhbmdlQW1vdW50ID0gdHhKc29uLmNoYW5nZU91dHB1dHNcbiAgICAgIC5yZWR1Y2UoKHN1bSwgb3V0cHV0KSA9PiB7XG4gICAgICAgIHJldHVybiBzdW0gKyBCaWdJbnQob3V0cHV0LnZhbHVlIHx8ICcwJyk7XG4gICAgICB9LCBCaWdJbnQoMCkpXG4gICAgICAudG9TdHJpbmcoKTtcblxuICAgIGxldCByZXdhcmRBZGRyZXNzZXM7XG4gICAgY29uc3Qgc3Rha2luZ1R5cGVzID0gW1xuICAgICAgVHJhbnNhY3Rpb25UeXBlLkFkZFZhbGlkYXRvcixcbiAgICAgIFRyYW5zYWN0aW9uVHlwZS5BZGREZWxlZ2F0b3IsXG4gICAgICBUcmFuc2FjdGlvblR5cGUuQWRkUGVybWlzc2lvbmxlc3NWYWxpZGF0b3IsXG4gICAgICBUcmFuc2FjdGlvblR5cGUuQWRkUGVybWlzc2lvbmxlc3NEZWxlZ2F0b3IsXG4gICAgXTtcblxuICAgIGlmIChzdGFraW5nVHlwZXMuaW5jbHVkZXModHhKc29uLnR5cGUpKSB7XG4gICAgICByZXdhcmRBZGRyZXNzZXMgPSB0aGlzLnJld2FyZEFkZHJlc3NlcztcbiAgICAgIGRpc3BsYXlPcmRlci5zcGxpY2UoNiwgMCwgUkVXQVJEX0FERFJFU1NFU19GSUVMRCk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGNyb3NzLWNoYWluIGluZm9ybWF0aW9uIGZvciBleHBvcnQvaW1wb3J0XG4gICAgaWYgKHRoaXMuaXNUcmFuc2FjdGlvbkZvckNDaGFpbikge1xuICAgICAgZGlzcGxheU9yZGVyLnB1c2goU09VUkNFX0NIQUlOX0ZJRUxELCBERVNUSU5BVElPTl9DSEFJTl9GSUVMRCk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhwbGFuYXRpb246IFRyYW5zYWN0aW9uRXhwbGFuYXRpb24gJiB7IG1lbW8/OiBzdHJpbmcgfSA9IHtcbiAgICAgIGRpc3BsYXlPcmRlcixcbiAgICAgIGlkOiB0eEpzb24uaWQsXG4gICAgICBpbnB1dHM6IHR4SnNvbi5pbnB1dHMsXG4gICAgICBvdXRwdXRzOiB0eEpzb24ub3V0cHV0cy5tYXAoKG8pID0+ICh7IGFkZHJlc3M6IG8uYWRkcmVzcywgYW1vdW50OiBvLnZhbHVlIH0pKSxcbiAgICAgIG91dHB1dEFtb3VudCxcbiAgICAgIGNoYW5nZU91dHB1dHM6IHR4SnNvbi5jaGFuZ2VPdXRwdXRzLm1hcCgobykgPT4gKHsgYWRkcmVzczogby5hZGRyZXNzLCBhbW91bnQ6IG8udmFsdWUgfSkpLFxuICAgICAgY2hhbmdlQW1vdW50LFxuICAgICAgcmV3YXJkQWRkcmVzc2VzLFxuICAgICAgZmVlOiB0aGlzLmZlZSxcbiAgICAgIHR5cGU6IHR4SnNvbi50eXBlLFxuICAgIH07XG5cbiAgICAvLyBBZGQgbWVtbyB0byBleHBsYW5hdGlvbiBpZiBwcmVzZW50XG4gICAgaWYgKHRoaXMuaGFzTWVtbygpKSB7XG4gICAgICBleHBsYW5hdGlvbi5tZW1vID0gdGhpcy5nZXRNZW1vU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV4cGxhbmF0aW9uO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,85 @@
1
+ import { BaseTransactionBuilder } from '@bitgo-beta/sdk-core';
2
+ import { BaseCoin as CoinConfig } from '@bitgo-beta/statics';
3
+ import { DecodedUtxoObj, Tx } from './iface';
4
+ import { KeyPair } from './keyPair';
5
+ import { Transaction } from './transaction';
6
+ export declare abstract class TransactionBuilder extends BaseTransactionBuilder {
7
+ protected _transaction: Transaction;
8
+ protected recoverSigner: boolean;
9
+ _signer: KeyPair[];
10
+ protected _recoveryMode: boolean;
11
+ constructor(_coinConfig: Readonly<CoinConfig>);
12
+ /**
13
+ * Initialize the transaction builder fields using the decoded transaction data
14
+ *
15
+ * @param {Tx} tx the transaction data
16
+ * @returns itself
17
+ */
18
+ initBuilder(tx: Tx): this;
19
+ /**
20
+ * Validates the threshold
21
+ * @param threshold
22
+ */
23
+ validateThreshold(threshold: number): void;
24
+ /**
25
+ * Check the UTXO has expected fields.
26
+ * @param UTXO
27
+ */
28
+ validateUtxo(value: DecodedUtxoObj): void;
29
+ /**
30
+ * Check the list of UTXOS is empty and check each UTXO.
31
+ * @param values
32
+ */
33
+ validateUtxos(values: DecodedUtxoObj[]): void;
34
+ /**
35
+ * Validates locktime
36
+ * @param locktime
37
+ */
38
+ validateLocktime(locktime: bigint): void;
39
+ /**
40
+ * Threshold is an int that names the number of unique signatures required to spend the output.
41
+ * Must be less than or equal to the length of Addresses.
42
+ * @param {number} value
43
+ */
44
+ threshold(value: number): this;
45
+ /**
46
+ * Locktime is a long that contains the unix timestamp that this output can be spent after.
47
+ * The unix timestamp is specific to the second.
48
+ * @param value
49
+ */
50
+ locktime(value: string | number): this;
51
+ /**
52
+ * When using recovery key must be set here
53
+ * @param {boolean}[recoverSigner=true] whether it's recovery signer
54
+ */
55
+ recoverMode(recoverSigner?: boolean): this;
56
+ /**
57
+ * fromPubKey is a list of unique addresses that correspond to the private keys that can be used to spend this output
58
+ * @param {string | string[]} senderPubKey
59
+ */
60
+ fromPubKey(senderPubKey: string | string[]): this;
61
+ /**
62
+ * List of UTXO required as inputs.
63
+ * A UTXO is a standalone representation of a transaction output.
64
+ *
65
+ * @param {DecodedUtxoObj[]} list of UTXOS
66
+ */
67
+ utxos(value: DecodedUtxoObj[]): this;
68
+ /**
69
+ * Build the Flare transaction using FlareJS API
70
+ * @protected
71
+ */
72
+ protected abstract buildFlareTransaction(): Promise<void> | void;
73
+ /** @inheritdoc */
74
+ protected fromImplementation(rawTransaction: string): Transaction;
75
+ /**
76
+ * Get the transaction instance
77
+ */
78
+ get transaction(): Transaction;
79
+ /**
80
+ * Validate required fields before building transaction
81
+ * @protected
82
+ */
83
+ protected validateRequiredFields(): void;
84
+ }
85
+ //# sourceMappingURL=transactionBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transactionBuilder.d.ts","sourceRoot":"","sources":["../../../src/lib/transactionBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAyB,MAAM,sBAAsB,CAAC;AACrF,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAiB5C,8BAAsB,kBAAmB,SAAQ,sBAAsB;IACrE,SAAS,CAAC,YAAY,EAAE,WAAW,CAAC;IACpC,SAAS,CAAC,aAAa,UAAS;IACzB,OAAO,EAAE,OAAO,EAAE,CAAM;IAG/B,SAAS,CAAC,aAAa,UAAS;gBAEpB,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC;IAK7C;;;;;OAKG;IACH,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI;IAyBzB;;;OAGG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM1C;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAMzC;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI;IAO7C;;;OAGG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOxC;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAMtC;;;OAGG;IACH,WAAW,CAAC,aAAa,UAAO,GAAG,IAAI;IAYvC;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAMjD;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI;IAMpC;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAEhE,kBAAkB;IAClB,SAAS,CAAC,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW;IAajE;;OAEG;IACH,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED;;;OAGG;IACH,SAAS,CAAC,sBAAsB,IAAI,IAAI;CAQzC"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransactionBuilder = void 0;
4
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
+ const transaction_1 = require("./transaction");
6
+ const constants_1 = require("./constants");
7
+ class TransactionBuilder extends sdk_core_1.BaseTransactionBuilder {
8
+ constructor(_coinConfig) {
9
+ super(_coinConfig);
10
+ this.recoverSigner = false;
11
+ this._signer = [];
12
+ // Recovery mode flag for transaction building
13
+ this._recoveryMode = false;
14
+ this._transaction = new transaction_1.Transaction(_coinConfig);
15
+ }
16
+ /**
17
+ * Initialize the transaction builder fields using the decoded transaction data
18
+ *
19
+ * @param {Tx} tx the transaction data
20
+ * @returns itself
21
+ */
22
+ initBuilder(tx) {
23
+ // Validate network and blockchain IDs if available
24
+ const txData = tx;
25
+ if (txData.networkID !== undefined && txData.networkID !== this._transaction._networkID) {
26
+ throw new Error(constants_1.ERROR_NETWORK_ID_MISMATCH);
27
+ }
28
+ if (txData.blockchainID) {
29
+ const blockchainID = Buffer.isBuffer(txData.blockchainID)
30
+ ? txData.blockchainID
31
+ : Buffer.from(txData.blockchainID, constants_1.HEX_ENCODING);
32
+ const transactionBlockchainID = Buffer.isBuffer(this._transaction._blockchainID)
33
+ ? this._transaction._blockchainID
34
+ : Buffer.from(this._transaction._blockchainID, constants_1.HEX_ENCODING);
35
+ if (!blockchainID.equals(transactionBlockchainID)) {
36
+ throw new Error(constants_1.ERROR_BLOCKCHAIN_ID_MISMATCH_BUILDER);
37
+ }
38
+ }
39
+ this._transaction.setTransaction(tx);
40
+ return this;
41
+ }
42
+ // region Validators
43
+ /**
44
+ * Validates the threshold
45
+ * @param threshold
46
+ */
47
+ validateThreshold(threshold) {
48
+ if (!threshold || threshold !== 2) {
49
+ throw new sdk_core_1.BuildTransactionError(constants_1.ERROR_INVALID_THRESHOLD);
50
+ }
51
+ }
52
+ /**
53
+ * Check the UTXO has expected fields.
54
+ * @param UTXO
55
+ */
56
+ validateUtxo(value) {
57
+ constants_1.UTXO_REQUIRED_FIELDS.forEach((field) => {
58
+ if (!value.hasOwnProperty(field))
59
+ throw new sdk_core_1.BuildTransactionError(`${constants_1.ERROR_UTXOS_MISSING_FIELD} ${field}`);
60
+ });
61
+ }
62
+ /**
63
+ * Check the list of UTXOS is empty and check each UTXO.
64
+ * @param values
65
+ */
66
+ validateUtxos(values) {
67
+ if (values.length === 0) {
68
+ throw new sdk_core_1.BuildTransactionError(constants_1.ERROR_UTXOS_EMPTY_ARRAY);
69
+ }
70
+ values.forEach(this.validateUtxo);
71
+ }
72
+ /**
73
+ * Validates locktime
74
+ * @param locktime
75
+ */
76
+ validateLocktime(locktime) {
77
+ if (!locktime || locktime < BigInt(0)) {
78
+ throw new sdk_core_1.BuildTransactionError(constants_1.ERROR_INVALID_LOCKTIME);
79
+ }
80
+ }
81
+ // endregion
82
+ /**
83
+ * Threshold is an int that names the number of unique signatures required to spend the output.
84
+ * Must be less than or equal to the length of Addresses.
85
+ * @param {number} value
86
+ */
87
+ threshold(value) {
88
+ this.validateThreshold(value);
89
+ this._transaction._threshold = value;
90
+ return this;
91
+ }
92
+ /**
93
+ * Locktime is a long that contains the unix timestamp that this output can be spent after.
94
+ * The unix timestamp is specific to the second.
95
+ * @param value
96
+ */
97
+ locktime(value) {
98
+ this.validateLocktime(BigInt(value));
99
+ this._transaction._locktime = BigInt(value);
100
+ return this;
101
+ }
102
+ /**
103
+ * When using recovery key must be set here
104
+ * @param {boolean}[recoverSigner=true] whether it's recovery signer
105
+ */
106
+ recoverMode(recoverSigner = true) {
107
+ this.recoverSigner = recoverSigner;
108
+ this._recoveryMode = recoverSigner;
109
+ // Recovery operations typically need single signature
110
+ if (recoverSigner && !this._transaction._threshold) {
111
+ this._transaction._threshold = 1;
112
+ }
113
+ return this;
114
+ }
115
+ /**
116
+ * fromPubKey is a list of unique addresses that correspond to the private keys that can be used to spend this output
117
+ * @param {string | string[]} senderPubKey
118
+ */
119
+ fromPubKey(senderPubKey) {
120
+ const pubKeys = senderPubKey instanceof Array ? senderPubKey : [senderPubKey];
121
+ this._transaction._fromAddresses = pubKeys; // Store as strings directly
122
+ return this;
123
+ }
124
+ /**
125
+ * List of UTXO required as inputs.
126
+ * A UTXO is a standalone representation of a transaction output.
127
+ *
128
+ * @param {DecodedUtxoObj[]} list of UTXOS
129
+ */
130
+ utxos(value) {
131
+ this.validateUtxos(value);
132
+ this._transaction._utxos = value;
133
+ return this;
134
+ }
135
+ /** @inheritdoc */
136
+ fromImplementation(rawTransaction) {
137
+ // Parse the raw transaction and initialize the builder
138
+ try {
139
+ const parsedTx = JSON.parse(rawTransaction);
140
+ this.initBuilder(parsedTx);
141
+ return this._transaction;
142
+ }
143
+ catch (error) {
144
+ throw new Error(`${constants_1.ERROR_PARSE_RAW_TRANSACTION}: ${error instanceof Error ? error.message : constants_1.ERROR_UNKNOWN_PARSING}`);
145
+ }
146
+ }
147
+ /**
148
+ * Get the transaction instance
149
+ */
150
+ get transaction() {
151
+ return this._transaction;
152
+ }
153
+ /**
154
+ * Validate required fields before building transaction
155
+ * @protected
156
+ */
157
+ validateRequiredFields() {
158
+ if (this._transaction._fromAddresses.length === 0) {
159
+ throw new Error(constants_1.ERROR_FROM_ADDRESSES_REQUIRED);
160
+ }
161
+ if (this._transaction._utxos.length === 0) {
162
+ throw new Error(constants_1.ERROR_UTXOS_REQUIRED_BUILDER);
163
+ }
164
+ }
165
+ }
166
+ exports.TransactionBuilder = TransactionBuilder;
167
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbURBQXFGO0FBSXJGLCtDQUE0QztBQUU1QywyQ0FhcUI7QUFFckIsTUFBc0Isa0JBQW1CLFNBQVEsaUNBQXNCO0lBUXJFLFlBQVksV0FBaUM7UUFDM0MsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBUFgsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDekIsWUFBTyxHQUFjLEVBQUUsQ0FBQztRQUUvQiw4Q0FBOEM7UUFDcEMsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFJOUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLHlCQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsV0FBVyxDQUFDLEVBQU07UUFDaEIsbURBQW1EO1FBQ25ELE1BQU0sTUFBTSxHQUFHLEVBQW1DLENBQUM7UUFFbkQsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDeEYsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBeUIsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QixNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7Z0JBQ3ZELENBQUMsQ0FBQyxNQUFNLENBQUMsWUFBWTtnQkFDckIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSx3QkFBWSxDQUFDLENBQUM7WUFDbkQsTUFBTSx1QkFBdUIsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDO2dCQUM5RSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhO2dCQUNqQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSx3QkFBWSxDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsRUFBRSxDQUFDO2dCQUNsRCxNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFvQyxDQUFDLENBQUM7WUFDeEQsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxvQkFBb0I7SUFDcEI7OztPQUdHO0lBQ0gsaUJBQWlCLENBQUMsU0FBaUI7UUFDakMsSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLGdDQUFxQixDQUFDLG1DQUF1QixDQUFDLENBQUM7UUFDM0QsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxZQUFZLENBQUMsS0FBcUI7UUFDaEMsZ0NBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyxHQUFHLHFDQUF5QixJQUFJLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDN0csQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYSxDQUFDLE1BQXdCO1FBQ3BDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixNQUFNLElBQUksZ0NBQXFCLENBQUMsbUNBQXVCLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBQ0QsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7T0FHRztJQUNILGdCQUFnQixDQUFDLFFBQWdCO1FBQy9CLElBQUksQ0FBQyxRQUFRLElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyxrQ0FBc0IsQ0FBQyxDQUFDO1FBQzFELENBQUM7SUFDSCxDQUFDO0lBQ0QsWUFBWTtJQUVaOzs7O09BSUc7SUFDSCxTQUFTLENBQUMsS0FBYTtRQUNyQixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3JDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxRQUFRLENBQUMsS0FBc0I7UUFDN0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSCxXQUFXLENBQUMsYUFBYSxHQUFHLElBQUk7UUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFDbkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7UUFFbkMsc0RBQXNEO1FBQ3RELElBQUksYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7T0FHRztJQUNILFVBQVUsQ0FBQyxZQUErQjtRQUN4QyxNQUFNLE9BQU8sR0FBRyxZQUFZLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDOUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLENBQUMsNEJBQTRCO1FBQ3hFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLEtBQXVCO1FBQzNCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQVFELGtCQUFrQjtJQUNSLGtCQUFrQixDQUFDLGNBQXNCO1FBQ2pELHVEQUF1RDtRQUN2RCxJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQzNCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FDYixHQUFHLHVDQUEyQixLQUFLLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGlDQUFxQixFQUFFLENBQ3BHLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7O09BR0c7SUFDTyxzQkFBc0I7UUFDOUIsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbEQsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBNkIsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQyxNQUFNLElBQUksS0FBSyxDQUFDLHdDQUE0QixDQUFDLENBQUM7UUFDaEQsQ0FBQztJQUNILENBQUM7Q0FDRjtBQXpMRCxnREF5TEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCYXNlVHJhbnNhY3Rpb25CdWlsZGVyLCBCdWlsZFRyYW5zYWN0aW9uRXJyb3IgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBDb2luQ29uZmlnIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBEZWNvZGVkVXR4b09iaiwgVHggfSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7IEtleVBhaXIgfSBmcm9tICcuL2tleVBhaXInO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICcuL3RyYW5zYWN0aW9uJztcbmltcG9ydCB7IFJhd1RyYW5zYWN0aW9uRGF0YSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgRVJST1JfTkVUV09SS19JRF9NSVNNQVRDSCxcbiAgRVJST1JfQkxPQ0tDSEFJTl9JRF9NSVNNQVRDSF9CVUlMREVSLFxuICBFUlJPUl9JTlZBTElEX1RIUkVTSE9MRCxcbiAgRVJST1JfSU5WQUxJRF9MT0NLVElNRSxcbiAgRVJST1JfVVRYT1NfRU1QVFlfQVJSQVksXG4gIEVSUk9SX1VUWE9TX01JU1NJTkdfRklFTEQsXG4gIEVSUk9SX0ZST01fQUREUkVTU0VTX1JFUVVJUkVELFxuICBFUlJPUl9VVFhPU19SRVFVSVJFRF9CVUlMREVSLFxuICBFUlJPUl9QQVJTRV9SQVdfVFJBTlNBQ1RJT04sXG4gIEVSUk9SX1VOS05PV05fUEFSU0lORyxcbiAgVVRYT19SRVFVSVJFRF9GSUVMRFMsXG4gIEhFWF9FTkNPRElORyxcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVHJhbnNhY3Rpb25CdWlsZGVyIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uQnVpbGRlciB7XG4gIHByb3RlY3RlZCBfdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uO1xuICBwcm90ZWN0ZWQgcmVjb3ZlclNpZ25lciA9IGZhbHNlO1xuICBwdWJsaWMgX3NpZ25lcjogS2V5UGFpcltdID0gW107XG5cbiAgLy8gUmVjb3ZlcnkgbW9kZSBmbGFnIGZvciB0cmFuc2FjdGlvbiBidWlsZGluZ1xuICBwcm90ZWN0ZWQgX3JlY292ZXJ5TW9kZSA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKF9jb2luQ29uZmlnOiBSZWFkb25seTxDb2luQ29uZmlnPikge1xuICAgIHN1cGVyKF9jb2luQ29uZmlnKTtcbiAgICB0aGlzLl90cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihfY29pbkNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgdHJhbnNhY3Rpb24gYnVpbGRlciBmaWVsZHMgdXNpbmcgdGhlIGRlY29kZWQgdHJhbnNhY3Rpb24gZGF0YVxuICAgKlxuICAgKiBAcGFyYW0ge1R4fSB0eCB0aGUgdHJhbnNhY3Rpb24gZGF0YVxuICAgKiBAcmV0dXJucyBpdHNlbGZcbiAgICovXG4gIGluaXRCdWlsZGVyKHR4OiBUeCk6IHRoaXMge1xuICAgIC8vIFZhbGlkYXRlIG5ldHdvcmsgYW5kIGJsb2NrY2hhaW4gSURzIGlmIGF2YWlsYWJsZVxuICAgIGNvbnN0IHR4RGF0YSA9IHR4IGFzIHVua25vd24gYXMgUmF3VHJhbnNhY3Rpb25EYXRhO1xuXG4gICAgaWYgKHR4RGF0YS5uZXR3b3JrSUQgIT09IHVuZGVmaW5lZCAmJiB0eERhdGEubmV0d29ya0lEICE9PSB0aGlzLl90cmFuc2FjdGlvbi5fbmV0d29ya0lEKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfTkVUV09SS19JRF9NSVNNQVRDSCk7XG4gICAgfVxuXG4gICAgaWYgKHR4RGF0YS5ibG9ja2NoYWluSUQpIHtcbiAgICAgIGNvbnN0IGJsb2NrY2hhaW5JRCA9IEJ1ZmZlci5pc0J1ZmZlcih0eERhdGEuYmxvY2tjaGFpbklEKVxuICAgICAgICA/IHR4RGF0YS5ibG9ja2NoYWluSURcbiAgICAgICAgOiBCdWZmZXIuZnJvbSh0eERhdGEuYmxvY2tjaGFpbklELCBIRVhfRU5DT0RJTkcpO1xuICAgICAgY29uc3QgdHJhbnNhY3Rpb25CbG9ja2NoYWluSUQgPSBCdWZmZXIuaXNCdWZmZXIodGhpcy5fdHJhbnNhY3Rpb24uX2Jsb2NrY2hhaW5JRClcbiAgICAgICAgPyB0aGlzLl90cmFuc2FjdGlvbi5fYmxvY2tjaGFpbklEXG4gICAgICAgIDogQnVmZmVyLmZyb20odGhpcy5fdHJhbnNhY3Rpb24uX2Jsb2NrY2hhaW5JRCwgSEVYX0VOQ09ESU5HKTtcbiAgICAgIGlmICghYmxvY2tjaGFpbklELmVxdWFscyh0cmFuc2FjdGlvbkJsb2NrY2hhaW5JRCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX0JMT0NLQ0hBSU5fSURfTUlTTUFUQ0hfQlVJTERFUik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb24odHgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVnaW9uIFZhbGlkYXRvcnNcbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgdGhyZXNob2xkXG4gICAqIEBwYXJhbSB0aHJlc2hvbGRcbiAgICovXG4gIHZhbGlkYXRlVGhyZXNob2xkKHRocmVzaG9sZDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCF0aHJlc2hvbGQgfHwgdGhyZXNob2xkICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKEVSUk9SX0lOVkFMSURfVEhSRVNIT0xEKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhlIFVUWE8gaGFzIGV4cGVjdGVkIGZpZWxkcy5cbiAgICogQHBhcmFtIFVUWE9cbiAgICovXG4gIHZhbGlkYXRlVXR4byh2YWx1ZTogRGVjb2RlZFV0eG9PYmopOiB2b2lkIHtcbiAgICBVVFhPX1JFUVVJUkVEX0ZJRUxEUy5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgICAgaWYgKCF2YWx1ZS5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoYCR7RVJST1JfVVRYT1NfTUlTU0lOR19GSUVMRH0gJHtmaWVsZH1gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB0aGUgbGlzdCBvZiBVVFhPUyBpcyBlbXB0eSBhbmQgY2hlY2sgZWFjaCBVVFhPLlxuICAgKiBAcGFyYW0gdmFsdWVzXG4gICAqL1xuICB2YWxpZGF0ZVV0eG9zKHZhbHVlczogRGVjb2RlZFV0eG9PYmpbXSk6IHZvaWQge1xuICAgIGlmICh2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKEVSUk9SX1VUWE9TX0VNUFRZX0FSUkFZKTtcbiAgICB9XG4gICAgdmFsdWVzLmZvckVhY2godGhpcy52YWxpZGF0ZVV0eG8pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBsb2NrdGltZVxuICAgKiBAcGFyYW0gbG9ja3RpbWVcbiAgICovXG4gIHZhbGlkYXRlTG9ja3RpbWUobG9ja3RpbWU6IGJpZ2ludCk6IHZvaWQge1xuICAgIGlmICghbG9ja3RpbWUgfHwgbG9ja3RpbWUgPCBCaWdJbnQoMCkpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoRVJST1JfSU5WQUxJRF9MT0NLVElNRSk7XG4gICAgfVxuICB9XG4gIC8vIGVuZHJlZ2lvblxuXG4gIC8qKlxuICAgKiBUaHJlc2hvbGQgaXMgYW4gaW50IHRoYXQgbmFtZXMgdGhlIG51bWJlciBvZiB1bmlxdWUgc2lnbmF0dXJlcyByZXF1aXJlZCB0byBzcGVuZCB0aGUgb3V0cHV0LlxuICAgKiBNdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgbGVuZ3RoIG9mIEFkZHJlc3Nlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gICAqL1xuICB0aHJlc2hvbGQodmFsdWU6IG51bWJlcik6IHRoaXMge1xuICAgIHRoaXMudmFsaWRhdGVUaHJlc2hvbGQodmFsdWUpO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uLl90aHJlc2hvbGQgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2NrdGltZSBpcyBhIGxvbmcgdGhhdCBjb250YWlucyB0aGUgdW5peCB0aW1lc3RhbXAgdGhhdCB0aGlzIG91dHB1dCBjYW4gYmUgc3BlbnQgYWZ0ZXIuXG4gICAqIFRoZSB1bml4IHRpbWVzdGFtcCBpcyBzcGVjaWZpYyB0byB0aGUgc2Vjb25kLlxuICAgKiBAcGFyYW0gdmFsdWVcbiAgICovXG4gIGxvY2t0aW1lKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlTG9ja3RpbWUoQmlnSW50KHZhbHVlKSk7XG4gICAgdGhpcy5fdHJhbnNhY3Rpb24uX2xvY2t0aW1lID0gQmlnSW50KHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVuIHVzaW5nIHJlY292ZXJ5IGtleSBtdXN0IGJlIHNldCBoZXJlXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn1bcmVjb3ZlclNpZ25lcj10cnVlXSB3aGV0aGVyIGl0J3MgcmVjb3Zlcnkgc2lnbmVyXG4gICAqL1xuICByZWNvdmVyTW9kZShyZWNvdmVyU2lnbmVyID0gdHJ1ZSk6IHRoaXMge1xuICAgIHRoaXMucmVjb3ZlclNpZ25lciA9IHJlY292ZXJTaWduZXI7XG4gICAgdGhpcy5fcmVjb3ZlcnlNb2RlID0gcmVjb3ZlclNpZ25lcjtcblxuICAgIC8vIFJlY292ZXJ5IG9wZXJhdGlvbnMgdHlwaWNhbGx5IG5lZWQgc2luZ2xlIHNpZ25hdHVyZVxuICAgIGlmIChyZWNvdmVyU2lnbmVyICYmICF0aGlzLl90cmFuc2FjdGlvbi5fdGhyZXNob2xkKSB7XG4gICAgICB0aGlzLl90cmFuc2FjdGlvbi5fdGhyZXNob2xkID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBmcm9tUHViS2V5IGlzIGEgbGlzdCBvZiB1bmlxdWUgYWRkcmVzc2VzIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgcHJpdmF0ZSBrZXlzIHRoYXQgY2FuIGJlIHVzZWQgdG8gc3BlbmQgdGhpcyBvdXRwdXRcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBzdHJpbmdbXX0gc2VuZGVyUHViS2V5XG4gICAqL1xuICBmcm9tUHViS2V5KHNlbmRlclB1YktleTogc3RyaW5nIHwgc3RyaW5nW10pOiB0aGlzIHtcbiAgICBjb25zdCBwdWJLZXlzID0gc2VuZGVyUHViS2V5IGluc3RhbmNlb2YgQXJyYXkgPyBzZW5kZXJQdWJLZXkgOiBbc2VuZGVyUHViS2V5XTtcbiAgICB0aGlzLl90cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3NlcyA9IHB1YktleXM7IC8vIFN0b3JlIGFzIHN0cmluZ3MgZGlyZWN0bHlcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IG9mIFVUWE8gcmVxdWlyZWQgYXMgaW5wdXRzLlxuICAgKiBBIFVUWE8gaXMgYSBzdGFuZGFsb25lIHJlcHJlc2VudGF0aW9uIG9mIGEgdHJhbnNhY3Rpb24gb3V0cHV0LlxuICAgKlxuICAgKiBAcGFyYW0ge0RlY29kZWRVdHhvT2JqW119IGxpc3Qgb2YgVVRYT1NcbiAgICovXG4gIHV0eG9zKHZhbHVlOiBEZWNvZGVkVXR4b09ialtdKTogdGhpcyB7XG4gICAgdGhpcy52YWxpZGF0ZVV0eG9zKHZhbHVlKTtcbiAgICB0aGlzLl90cmFuc2FjdGlvbi5fdXR4b3MgPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgRmxhcmUgdHJhbnNhY3Rpb24gdXNpbmcgRmxhcmVKUyBBUElcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGJ1aWxkRmxhcmVUcmFuc2FjdGlvbigpOiBQcm9taXNlPHZvaWQ+IHwgdm9pZDtcblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcHJvdGVjdGVkIGZyb21JbXBsZW1lbnRhdGlvbihyYXdUcmFuc2FjdGlvbjogc3RyaW5nKTogVHJhbnNhY3Rpb24ge1xuICAgIC8vIFBhcnNlIHRoZSByYXcgdHJhbnNhY3Rpb24gYW5kIGluaXRpYWxpemUgdGhlIGJ1aWxkZXJcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkVHggPSBKU09OLnBhcnNlKHJhd1RyYW5zYWN0aW9uKTtcbiAgICAgIHRoaXMuaW5pdEJ1aWxkZXIocGFyc2VkVHgpO1xuICAgICAgcmV0dXJuIHRoaXMuX3RyYW5zYWN0aW9uO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke0VSUk9SX1BBUlNFX1JBV19UUkFOU0FDVElPTn06ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBFUlJPUl9VTktOT1dOX1BBUlNJTkd9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSB0cmFuc2FjdGlvbiBpbnN0YW5jZVxuICAgKi9cbiAgZ2V0IHRyYW5zYWN0aW9uKCk6IFRyYW5zYWN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNhY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgcmVxdWlyZWQgZmllbGRzIGJlZm9yZSBidWlsZGluZyB0cmFuc2FjdGlvblxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgdmFsaWRhdGVSZXF1aXJlZEZpZWxkcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fdHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRVJST1JfRlJPTV9BRERSRVNTRVNfUkVRVUlSRUQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fdHJhbnNhY3Rpb24uX3V0eG9zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKEVSUk9SX1VUWE9TX1JFUVVJUkVEX0JVSUxERVIpO1xuICAgIH1cbiAgfVxufVxuIl19