@bitgo-beta/abstract-eth 1.0.2-beta.202 → 1.0.2-beta.2020

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 (172) hide show
  1. package/dist/src/abstractEthLikeCoin.d.ts +20 -9
  2. package/dist/src/abstractEthLikeCoin.d.ts.map +1 -1
  3. package/dist/src/abstractEthLikeCoin.js +46 -15
  4. package/dist/src/abstractEthLikeNewCoins.d.ts +847 -0
  5. package/dist/src/abstractEthLikeNewCoins.d.ts.map +1 -0
  6. package/dist/src/abstractEthLikeNewCoins.js +2553 -0
  7. package/dist/src/ethLikeToken.d.ts +38 -6
  8. package/dist/src/ethLikeToken.d.ts.map +1 -1
  9. package/dist/src/ethLikeToken.js +289 -10
  10. package/dist/src/index.d.ts +2 -0
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +8 -2
  13. package/dist/src/lib/constants.d.ts +4 -0
  14. package/dist/src/lib/constants.d.ts.map +1 -0
  15. package/dist/src/lib/constants.js +11 -0
  16. package/dist/src/lib/contractCall.d.ts +8 -0
  17. package/dist/src/lib/contractCall.d.ts.map +1 -0
  18. package/dist/src/lib/contractCall.js +17 -0
  19. package/dist/src/lib/decryptionDelegationBuilder.d.ts +90 -0
  20. package/dist/src/lib/decryptionDelegationBuilder.d.ts.map +1 -0
  21. package/dist/src/lib/decryptionDelegationBuilder.js +59 -0
  22. package/dist/src/lib/iface.d.ts +137 -0
  23. package/dist/src/lib/iface.d.ts.map +1 -0
  24. package/dist/src/lib/iface.js +8 -0
  25. package/dist/src/lib/index.d.ts +19 -0
  26. package/dist/src/lib/index.d.ts.map +1 -0
  27. package/dist/src/lib/index.js +60 -0
  28. package/dist/src/lib/keyPair.d.ts +26 -0
  29. package/dist/src/lib/keyPair.d.ts.map +1 -0
  30. package/dist/src/lib/keyPair.js +65 -0
  31. package/dist/src/lib/messages/eip191/eip191Message.d.ts +12 -0
  32. package/dist/src/lib/messages/eip191/eip191Message.d.ts.map +1 -0
  33. package/dist/src/lib/messages/eip191/eip191Message.js +25 -0
  34. package/dist/src/lib/messages/eip191/eip191MessageBuilder.d.ts +19 -0
  35. package/dist/src/lib/messages/eip191/eip191MessageBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/messages/eip191/eip191MessageBuilder.js +27 -0
  37. package/dist/src/lib/messages/eip191/index.d.ts +3 -0
  38. package/dist/src/lib/messages/eip191/index.d.ts.map +1 -0
  39. package/dist/src/lib/messages/eip191/index.js +19 -0
  40. package/dist/src/lib/messages/eip712/eip712Message.d.ts +6 -0
  41. package/dist/src/lib/messages/eip712/eip712Message.d.ts.map +1 -0
  42. package/dist/src/lib/messages/eip712/eip712Message.js +27 -0
  43. package/dist/src/lib/messages/eip712/eip712MessageBuilder.d.ts +7 -0
  44. package/dist/src/lib/messages/eip712/eip712MessageBuilder.d.ts.map +1 -0
  45. package/dist/src/lib/messages/eip712/eip712MessageBuilder.js +15 -0
  46. package/dist/src/lib/messages/eip712/index.d.ts +3 -0
  47. package/dist/src/lib/messages/eip712/index.d.ts.map +1 -0
  48. package/dist/src/lib/messages/eip712/index.js +19 -0
  49. package/dist/src/lib/messages/index.d.ts +4 -0
  50. package/dist/src/lib/messages/index.d.ts.map +1 -0
  51. package/dist/src/lib/messages/index.js +20 -0
  52. package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
  53. package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
  54. package/dist/src/lib/messages/messageBuilderFactory.js +23 -0
  55. package/dist/src/lib/transaction.d.ts +69 -0
  56. package/dist/src/lib/transaction.d.ts.map +1 -0
  57. package/dist/src/lib/transaction.js +149 -0
  58. package/dist/src/lib/transactionBuilder.d.ts +270 -0
  59. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  60. package/dist/src/lib/transactionBuilder.js +834 -0
  61. package/dist/src/lib/transferBuilder.d.ts +76 -0
  62. package/dist/src/lib/transferBuilder.d.ts.map +1 -0
  63. package/dist/src/lib/transferBuilder.js +307 -0
  64. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts +54 -0
  65. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.d.ts.map +1 -0
  66. package/dist/src/lib/transferBuilders/baseNFTTransferBuilder.js +120 -0
  67. package/dist/src/lib/transferBuilders/index.d.ts +4 -0
  68. package/dist/src/lib/transferBuilders/index.d.ts.map +1 -0
  69. package/dist/src/lib/transferBuilders/index.js +20 -0
  70. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts +17 -0
  71. package/dist/src/lib/transferBuilders/transferBuilderERC1155.d.ts.map +1 -0
  72. package/dist/src/lib/transferBuilders/transferBuilderERC1155.js +96 -0
  73. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts +21 -0
  74. package/dist/src/lib/transferBuilders/transferBuilderERC721.d.ts.map +1 -0
  75. package/dist/src/lib/transferBuilders/transferBuilderERC721.js +91 -0
  76. package/dist/src/lib/types.d.ts +40 -0
  77. package/dist/src/lib/types.d.ts.map +1 -0
  78. package/dist/src/lib/types.js +140 -0
  79. package/dist/src/lib/utils.d.ts +310 -0
  80. package/dist/src/lib/utils.d.ts.map +1 -0
  81. package/dist/src/lib/utils.js +851 -0
  82. package/dist/src/lib/walletUtil.d.ts +42 -0
  83. package/dist/src/lib/walletUtil.d.ts.map +1 -0
  84. package/dist/src/lib/walletUtil.js +45 -0
  85. package/dist/src/lib/zamaUtils.d.ts +73 -0
  86. package/dist/src/lib/zamaUtils.d.ts.map +1 -0
  87. package/dist/src/lib/zamaUtils.js +159 -0
  88. package/dist/src/types.d.ts +9 -0
  89. package/dist/src/types.d.ts.map +1 -0
  90. package/dist/src/types.js +3 -0
  91. package/dist/test/index.d.ts +2 -0
  92. package/dist/test/index.d.ts.map +1 -0
  93. package/dist/test/index.js +18 -0
  94. package/dist/test/unit/coin.d.ts +8 -0
  95. package/dist/test/unit/coin.d.ts.map +1 -0
  96. package/dist/test/unit/coin.js +577 -0
  97. package/dist/test/unit/decryptionDelegationBuilder.d.ts +2 -0
  98. package/dist/test/unit/decryptionDelegationBuilder.d.ts.map +1 -0
  99. package/dist/test/unit/decryptionDelegationBuilder.js +265 -0
  100. package/dist/test/unit/index.d.ts +8 -0
  101. package/dist/test/unit/index.d.ts.map +1 -0
  102. package/dist/test/unit/index.js +24 -0
  103. package/dist/test/unit/messages/abstractEthMessageBuilderTests.d.ts +3 -0
  104. package/dist/test/unit/messages/abstractEthMessageBuilderTests.d.ts.map +1 -0
  105. package/dist/test/unit/messages/abstractEthMessageBuilderTests.js +110 -0
  106. package/dist/test/unit/messages/abstractEthMessageTestTypes.d.ts +43 -0
  107. package/dist/test/unit/messages/abstractEthMessageTestTypes.d.ts.map +1 -0
  108. package/dist/test/unit/messages/abstractEthMessageTestTypes.js +3 -0
  109. package/dist/test/unit/messages/abstractEthMessagesTests.d.ts +3 -0
  110. package/dist/test/unit/messages/abstractEthMessagesTests.d.ts.map +1 -0
  111. package/dist/test/unit/messages/abstractEthMessagesTests.js +129 -0
  112. package/dist/test/unit/messages/eip191/eip191Message.d.ts +2 -0
  113. package/dist/test/unit/messages/eip191/eip191Message.d.ts.map +1 -0
  114. package/dist/test/unit/messages/eip191/eip191Message.js +15 -0
  115. package/dist/test/unit/messages/eip191/eip191MessageBuilder.d.ts +2 -0
  116. package/dist/test/unit/messages/eip191/eip191MessageBuilder.d.ts.map +1 -0
  117. package/dist/test/unit/messages/eip191/eip191MessageBuilder.js +16 -0
  118. package/dist/test/unit/messages/eip191/fixtures.d.ts +109 -0
  119. package/dist/test/unit/messages/eip191/fixtures.d.ts.map +1 -0
  120. package/dist/test/unit/messages/eip191/fixtures.js +63 -0
  121. package/dist/test/unit/messages/eip712/eip712Message.d.ts +2 -0
  122. package/dist/test/unit/messages/eip712/eip712Message.d.ts.map +1 -0
  123. package/dist/test/unit/messages/eip712/eip712Message.js +15 -0
  124. package/dist/test/unit/messages/eip712/eip712MessageBuilder.d.ts +2 -0
  125. package/dist/test/unit/messages/eip712/eip712MessageBuilder.d.ts.map +1 -0
  126. package/dist/test/unit/messages/eip712/eip712MessageBuilder.js +16 -0
  127. package/dist/test/unit/messages/eip712/fixtures.d.ts +76 -0
  128. package/dist/test/unit/messages/eip712/fixtures.d.ts.map +1 -0
  129. package/dist/test/unit/messages/eip712/fixtures.js +120 -0
  130. package/dist/test/unit/messages/index.d.ts +4 -0
  131. package/dist/test/unit/messages/index.d.ts.map +1 -0
  132. package/dist/test/unit/messages/index.js +20 -0
  133. package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
  134. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  135. package/dist/test/unit/messages/messageBuilderFactory.js +52 -0
  136. package/dist/test/unit/token.d.ts +2 -0
  137. package/dist/test/unit/token.d.ts.map +1 -0
  138. package/dist/test/unit/token.js +37 -0
  139. package/dist/test/unit/transaction.d.ts +3 -0
  140. package/dist/test/unit/transaction.d.ts.map +1 -0
  141. package/dist/test/unit/transaction.js +73 -0
  142. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts +8 -0
  143. package/dist/test/unit/transactionBuilder/addressInitialization.d.ts.map +1 -0
  144. package/dist/test/unit/transactionBuilder/addressInitialization.js +95 -0
  145. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts +3 -0
  146. package/dist/test/unit/transactionBuilder/decryptionDelegation.d.ts.map +1 -0
  147. package/dist/test/unit/transactionBuilder/decryptionDelegation.js +161 -0
  148. package/dist/test/unit/transactionBuilder/flushNft.d.ts +2 -0
  149. package/dist/test/unit/transactionBuilder/flushNft.d.ts.map +1 -0
  150. package/dist/test/unit/transactionBuilder/flushNft.js +381 -0
  151. package/dist/test/unit/transactionBuilder/index.d.ts +6 -0
  152. package/dist/test/unit/transactionBuilder/index.d.ts.map +1 -0
  153. package/dist/test/unit/transactionBuilder/index.js +22 -0
  154. package/dist/test/unit/transactionBuilder/send.d.ts +3 -0
  155. package/dist/test/unit/transactionBuilder/send.d.ts.map +1 -0
  156. package/dist/test/unit/transactionBuilder/send.js +197 -0
  157. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts +11 -0
  158. package/dist/test/unit/transactionBuilder/walletInitialization.d.ts.map +1 -0
  159. package/dist/test/unit/transactionBuilder/walletInitialization.js +137 -0
  160. package/dist/test/unit/transferBuilder.d.ts +2 -0
  161. package/dist/test/unit/transferBuilder.d.ts.map +1 -0
  162. package/dist/test/unit/transferBuilder.js +76 -0
  163. package/dist/test/unit/utils.d.ts +2 -0
  164. package/dist/test/unit/utils.d.ts.map +1 -0
  165. package/dist/test/unit/utils.js +214 -0
  166. package/dist/test/unit/zamaUtils.d.ts +2 -0
  167. package/dist/test/unit/zamaUtils.d.ts.map +1 -0
  168. package/dist/test/unit/zamaUtils.js +251 -0
  169. package/dist/tsconfig.tsbuildinfo +1 -8244
  170. package/package.json +34 -10
  171. package/.eslintignore +0 -5
  172. package/CHANGELOG.md +0 -166
@@ -0,0 +1,834 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.TransactionBuilder = void 0;
40
+ const statics_1 = require("@bitgo-beta/statics");
41
+ const ethereumjs_abi_1 = __importDefault(require("ethereumjs-abi"));
42
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
43
+ const ethUtil = __importStar(require("ethereumjs-util"));
44
+ const tx_1 = require("@ethereumjs/tx");
45
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
46
+ const keyPair_1 = require("./keyPair");
47
+ const iface_1 = require("./iface");
48
+ const utils_1 = require("./utils");
49
+ const walletUtil_1 = require("./walletUtil");
50
+ const transaction_1 = require("./transaction");
51
+ const DEFAULT_M = 3;
52
+ const RAW_TX_HEX_REGEX = /^(0x)?[0-9a-f]{1,}$/;
53
+ /**
54
+ * EthereumLike transaction builder.
55
+ */
56
+ class TransactionBuilder extends sdk_core_1.BaseTransactionBuilder {
57
+ /**
58
+ * Public constructor.
59
+ *
60
+ * @param _coinConfig
61
+ */
62
+ constructor(_coinConfig) {
63
+ super(_coinConfig);
64
+ this._common = (0, utils_1.getCommon)(this._coinConfig.network);
65
+ this._type = sdk_core_1.TransactionType.Send;
66
+ this._counter = 0;
67
+ this._value = '0';
68
+ this._walletOwnerAddresses = [];
69
+ this._forwarderVersion = 0;
70
+ this._walletVersion = 0;
71
+ this.transaction = new transaction_1.Transaction(this._coinConfig, this._common);
72
+ this._walletSimpleByteCode = '';
73
+ }
74
+ /** @inheritdoc */
75
+ async buildImplementation() {
76
+ const transactionData = this.getTransactionData();
77
+ if (this._txSignature) {
78
+ Object.assign(transactionData, this._txSignature);
79
+ }
80
+ this.transaction.setTransactionType(this._type);
81
+ transactionData.from = this._sourceKeyPair ? this._sourceKeyPair.getAddress() : undefined;
82
+ this.transaction.setTransactionData(transactionData, this._transfer ? this._transfer.getIsFirstSigner() : undefined);
83
+ // Build and sign a new transaction based on the latest changes
84
+ if (this._sourceKeyPair && this._sourceKeyPair.getKeys().prv) {
85
+ await this.transaction.sign(this._sourceKeyPair);
86
+ }
87
+ return this.transaction;
88
+ }
89
+ getTransactionData() {
90
+ switch (this._type) {
91
+ case sdk_core_1.TransactionType.WalletInitialization:
92
+ return this.buildWalletInitializationTransaction(this._walletVersion);
93
+ case sdk_core_1.TransactionType.RecoveryWalletDeployment:
94
+ return this.buildBase(this._data);
95
+ case sdk_core_1.TransactionType.Send:
96
+ case sdk_core_1.TransactionType.SendERC721:
97
+ case sdk_core_1.TransactionType.SendERC1155:
98
+ return this.buildSendTransaction();
99
+ case sdk_core_1.TransactionType.AddressInitialization:
100
+ return this.buildAddressInitializationTransaction();
101
+ case sdk_core_1.TransactionType.FlushTokens:
102
+ return this.buildFlushTokensTransaction();
103
+ case sdk_core_1.TransactionType.FlushCoins:
104
+ return this.buildFlushCoinsTransaction();
105
+ case sdk_core_1.TransactionType.FlushERC721:
106
+ return this.buildFlushERC721Transaction();
107
+ case sdk_core_1.TransactionType.FlushERC1155:
108
+ return this.buildFlushERC1155Transaction();
109
+ case sdk_core_1.TransactionType.SingleSigSend:
110
+ return this.buildBase('0x');
111
+ case sdk_core_1.TransactionType.ContractCall:
112
+ case sdk_core_1.TransactionType.DecryptionDelegation:
113
+ return this.buildGenericContractCallTransaction();
114
+ default:
115
+ throw new sdk_core_1.BuildTransactionError('Unsupported transaction type');
116
+ }
117
+ }
118
+ /** @inheritdoc */
119
+ fromImplementation(rawTransaction, isFirstSigner) {
120
+ let tx;
121
+ if (RAW_TX_HEX_REGEX.test(rawTransaction.toLowerCase())) {
122
+ tx = transaction_1.Transaction.fromSerialized(this._coinConfig, this._common, rawTransaction, isFirstSigner);
123
+ this.loadBuilderInput(tx.toJson(), isFirstSigner);
124
+ }
125
+ else {
126
+ const txData = JSON.parse(rawTransaction);
127
+ tx = new transaction_1.Transaction(this._coinConfig, txData);
128
+ }
129
+ return tx;
130
+ }
131
+ /**
132
+ * Load the builder data using the deserialized transaction
133
+ *
134
+ * @param {TxData} transactionJson the deserialized transaction json
135
+ * @param {boolean} isFirstSigner if the transaction is being signed by the first signer
136
+ */
137
+ loadBuilderInput(transactionJson, isFirstSigner) {
138
+ const decodedType = (0, utils_1.classifyTransaction)(transactionJson.data);
139
+ this.type(decodedType);
140
+ this.counter(transactionJson.nonce);
141
+ this.value(transactionJson.value);
142
+ if (transactionJson._type === iface_1.ETHTransactionType.LEGACY) {
143
+ this.fee({
144
+ fee: transactionJson.gasPrice,
145
+ gasPrice: transactionJson.gasPrice,
146
+ gasLimit: transactionJson.gasLimit,
147
+ });
148
+ }
149
+ else {
150
+ this.fee({
151
+ gasLimit: transactionJson.gasLimit,
152
+ fee: transactionJson.maxFeePerGas,
153
+ eip1559: {
154
+ maxFeePerGas: transactionJson.maxFeePerGas,
155
+ maxPriorityFeePerGas: transactionJson.maxPriorityFeePerGas,
156
+ },
157
+ });
158
+ }
159
+ if ((0, utils_1.hasSignature)(transactionJson)) {
160
+ this._txSignature = { v: transactionJson.v, r: transactionJson.r, s: transactionJson.s };
161
+ }
162
+ this.setTransactionTypeFields(decodedType, transactionJson, isFirstSigner);
163
+ }
164
+ setTransactionTypeFields(decodedType, transactionJson, isFirstSigner) {
165
+ switch (decodedType) {
166
+ case sdk_core_1.TransactionType.WalletInitialization:
167
+ const { owners, salt } = (0, utils_1.decodeWalletCreationData)(transactionJson.data);
168
+ owners.forEach((element) => {
169
+ this.owner(element);
170
+ });
171
+ if (salt) {
172
+ this.salt(salt);
173
+ this.walletVersion(1);
174
+ this.setContract(transactionJson.to);
175
+ }
176
+ break;
177
+ case sdk_core_1.TransactionType.RecoveryWalletDeployment:
178
+ this.data(transactionJson.data);
179
+ break;
180
+ case sdk_core_1.TransactionType.FlushTokens:
181
+ this.setContract(transactionJson.to);
182
+ const { forwarderAddress, tokenAddress, forwarderVersion } = (0, utils_1.decodeFlushTokensData)(transactionJson.data, transactionJson.to);
183
+ if (forwarderVersion === 4) {
184
+ this.forwarderVersion(4);
185
+ }
186
+ this.forwarderAddress(forwarderAddress);
187
+ this.tokenAddress(tokenAddress);
188
+ break;
189
+ case sdk_core_1.TransactionType.FlushCoins:
190
+ this.setContract(transactionJson.to);
191
+ break;
192
+ case sdk_core_1.TransactionType.FlushERC721:
193
+ this.setContract(transactionJson.to);
194
+ const erc721Data = (0, utils_1.decodeFlushERC721TokensData)(transactionJson.data, transactionJson.to);
195
+ if (erc721Data.forwarderVersion === 4) {
196
+ this.forwarderVersion(erc721Data.forwarderVersion);
197
+ }
198
+ this.forwarderAddress(erc721Data.forwarderAddress);
199
+ this.tokenAddress(erc721Data.tokenAddress);
200
+ this.tokenId(erc721Data.tokenId);
201
+ break;
202
+ case sdk_core_1.TransactionType.FlushERC1155:
203
+ this.setContract(transactionJson.to);
204
+ const erc1155Data = (0, utils_1.decodeFlushERC1155TokensData)(transactionJson.data, transactionJson.to);
205
+ if (erc1155Data.forwarderVersion === 4) {
206
+ this.forwarderVersion(erc1155Data.forwarderVersion);
207
+ }
208
+ this.forwarderAddress(erc1155Data.forwarderAddress);
209
+ this.tokenAddress(erc1155Data.tokenAddress);
210
+ this.tokenId(erc1155Data.tokenId);
211
+ break;
212
+ case sdk_core_1.TransactionType.Send:
213
+ case sdk_core_1.TransactionType.SendERC1155:
214
+ case sdk_core_1.TransactionType.SendERC721:
215
+ this.setContract(transactionJson.to);
216
+ this._transfer = this.transfer(transactionJson.data, isFirstSigner);
217
+ break;
218
+ case sdk_core_1.TransactionType.AddressInitialization:
219
+ this.setContract(transactionJson.to);
220
+ const { baseAddress, addressCreationSalt, feeAddress } = (0, utils_1.decodeForwarderCreationData)(transactionJson.data);
221
+ if (baseAddress && addressCreationSalt) {
222
+ this.baseAddress(baseAddress);
223
+ this.salt(addressCreationSalt);
224
+ if (feeAddress) {
225
+ this.feeAddress(feeAddress);
226
+ this.forwarderVersion(4);
227
+ }
228
+ else {
229
+ this.forwarderVersion(1);
230
+ }
231
+ const forwarderImplementationAddress = this._coinConfig.network
232
+ .forwarderImplementationAddress;
233
+ if (forwarderImplementationAddress) {
234
+ this.initCode(forwarderImplementationAddress);
235
+ }
236
+ }
237
+ break;
238
+ case sdk_core_1.TransactionType.SingleSigSend:
239
+ this.setContract(transactionJson.to);
240
+ break;
241
+ case sdk_core_1.TransactionType.ContractCall:
242
+ case sdk_core_1.TransactionType.DecryptionDelegation:
243
+ this.setContract(transactionJson.to);
244
+ this.data(transactionJson.data);
245
+ break;
246
+ default:
247
+ throw new sdk_core_1.BuildTransactionError('Unsupported transaction type');
248
+ // TODO: Add other cases of deserialization
249
+ }
250
+ }
251
+ /** @inheritdoc */
252
+ signImplementation(key) {
253
+ const signer = new keyPair_1.KeyPair({ prv: key.key });
254
+ if (this._type === sdk_core_1.TransactionType.WalletInitialization && this._walletOwnerAddresses.length === 0) {
255
+ throw new sdk_core_1.SigningError('Cannot sign an wallet initialization transaction without owners');
256
+ }
257
+ if (this._sourceKeyPair) {
258
+ throw new sdk_core_1.SigningError('Cannot sign multiple times a non send-type transaction');
259
+ }
260
+ // Signing the transaction is an async operation, so save the source and leave the actual
261
+ // signing for the build step
262
+ this._sourceKeyPair = signer;
263
+ return this.transaction;
264
+ }
265
+ /** @inheritdoc */
266
+ validateAddress(address) {
267
+ if (!(0, utils_1.isValidEthAddress)(address.address)) {
268
+ throw new sdk_core_1.BuildTransactionError('Invalid address ' + address.address);
269
+ }
270
+ }
271
+ /** @inheritdoc */
272
+ validateKey(key) {
273
+ if (!((0, sdk_core_1.isValidXprv)(key.key) || (0, sdk_core_1.isValidPrv)(key.key))) {
274
+ throw new sdk_core_1.BuildTransactionError('Invalid key');
275
+ }
276
+ }
277
+ /**
278
+ * Validate the raw transaction is either a JSON or
279
+ * a hex encoded transaction
280
+ *
281
+ * @param {any} rawTransaction The raw transaction to be validated
282
+ */
283
+ validateRawTransaction(rawTransaction) {
284
+ if (!rawTransaction) {
285
+ throw new sdk_core_1.InvalidTransactionError('Raw transaction is empty');
286
+ }
287
+ if (typeof rawTransaction === 'string') {
288
+ if (RAW_TX_HEX_REGEX.test(rawTransaction.toLowerCase())) {
289
+ const txBytes = ethUtil.toBuffer(ethUtil.addHexPrefix(rawTransaction.toLowerCase()));
290
+ if (!this.isEip1559Txn(txBytes) && !this.isRLPDecodable(txBytes)) {
291
+ throw new sdk_core_1.ParseTransactionError('There was error in decoding the hex string');
292
+ }
293
+ }
294
+ else {
295
+ try {
296
+ JSON.parse(rawTransaction);
297
+ }
298
+ catch (e) {
299
+ throw new sdk_core_1.ParseTransactionError('There was error in parsing the JSON string');
300
+ }
301
+ }
302
+ }
303
+ else {
304
+ throw new sdk_core_1.InvalidTransactionError('Transaction is not a hex string or stringified json');
305
+ }
306
+ }
307
+ isEip1559Txn(txn) {
308
+ try {
309
+ tx_1.FeeMarketEIP1559Transaction.fromSerializedTx(txn);
310
+ return true;
311
+ }
312
+ catch (_) {
313
+ return false;
314
+ }
315
+ }
316
+ isRLPDecodable(bytes) {
317
+ try {
318
+ ethUtil.rlp.decode(bytes);
319
+ return true;
320
+ }
321
+ catch (_) {
322
+ return false;
323
+ }
324
+ }
325
+ validateBaseTransactionFields() {
326
+ if (this._fee === undefined || (!this._fee.fee && !this._fee.gasPrice && !this._fee.eip1559)) {
327
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing fee');
328
+ }
329
+ if (this._common === undefined) {
330
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: network common');
331
+ }
332
+ if (this._counter === undefined) {
333
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing address counter');
334
+ }
335
+ }
336
+ /** @inheritdoc */
337
+ validateTransaction(transaction) {
338
+ this.validateBaseTransactionFields();
339
+ switch (this._type) {
340
+ case sdk_core_1.TransactionType.WalletInitialization:
341
+ this.validateWalletInitializationFields();
342
+ break;
343
+ case sdk_core_1.TransactionType.RecoveryWalletDeployment:
344
+ this.validateDataField();
345
+ break;
346
+ case sdk_core_1.TransactionType.Send:
347
+ case sdk_core_1.TransactionType.SendERC721:
348
+ case sdk_core_1.TransactionType.SendERC1155:
349
+ this.validateContractAddress();
350
+ break;
351
+ case sdk_core_1.TransactionType.AddressInitialization:
352
+ this.validateContractAddress();
353
+ break;
354
+ case sdk_core_1.TransactionType.FlushCoins:
355
+ this.validateContractAddress();
356
+ break;
357
+ case sdk_core_1.TransactionType.FlushTokens:
358
+ this.validateContractAddress();
359
+ this.validateForwarderAddress();
360
+ this.validateTokenAddress();
361
+ break;
362
+ case sdk_core_1.TransactionType.FlushERC721:
363
+ case sdk_core_1.TransactionType.FlushERC1155:
364
+ this.validateContractAddress();
365
+ if (this._forwarderVersion < 4) {
366
+ this.validateForwarderAddress();
367
+ }
368
+ this.validateTokenAddress();
369
+ if (!this._tokenId) {
370
+ throw new sdk_core_1.BuildTransactionError(this._type === sdk_core_1.TransactionType.FlushERC721
371
+ ? 'Token ID is required for ERC721 flush'
372
+ : 'Token ID is required for ERC1155 flush');
373
+ }
374
+ break;
375
+ case sdk_core_1.TransactionType.SingleSigSend:
376
+ // for single sig sends, the contract address is actually the recipient
377
+ this.validateContractAddress();
378
+ break;
379
+ case sdk_core_1.TransactionType.StakingLock:
380
+ case sdk_core_1.TransactionType.StakingUnlock:
381
+ case sdk_core_1.TransactionType.StakingVote:
382
+ case sdk_core_1.TransactionType.StakingUnvote:
383
+ case sdk_core_1.TransactionType.StakingActivate:
384
+ case sdk_core_1.TransactionType.StakingWithdraw:
385
+ break;
386
+ case sdk_core_1.TransactionType.ContractCall:
387
+ case sdk_core_1.TransactionType.DecryptionDelegation:
388
+ this.validateContractAddress();
389
+ this.validateDataField();
390
+ break;
391
+ default:
392
+ throw new sdk_core_1.BuildTransactionError('Unsupported transaction type');
393
+ }
394
+ }
395
+ /**
396
+ * Check wallet owner addresses for wallet initialization transactions are valid or throw.
397
+ */
398
+ validateWalletInitializationFields() {
399
+ if (this._walletOwnerAddresses === undefined) {
400
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing wallet owners');
401
+ }
402
+ if (this._walletOwnerAddresses.length !== 3) {
403
+ throw new sdk_core_1.BuildTransactionError(`Invalid transaction: wrong number of owners -- required: 3, found: ${this._walletOwnerAddresses.length}`);
404
+ }
405
+ }
406
+ /**
407
+ * Check if a token address for the tx was defined or throw.
408
+ */
409
+ validateTokenAddress() {
410
+ if (this._tokenAddress === undefined) {
411
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing token address');
412
+ }
413
+ }
414
+ /**
415
+ * Check if a forwarder address for the tx was defined or throw.
416
+ */
417
+ validateForwarderAddress() {
418
+ if (this._forwarderAddress === undefined) {
419
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing forwarder address');
420
+ }
421
+ }
422
+ /**
423
+ * Check if a contract address for the wallet was defined or throw.
424
+ */
425
+ validateContractAddress() {
426
+ if (this._contractAddress === undefined) {
427
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing contract address');
428
+ }
429
+ }
430
+ /**
431
+ * Checks if a contract call data field was defined or throws otherwise
432
+ */
433
+ validateDataField() {
434
+ if (!this._data) {
435
+ throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing contract call data field');
436
+ }
437
+ }
438
+ setContract(address) {
439
+ if (address === undefined) {
440
+ throw new sdk_core_1.BuildTransactionError('Undefined recipient address');
441
+ }
442
+ this.contract(address);
443
+ }
444
+ validateValue(value) {
445
+ if (value.isLessThan(0)) {
446
+ throw new sdk_core_1.BuildTransactionError('Value cannot be below less than zero');
447
+ }
448
+ // TODO: validate the amount is not bigger than the max amount in each Eth family coin
449
+ }
450
+ // region Common builder methods
451
+ /**
452
+ * The type of transaction being built.
453
+ *
454
+ * @param {TransactionType} type
455
+ */
456
+ type(type) {
457
+ this._type = type;
458
+ }
459
+ /**
460
+ * Set the transaction fees. Low fees may get a transaction rejected or never picked up by bakers.
461
+ *
462
+ * @param {Fee} fee Baker fees. May also include the maximum gas to pay
463
+ */
464
+ fee(fee) {
465
+ this.validateValue(new bignumber_js_1.default(fee.fee));
466
+ if (fee.gasLimit) {
467
+ this.validateValue(new bignumber_js_1.default(fee.gasLimit));
468
+ }
469
+ if (fee.eip1559) {
470
+ const maxFee = new bignumber_js_1.default(fee.eip1559.maxFeePerGas);
471
+ const priorityFee = new bignumber_js_1.default(fee.eip1559.maxPriorityFeePerGas);
472
+ this.validateValue(maxFee);
473
+ this.validateValue(priorityFee);
474
+ if (priorityFee.isGreaterThan(maxFee)) {
475
+ throw new sdk_core_1.BuildTransactionError('maxPriorityFeePerGas cannot exceed maxFeePerGas');
476
+ }
477
+ }
478
+ if (fee.gasPrice) {
479
+ this.validateValue(new bignumber_js_1.default(fee.gasPrice));
480
+ }
481
+ this._fee = fee;
482
+ }
483
+ /**
484
+ * Set the transaction counter to prevent submitting repeated transactions.
485
+ *
486
+ * @param {number} counter The counter to use
487
+ */
488
+ counter(counter) {
489
+ if (counter < 0) {
490
+ throw new sdk_core_1.BuildTransactionError(`Invalid counter: ${counter}`);
491
+ }
492
+ this._counter = counter;
493
+ }
494
+ /**
495
+ * The value to send along with this transaction. 0 by default
496
+ *
497
+ * @param {string} value The value to send along with this transaction
498
+ */
499
+ value(value) {
500
+ this._value = value;
501
+ }
502
+ // set args that are required for all types of eth transactions
503
+ buildBase(data) {
504
+ const baseParams = {
505
+ gasLimit: this._fee.gasLimit,
506
+ nonce: this._counter,
507
+ data: data,
508
+ chainId: this._common.chainIdBN().toString(),
509
+ value: this._value,
510
+ to: this._contractAddress,
511
+ };
512
+ if (this._fee.eip1559) {
513
+ return {
514
+ ...baseParams,
515
+ _type: iface_1.ETHTransactionType.EIP1559,
516
+ maxFeePerGas: this._fee.eip1559.maxFeePerGas,
517
+ maxPriorityFeePerGas: this._fee.eip1559.maxPriorityFeePerGas,
518
+ };
519
+ }
520
+ else {
521
+ return {
522
+ ...baseParams,
523
+ _type: iface_1.ETHTransactionType.LEGACY,
524
+ gasPrice: this._fee?.gasPrice ?? this._fee.fee,
525
+ v: this.getFinalV(),
526
+ };
527
+ }
528
+ }
529
+ // endregion
530
+ // region WalletInitialization builder methods
531
+ /**
532
+ * Set one of the owners of the multisig wallet.
533
+ *
534
+ * @param {string} address An Ethereum address
535
+ */
536
+ owner(address) {
537
+ if (this._type !== sdk_core_1.TransactionType.WalletInitialization) {
538
+ throw new sdk_core_1.BuildTransactionError('Multisig wallet owner can only be set for initialization transactions');
539
+ }
540
+ if (this._walletOwnerAddresses.length >= DEFAULT_M) {
541
+ throw new sdk_core_1.BuildTransactionError('A maximum of ' + DEFAULT_M + ' owners can be set for a multisig wallet');
542
+ }
543
+ if (!(0, utils_1.isValidEthAddress)(address)) {
544
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + address);
545
+ }
546
+ if (this._walletOwnerAddresses.includes(address)) {
547
+ throw new sdk_core_1.BuildTransactionError('Repeated owner address: ' + address);
548
+ }
549
+ this._walletOwnerAddresses.push(address);
550
+ }
551
+ /**
552
+ * Build a transaction for a generic multisig contract.
553
+ *
554
+ * @returns {TxData} The Ethereum transaction data
555
+ */
556
+ buildWalletInitializationTransaction(walletVersion) {
557
+ const walletInitData = walletVersion === walletUtil_1.defaultWalletVersion
558
+ ? this.getContractData(this._walletOwnerAddresses)
559
+ : (0, utils_1.getV1WalletInitializationData)(this._walletOwnerAddresses, this._salt);
560
+ return this.buildBase(walletInitData);
561
+ }
562
+ /**
563
+ * Returns the smart contract encoded data
564
+ *
565
+ * @param {string[]} addresses - the contract signers
566
+ * @returns {string} - the smart contract encoded data
567
+ */
568
+ getContractData(addresses) {
569
+ const params = [addresses];
570
+ const resultEncodedParameters = ethereumjs_abi_1.default.rawEncode(walletUtil_1.walletSimpleConstructor, params)
571
+ .toString('hex')
572
+ .replace('0x', '');
573
+ return this._walletSimpleByteCode + resultEncodedParameters;
574
+ }
575
+ // endregion
576
+ // region Send builder methods
577
+ contract(address) {
578
+ if (!(0, utils_1.isValidEthAddress)(address)) {
579
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + address);
580
+ }
581
+ this._contractAddress = address;
582
+ }
583
+ /**
584
+ * Returns the serialized sendMultiSig contract method data
585
+ *
586
+ * @returns {string} serialized sendMultiSig data
587
+ */
588
+ getSendData() {
589
+ if (!this._transfer) {
590
+ throw new sdk_core_1.BuildTransactionError('Missing transfer information');
591
+ }
592
+ const chainId = this._common.chainIdBN().toString();
593
+ this._transfer.walletVersion(this._walletVersion);
594
+ // This change is made to support new contracts with different encoding type
595
+ return this._transfer.signAndBuild(chainId, this.coinUsesNonPackedEncodingForTxData());
596
+ }
597
+ /**
598
+ * Decide if the coin uses non-packed encoding for tx data
599
+ *
600
+ * @returns {boolean} true if the coin uses non-packed encoding for tx data
601
+ */
602
+ coinUsesNonPackedEncodingForTxData() {
603
+ return (this._walletVersion === 4 || this._coinConfig.features.includes(statics_1.CoinFeature.USES_NON_PACKED_ENCODING_FOR_TXDATA));
604
+ }
605
+ buildSendTransaction() {
606
+ const sendData = this.getSendData();
607
+ const tx = this.buildBase(sendData);
608
+ tx.to = this._contractAddress;
609
+ return tx;
610
+ }
611
+ // endregion
612
+ // region AddressInitialization builder methods
613
+ /**
614
+ * Set the contract transaction nonce to calculate the forwarder address.
615
+ *
616
+ * @param {number} contractCounter The counter to use
617
+ */
618
+ contractCounter(contractCounter) {
619
+ if (contractCounter < 0) {
620
+ throw new sdk_core_1.BuildTransactionError(`Invalid contract counter: ${contractCounter}`);
621
+ }
622
+ this._contractCounter = contractCounter;
623
+ }
624
+ /**
625
+ * Build a transaction to create a forwarder.
626
+ *
627
+ * @returns {TxData} The Ethereum transaction data
628
+ */
629
+ buildAddressInitializationTransaction() {
630
+ const addressInitData = (0, utils_1.getAddressInitDataAllForwarderVersions)(this._forwarderVersion, this._baseAddress, this._salt, this._feeAddress);
631
+ const tx = this.buildBase(addressInitData);
632
+ tx.to = this._contractAddress;
633
+ if (this._contractCounter) {
634
+ tx.deployedAddress = (0, utils_1.calculateForwarderAddress)(this._contractAddress, this._contractCounter);
635
+ }
636
+ if (this._salt && this._initCode) {
637
+ const saltBuffer = ethUtil.setLengthLeft(ethUtil.toBuffer(this._salt), 32);
638
+ const { createForwarderParams, createForwarderTypes } = (0, utils_1.getCreateForwarderParamsAndTypes)(this._baseAddress, saltBuffer, this._feeAddress);
639
+ // Hash the wallet base address and fee address if present with the given salt, so the address directly relies on the base address and fee address
640
+ const calculationSalt = ethUtil.bufferToHex(ethereumjs_abi_1.default.soliditySHA3(createForwarderTypes, createForwarderParams));
641
+ tx.deployedAddress = (0, utils_1.calculateForwarderV1Address)(this._contractAddress, calculationSalt, this._initCode);
642
+ }
643
+ return tx;
644
+ }
645
+ // endregion
646
+ // region flush methods
647
+ /**
648
+ * Set the forwarder address to flush
649
+ *
650
+ * @param {string} address The address to flush
651
+ */
652
+ forwarderAddress(address) {
653
+ if (!(0, utils_1.isValidEthAddress)(address)) {
654
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + address);
655
+ }
656
+ this._forwarderAddress = address;
657
+ }
658
+ /**
659
+ * Set the address of the ERC20 token contract that we are flushing tokens for
660
+ *
661
+ * @param {string} address the contract address of the token to flush
662
+ */
663
+ tokenAddress(address) {
664
+ if (!(0, utils_1.isValidEthAddress)(address)) {
665
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + address);
666
+ }
667
+ this._tokenAddress = address;
668
+ }
669
+ /**
670
+ * Set the token ID for ERC721/ERC1155 token flush
671
+ *
672
+ * @param {string} tokenId the token ID to flush
673
+ */
674
+ tokenId(tokenId) {
675
+ this._tokenId = tokenId;
676
+ }
677
+ /**
678
+ * Build a transaction to flush tokens from a forwarder.
679
+ *
680
+ * @returns {TxData} The Ethereum transaction data
681
+ */
682
+ buildFlushTokensTransaction() {
683
+ if (this._forwarderVersion >= 4 && this._contractAddress !== this._forwarderAddress) {
684
+ throw new sdk_core_1.BuildTransactionError('Invalid contract address: ' + this._contractAddress);
685
+ }
686
+ return this.buildBase((0, utils_1.flushTokensData)(this._forwarderAddress, this._tokenAddress, this._forwarderVersion));
687
+ }
688
+ /**
689
+ * Build a transaction to flush tokens from a forwarder.
690
+ *
691
+ * @returns {TxData} The Ethereum transaction data
692
+ */
693
+ buildFlushCoinsTransaction() {
694
+ return this.buildBase((0, utils_1.flushCoinsData)());
695
+ }
696
+ /**
697
+ * Build a transaction to flush ERC721 NFTs from a forwarder.
698
+ *
699
+ * @returns {TxData} The Ethereum transaction data
700
+ */
701
+ buildFlushERC721Transaction() {
702
+ if (!this._tokenAddress) {
703
+ throw new sdk_core_1.BuildTransactionError('Token address is required for ERC721 flush');
704
+ }
705
+ if (!this._tokenId) {
706
+ throw new sdk_core_1.BuildTransactionError('Token ID is required for ERC721 flush');
707
+ }
708
+ if (this._forwarderVersion >= 4 && this._contractAddress !== this._forwarderAddress) {
709
+ throw new sdk_core_1.BuildTransactionError('Invalid contract address: ' + this._contractAddress);
710
+ }
711
+ return this.buildBase((0, utils_1.flushERC721TokensData)(this._forwarderAddress, this._tokenAddress, this._tokenId, this._forwarderVersion));
712
+ }
713
+ /**
714
+ * Build a transaction to flush ERC1155 tokens from a forwarder.
715
+ *
716
+ * @returns {TxData} The Ethereum transaction data
717
+ */
718
+ buildFlushERC1155Transaction() {
719
+ if (!this._tokenAddress) {
720
+ throw new sdk_core_1.BuildTransactionError('Token address is required for ERC1155 flush');
721
+ }
722
+ if (!this._tokenId) {
723
+ throw new sdk_core_1.BuildTransactionError('Token ID is required for ERC1155 flush');
724
+ }
725
+ if (this._forwarderVersion >= 4 && this._contractAddress !== this._forwarderAddress) {
726
+ throw new sdk_core_1.BuildTransactionError('Invalid contract address: ' + this._contractAddress);
727
+ }
728
+ return this.buildBase((0, utils_1.flushERC1155TokensData)(this._forwarderAddress, this._tokenAddress, this._tokenId, this._forwarderVersion));
729
+ }
730
+ // endregion
731
+ // region generic contract call
732
+ data(encodedCall) {
733
+ const supportedTransactionTypes = [
734
+ sdk_core_1.TransactionType.ContractCall,
735
+ sdk_core_1.TransactionType.RecoveryWalletDeployment,
736
+ sdk_core_1.TransactionType.DecryptionDelegation,
737
+ ];
738
+ if (!supportedTransactionTypes.includes(this._type)) {
739
+ throw new sdk_core_1.BuildTransactionError('data can only be set for contract call transaction types');
740
+ }
741
+ this._data = encodedCall;
742
+ }
743
+ buildGenericContractCallTransaction() {
744
+ return this.buildBase(this._data);
745
+ }
746
+ // endregion
747
+ /** @inheritdoc */
748
+ get transaction() {
749
+ return this._transaction;
750
+ }
751
+ /** @inheritdoc */
752
+ set transaction(transaction) {
753
+ this._transaction = transaction;
754
+ }
755
+ /**
756
+ * Get the final v value. Final v is described in EIP-155.
757
+ *
758
+ * @protected for internal use when the enableFinalVField flag is true.
759
+ */
760
+ getFinalV() {
761
+ return ethUtil.addHexPrefix(this._common.chainIdBN().muln(2).addn(35).toString(16));
762
+ }
763
+ /**
764
+ * Set the forwarder version for address to be initialized
765
+ *
766
+ * @param {number} version forwarder version
767
+ */
768
+ forwarderVersion(version) {
769
+ if (version < 0 || version > 4 || version === 3) {
770
+ throw new sdk_core_1.BuildTransactionError(`Invalid forwarder version: ${version}`);
771
+ }
772
+ this._forwarderVersion = version;
773
+ }
774
+ /**
775
+ * Set the salt to create the address using create2
776
+ *
777
+ * @param {string} salt The salt to create the address using create2, hex string
778
+ */
779
+ salt(salt) {
780
+ this._salt = salt;
781
+ }
782
+ /**
783
+ * Take the implementation address for the proxy contract, and get the binary initcode for the associated proxy
784
+ *
785
+ * @param {string} implementationAddress The address of the implementation contract
786
+ */
787
+ initCode(implementationAddress) {
788
+ if (!(0, utils_1.isValidEthAddress)(implementationAddress)) {
789
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + implementationAddress);
790
+ }
791
+ this._initCode = (0, utils_1.getProxyInitcode)(implementationAddress);
792
+ }
793
+ /**
794
+ * Set the wallet version for wallet to be initialized
795
+ *
796
+ * @param {number} version wallet version
797
+ */
798
+ walletVersion(version) {
799
+ if (version < 0 || version > 4 || version === 3) {
800
+ throw new sdk_core_1.BuildTransactionError(`Invalid wallet version: ${version}`);
801
+ }
802
+ this._walletVersion = version;
803
+ }
804
+ /**
805
+ * Set the base address of the wallet
806
+ *
807
+ * @param {string} address The wallet contract address
808
+ */
809
+ baseAddress(address) {
810
+ if (!(0, utils_1.isValidEthAddress)(address)) {
811
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + address);
812
+ }
813
+ this._baseAddress = address;
814
+ }
815
+ /**
816
+ * Set the fee address of the wallet
817
+ *
818
+ * @param {string} address The fee address of the wallet
819
+ */
820
+ feeAddress(address) {
821
+ if (!(0, utils_1.isValidEthAddress)(address)) {
822
+ throw new sdk_core_1.BuildTransactionError('Invalid address: ' + address);
823
+ }
824
+ this._feeAddress = address;
825
+ }
826
+ /**
827
+ * Get the wallet version for wallet
828
+ */
829
+ getWalletVersion() {
830
+ return this._walletVersion;
831
+ }
832
+ }
833
+ exports.TransactionBuilder = TransactionBuilder;
834
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQTJGO0FBRTNGLG9FQUF5QztBQUN6QyxnRUFBcUM7QUFDckMseURBQTJDO0FBQzNDLHVDQUE2RDtBQUU3RCxtREFZOEI7QUFFOUIsdUNBQW9DO0FBQ3BDLG1DQUEwRTtBQUMxRSxtQ0FvQmlCO0FBQ2pCLDZDQUE2RTtBQUc3RSwrQ0FBNEM7QUFHNUMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0FBQ3BCLE1BQU0sZ0JBQWdCLEdBQUcscUJBQXFCLENBQUM7QUFFL0M7O0dBRUc7QUFDSCxNQUFzQixrQkFBbUIsU0FBUSxpQ0FBc0I7SUF5Q3JFOzs7O09BSUc7SUFDSCxZQUFZLFdBQWlDO1FBQzNDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUEsaUJBQVMsRUFBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQTBCLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsS0FBSyxHQUFHLDBCQUFlLENBQUMsSUFBSSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztRQUN4QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUkseUJBQVcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMs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QUcsQ0FBQyxJQUFJLE9BQU8sR0FBRyxDQUFDLElBQUksT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2hELE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQywyQkFBMkIsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBRUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxXQUFXLENBQUMsT0FBZTtRQUN6QixJQUFJLENBQUMsSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyxtQkFBbUIsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUM7SUFDOUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxVQUFVLENBQUMsT0FBZTtRQUN4QixJQUFJLENBQUMsSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxnQ0FBcUIsQ0FBQyxtQkFBbUIsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUNqRSxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUM7SUFDN0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ksZ0JBQWdCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUM3QixDQUFDO0NBQ0Y7QUE1NUJELGdEQTQ1QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCYXNlQ29pbiBhcyBDb2luQ29uZmlnLCBFdGhlcmV1bU5ldHdvcmssIENvaW5GZWF0dXJlIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgRXRoZXJldW1Db21tb24gZnJvbSAnQGV0aGVyZXVtanMvY29tbW9uJztcbmltcG9ydCBFdGhlcmV1bUFiaSBmcm9tICdldGhlcmV1bWpzLWFiaSc7XG5pbXBvcnQgQmlnTnVtYmVyIGZyb20gJ2JpZ251bWJlci5qcyc7XG5pbXBvcnQgKiBhcyBldGhVdGlsIGZyb20gJ2V0aGVyZXVtanMtdXRpbCc7XG5pbXBvcnQgeyBGZWVNYXJrZXRFSVAxNTU5VHJhbnNhY3Rpb24gfSBmcm9tICdAZXRoZXJldW1qcy90eCc7XG5cbmltcG9ydCB7XG4gIEJhc2VBZGRyZXNzLFxuICBCYXNlS2V5LFxuICBCYXNlVHJhbnNhY3Rpb24sXG4gIEJhc2VUcmFuc2FjdGlvbkJ1aWxkZXIsXG4gIEJ1aWxkVHJhbnNhY3Rpb25FcnJvcixcbiAgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IsXG4gIGlzVmFsaWRQcnYsXG4gIGlzVmFsaWRYcHJ2LFxuICBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsXG4gIFNpZ25pbmdFcnJvcixcbiAgVHJhbnNhY3Rpb25UeXBlLFxufSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5cbmltcG9ydCB7IEtleVBhaXIgfSBmcm9tICcuL2tleVBhaXInO1xuaW1wb3J0IHsgRVRIVHJhbnNhY3Rpb25UeXBlLCBGZWUsIFNpZ25hdHVyZVBhcnRzLCBUeERhdGEgfSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZUZvcndhcmRlckFkZHJlc3MsXG4gIGNhbGN1bGF0ZUZvcndhcmRlclYxQWRkcmVzcyxcbiAgY2xhc3NpZnlUcmFuc2FjdGlvbixcbiAgZGVjb2RlRm9yd2FyZGVyQ3JlYXRpb25EYXRhLFxuICBkZWNvZGVGbHVzaFRva2Vuc0RhdGEsXG4gIGRlY29kZUZsdXNoRVJDNzIxVG9rZW5zRGF0YSxcbiAgZGVjb2RlRmx1c2hFUkMxMTU1VG9rZW5zRGF0YSxcbiAgZGVjb2RlV2FsbGV0Q3JlYXRpb25EYXRhLFxuICBmbHVzaENvaW5zRGF0YSxcbiAgZmx1c2hUb2tlbnNEYXRhLFxuICBmbHVzaEVSQzcyMVRva2Vuc0RhdGEsXG4gIGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEsXG4gIGdldEFkZHJlc3NJbml0RGF0YUFsbEZvcndhcmRlclZlcnNpb25zLFxuICBnZXRDb21tb24sXG4gIGdldFByb3h5SW5pdGNvZGUsXG4gIGhhc1NpZ25hdHVyZSxcbiAgaXNWYWxpZEV0aEFkZHJlc3MsXG4gIGdldFYxV2FsbGV0SW5pdGlhbGl6YXRpb25EYXRhLFxuICBnZXRDcmVhdGVGb3J3YXJkZXJQYXJhbXNBbmRUeXBlcyxcbn0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBkZWZhdWx0V2FsbGV0VmVyc2lvbiwgd2FsbGV0U2ltcGxlQ29uc3RydWN0b3IgfSBmcm9tICcuL3dhbGxldFV0aWwnO1xuaW1wb3J0IHsgRVJDMTE1NVRyYW5zZmVyQnVpbGRlciB9IGZyb20gJy4vdHJhbnNmZXJCdWlsZGVycy90cmFuc2ZlckJ1aWxkZXJFUkMxMTU1JztcbmltcG9ydCB7IEVSQzcyMVRyYW5zZmVyQnVpbGRlciB9IGZyb20gJy4vdHJhbnNmZXJCdWlsZGVycy90cmFuc2ZlckJ1aWxkZXJFUkM3MjEnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICcuL3RyYW5zYWN0aW9uJztcbmltcG9ydCB7IFRyYW5zZmVyQnVpbGRlciB9IGZyb20gJy4vdHJhbnNmZXJCdWlsZGVyJztcblxuY29uc3QgREVGQVVMVF9NID0gMztcbmNvbnN0IFJBV19UWF9IRVhfUkVHRVggPSAvXigweCk/WzAtOWEtZl17MSx9JC87XG5cbi8qKlxuICogRXRoZXJldW1MaWtlIHRyYW5zYWN0aW9uIGJ1aWxkZXIuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUcmFuc2FjdGlvbkJ1aWxkZXIgZXh0ZW5kcyBCYXNlVHJhbnNhY3Rpb25CdWlsZGVyIHtcbiAgcHJvdGVjdGVkIF90eXBlOiBUcmFuc2FjdGlvblR5cGU7XG4gIC8vIFNwZWNpZmllcyBjb21tb24gY2hhaW4gYW5kIGhhcmRmb3JrIHBhcmFtZXRlcnMuXG4gIHByb3RlY3RlZCBfY29tbW9uOiBFdGhlcmV1bUNvbW1vbjtcbiAgcHJvdGVjdGVkIF9zb3VyY2VLZXlQYWlyOiBLZXlQYWlyO1xuICBwcml2YXRlIF90cmFuc2FjdGlvbjogVHJhbnNhY3Rpb247XG4gIHByaXZhdGUgX2NvdW50ZXI6IG51bWJlcjtcbiAgcHJpdmF0ZSBfZmVlOiBGZWU7XG4gIHByb3RlY3RlZCBfdmFsdWU6IHN0cmluZztcblxuICAvLyB0aGUgc2lnbmF0dXJlIG9uIHRoZSBleHRlcm5hbCBFVEggdHJhbnNhY3Rpb25cbiAgcHJpdmF0ZSBfdHhTaWduYXR1cmU6IFNpZ25hdHVyZVBhcnRzO1xuXG4gIC8vIFdhbGxldCBpbml0aWFsaXphdGlvbiB0cmFuc2FjdGlvbiBwYXJhbWV0ZXJzXG4gIHByaXZhdGUgX3dhbGxldE93bmVyQWRkcmVzc2VzOiBzdHJpbmdbXTtcbiAgcHJvdGVjdGVkIF93YWxsZXRWZXJzaW9uOiBudW1iZXI7XG5cbiAgLy8gZmx1c2ggdG9rZW5zIHBhcmFtZXRlcnNcbiAgcHJpdmF0ZSBfZm9yd2FyZGVyQWRkcmVzczogc3RyaW5nO1xuICBwcml2YXRlIF90b2tlbkFkZHJlc3M6IHN0cmluZztcbiAgcHJpdmF0ZSBfdG9rZW5JZDogc3RyaW5nO1xuXG4gIC8vIFNlbmQgYW5kIEFkZHJlc3NJbml0aWFsaXphdGlvbiB0cmFuc2FjdGlvbiBzcGVjaWZpYyBwYXJhbWV0ZXJzXG4gIHByb3RlY3RlZCBfdHJhbnNmZXI6IFRyYW5zZmVyQnVpbGRlciB8IEVSQzcyMVRyYW5zZmVyQnVpbGRlciB8IEVSQzExNTVUcmFuc2ZlckJ1aWxkZXI7XG4gIHByaXZhdGUgX2NvbnRyYWN0QWRkcmVzczogc3RyaW5nO1xuICBwcml2YXRlIF9jb250cmFjdENvdW50ZXI6IG51bWJlcjtcbiAgcHJpdmF0ZSBfZm9yd2FyZGVyVmVyc2lvbjogbnVtYmVyO1xuICBwcml2YXRlIF9pbml0Q29kZTogc3RyaW5nO1xuICBwcml2YXRlIF9iYXNlQWRkcmVzczogc3RyaW5nO1xuICBwcml2YXRlIF9mZWVBZGRyZXNzOiBzdHJpbmc7XG5cbiAgLy8gZ2VuZXJpYyBjb250cmFjdCBjYWxsIGJ1aWxkZXJcbiAgLy8gZW5jb2RlZCBjb250cmFjdCBjYWxsIGhleFxuICBwcml2YXRlIF9kYXRhOiBzdHJpbmc7XG5cbiAgLy8gQ29tbW9uIHBhcmFtZXRlciBmb3Igd2FsbGV0IGluaXRpYWxpemF0aW9uIGFuZCBhZGRyZXNzIGluaXRpYWxpemF0aW9uIHRyYW5zYWN0aW9uXG4gIHByaXZhdGUgX3NhbHQ6IHN0cmluZztcblxuICAvLyB3YWxsZXRzaW1wbGVieXRlY29kZVxuICBwcm90ZWN0ZWQgX3dhbGxldFNpbXBsZUJ5dGVDb2RlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFB1YmxpYyBjb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogQHBhcmFtIF9jb2luQ29uZmlnXG4gICAqL1xuICBjb25zdHJ1Y3RvcihfY29pbkNvbmZpZzogUmVhZG9ubHk8Q29pbkNvbmZpZz4pIHtcbiAgICBzdXBlcihfY29pbkNvbmZpZyk7XG4gICAgdGhpcy5fY29tbW9uID0gZ2V0Q29tbW9uKHRoaXMuX2NvaW5Db25maWcubmV0d29yayBhcyBFdGhlcmV1bU5ldHdvcmspO1xuICAgIHRoaXMuX3R5cGUgPSBUcmFuc2FjdGlvblR5cGUuU2VuZDtcbiAgICB0aGlzLl9jb3VudGVyID0gMDtcbiAgICB0aGlzLl92YWx1ZSA9ICcwJztcbiAgICB0aGlzLl93YWxsZXRPd25lckFkZHJlc3NlcyA9IFtdO1xuICAgIHRoaXMuX2ZvcndhcmRlclZlcnNpb24gPSAwO1xuICAgIHRoaXMuX3dhbGxldFZlcnNpb24gPSAwO1xuICAgIHRoaXMudHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24odGhpcy5fY29pbkNvbmZpZywgdGhpcy5fY29tbW9uKTtcbiAgICB0aGlzLl93YWxsZXRTaW1wbGVCeXRlQ29kZSA9ICcnO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHByb3RlY3RlZCBhc3luYyBidWlsZEltcGxlbWVudGF0aW9uKCk6IFByb21pc2U8QmFzZVRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgdHJhbnNhY3Rpb25EYXRhID0gdGhpcy5nZXRUcmFuc2FjdGlvbkRhdGEoKTtcblxuICAgIGlmICh0aGlzLl90eFNpZ25hdHVyZSkge1xuICAgICAgT2JqZWN0LmFzc2lnbih0cmFuc2FjdGlvbkRhdGEsIHRoaXMuX3R4U2lnbmF0dXJlKTtcbiAgICB9XG5cbiAgICB0aGlzLnRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uVHlwZSh0aGlzLl90eXBlKTtcbiAgICB0cmFuc2FjdGlvbkRhdGEuZnJvbSA9IHRoaXMuX3NvdXJjZUtleVBhaXIgPyB0aGlzLl9zb3VyY2VLZXlQYWlyLmdldEFkZHJlc3MoKSA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLnRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uRGF0YShcbiAgICAgIHRyYW5zYWN0aW9uRGF0YSxcbiAgICAgIHRoaXMuX3RyYW5zZmVyID8gdGhpcy5fdHJhbnNmZXIuZ2V0SXNGaXJzdFNpZ25lcigpIDogdW5kZWZpbmVkXG4gICAgKTtcbiAgICAvLyBCdWlsZCBhbmQgc2lnbiBhIG5ldyB0cmFuc2FjdGlvbiBiYXNlZCBvbiB0aGUgbGF0ZXN0IGNoYW5nZXNcbiAgICBpZiAodGhpcy5fc291cmNlS2V5UGFpciAmJiB0aGlzLl9zb3VyY2VLZXlQYWlyLmdldEtleXMoKS5wcnYpIHtcbiAgICAgIGF3YWl0IHRoaXMudHJhbnNhY3Rpb24uc2lnbih0aGlzLl9zb3VyY2VLZXlQYWlyKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb247XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VHJhbnNhY3Rpb25EYXRhKCk6IFR4RGF0YSB7XG4gICAgc3dpdGNoICh0aGlzLl90eXBlKSB7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5XYWxsZXRJbml0aWFsaXphdGlvbjpcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRXYWxsZXRJbml0aWFsaXphdGlvblRyYW5zYWN0aW9uKHRoaXMuX3dhbGxldFZlcnNpb24pO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuUmVjb3ZlcnlXYWxsZXREZXBsb3ltZW50OlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEJhc2UodGhpcy5fZGF0YSk7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TZW5kOlxuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuU2VuZEVSQzcyMTpcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlNlbmRFUkMxMTU1OlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZFNlbmRUcmFuc2FjdGlvbigpO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuQWRkcmVzc0luaXRpYWxpemF0aW9uOlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEFkZHJlc3NJbml0aWFsaXphdGlvblRyYW5zYWN0aW9uKCk7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5GbHVzaFRva2VuczpcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRGbHVzaFRva2Vuc1RyYW5zYWN0aW9uKCk7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5GbHVzaENvaW5zOlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEZsdXNoQ29pbnNUcmFuc2FjdGlvbigpO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRmx1c2hFUkM3MjE6XG4gICAgICAgIHJldHVybiB0aGlzLmJ1aWxkRmx1c2hFUkM3MjFUcmFuc2FjdGlvbigpO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRmx1c2hFUkMxMTU1OlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEZsdXNoRVJDMTE1NVRyYW5zYWN0aW9uKCk7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TaW5nbGVTaWdTZW5kOlxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZEJhc2UoJzB4Jyk7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5Db250cmFjdENhbGw6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5EZWNyeXB0aW9uRGVsZWdhdGlvbjpcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRHZW5lcmljQ29udHJhY3RDYWxsVHJhbnNhY3Rpb24oKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ1Vuc3VwcG9ydGVkIHRyYW5zYWN0aW9uIHR5cGUnKTtcbiAgICB9XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcHJvdGVjdGVkIGZyb21JbXBsZW1lbnRhdGlvbihyYXdUcmFuc2FjdGlvbjogc3RyaW5nLCBpc0ZpcnN0U2lnbmVyPzogYm9vbGVhbik6IFRyYW5zYWN0aW9uIHtcbiAgICBsZXQgdHg6IFRyYW5zYWN0aW9uO1xuICAgIGlmIChSQVdfVFhfSEVYX1JFR0VYLnRlc3QocmF3VHJhbnNhY3Rpb24udG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgIHR4ID0gVHJhbnNhY3Rpb24uZnJvbVNlcmlhbGl6ZWQodGhpcy5fY29pbkNvbmZpZywgdGhpcy5fY29tbW9uLCByYXdUcmFuc2FjdGlvbiwgaXNGaXJzdFNpZ25lcik7XG4gICAgICB0aGlzLmxvYWRCdWlsZGVySW5wdXQodHgudG9Kc29uKCksIGlzRmlyc3RTaWduZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0eERhdGEgPSBKU09OLnBhcnNlKHJhd1RyYW5zYWN0aW9uKTtcbiAgICAgIHR4ID0gbmV3IFRyYW5zYWN0aW9uKHRoaXMuX2NvaW5Db25maWcsIHR4RGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB0eDtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHRoZSBidWlsZGVyIGRhdGEgdXNpbmcgdGhlIGRlc2VyaWFsaXplZCB0cmFuc2FjdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge1R4RGF0YX0gdHJhbnNhY3Rpb25Kc29uIHRoZSBkZXNlcmlhbGl6ZWQgdHJhbnNhY3Rpb24ganNvblxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzRmlyc3RTaWduZXIgaWYgdGhlIHRyYW5zYWN0aW9uIGlzIGJlaW5nIHNpZ25lZCBieSB0aGUgZmlyc3Qgc2lnbmVyXG4gICAqL1xuICBwcm90ZWN0ZWQgbG9hZEJ1aWxkZXJJbnB1dCh0cmFuc2FjdGlvbkpzb246IFR4RGF0YSwgaXNGaXJzdFNpZ25lcj86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBkZWNvZGVkVHlwZSA9IGNsYXNzaWZ5VHJhbnNhY3Rpb24odHJhbnNhY3Rpb25Kc29uLmRhdGEpO1xuICAgIHRoaXMudHlwZShkZWNvZGVkVHlwZSk7XG4gICAgdGhpcy5jb3VudGVyKHRyYW5zYWN0aW9uSnNvbi5ub25jZSk7XG4gICAgdGhpcy52YWx1ZSh0cmFuc2FjdGlvbkpzb24udmFsdWUpO1xuXG4gICAgaWYgKHRyYW5zYWN0aW9uSnNvbi5fdHlwZSA9PT0gRVRIVHJhbnNhY3Rpb25UeXBlLkxFR0FDWSkge1xuICAgICAgdGhpcy5mZWUoe1xuICAgICAgICBmZWU6IHRyYW5zYWN0aW9uSnNvbi5nYXNQcmljZSxcbiAgICAgICAgZ2FzUHJpY2U6IHRyYW5zYWN0aW9uSnNvbi5nYXNQcmljZSxcbiAgICAgICAgZ2FzTGltaXQ6IHRyYW5zYWN0aW9uSnNvbi5nYXNMaW1pdCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZlZSh7XG4gICAgICAgIGdhc0xpbWl0OiB0cmFuc2FjdGlvbkpzb24uZ2FzTGltaXQsXG4gICAgICAgIGZlZTogdHJhbnNhY3Rpb25Kc29uLm1heEZlZVBlckdhcyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heEZlZVBlckdhczogdHJhbnNhY3Rpb25Kc29uLm1heEZlZVBlckdhcyxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogdHJhbnNhY3Rpb25Kc29uLm1heFByaW9yaXR5RmVlUGVyR2FzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGhhc1NpZ25hdHVyZSh0cmFuc2FjdGlvbkpzb24pKSB7XG4gICAgICB0aGlzLl90eFNpZ25hdHVyZSA9IHsgdjogdHJhbnNhY3Rpb25Kc29uLnYhLCByOiB0cmFuc2FjdGlvbkpzb24uciEsIHM6IHRyYW5zYWN0aW9uSnNvbi5zISB9O1xuICAgIH1cbiAgICB0aGlzLnNldFRyYW5zYWN0aW9uVHlwZUZpZWxkcyhkZWNvZGVkVHlwZSwgdHJhbnNhY3Rpb25Kc29uLCBpc0ZpcnN0U2lnbmVyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzZXRUcmFuc2FjdGlvblR5cGVGaWVsZHMoXG4gICAgZGVjb2RlZFR5cGU6IFRyYW5zYWN0aW9uVHlwZSxcbiAgICB0cmFuc2FjdGlvbkpzb246IFR4RGF0YSxcbiAgICBpc0ZpcnN0U2lnbmVyPzogYm9vbGVhblxuICApOiB2b2lkIHtcbiAgICBzd2l0Y2ggKGRlY29kZWRUeXBlKSB7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5XYWxsZXRJbml0aWFsaXphdGlvbjpcbiAgICAgICAgY29uc3QgeyBvd25lcnMsIHNhbHQgfSA9IGRlY29kZVdhbGxldENyZWF0aW9uRGF0YSh0cmFuc2FjdGlvbkpzb24uZGF0YSk7XG4gICAgICAgIG93bmVycy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XG4gICAgICAgICAgdGhpcy5vd25lcihlbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChzYWx0KSB7XG4gICAgICAgICAgdGhpcy5zYWx0KHNhbHQgYXMgc3RyaW5nKTtcbiAgICAgICAgICB0aGlzLndhbGxldFZlcnNpb24oMSk7XG4gICAgICAgICAgdGhpcy5zZXRDb250cmFjdCh0cmFuc2FjdGlvbkpzb24udG8pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuUmVjb3ZlcnlXYWxsZXREZXBsb3ltZW50OlxuICAgICAgICB0aGlzLmRhdGEodHJhbnNhY3Rpb25Kc29uLmRhdGEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkZsdXNoVG9rZW5zOlxuICAgICAgICB0aGlzLnNldENvbnRyYWN0KHRyYW5zYWN0aW9uSnNvbi50byk7XG4gICAgICAgIGNvbnN0IHsgZm9yd2FyZGVyQWRkcmVzcywgdG9rZW5BZGRyZXNzLCBmb3J3YXJkZXJWZXJzaW9uIH0gPSBkZWNvZGVGbHVzaFRva2Vuc0RhdGEoXG4gICAgICAgICAgdHJhbnNhY3Rpb25Kc29uLmRhdGEsXG4gICAgICAgICAgdHJhbnNhY3Rpb25Kc29uLnRvXG4gICAgICAgICk7XG4gICAgICAgIGlmIChmb3J3YXJkZXJWZXJzaW9uID09PSA0KSB7XG4gICAgICAgICAgdGhpcy5mb3J3YXJkZXJWZXJzaW9uKDQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9yd2FyZGVyQWRkcmVzcyhmb3J3YXJkZXJBZGRyZXNzKTtcbiAgICAgICAgdGhpcy50b2tlbkFkZHJlc3ModG9rZW5BZGRyZXNzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5GbHVzaENvaW5zOlxuICAgICAgICB0aGlzLnNldENvbnRyYWN0KHRyYW5zYWN0aW9uSnNvbi50byk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRmx1c2hFUkM3MjE6XG4gICAgICAgIHRoaXMuc2V0Q29udHJhY3QodHJhbnNhY3Rpb25Kc29uLnRvKTtcbiAgICAgICAgY29uc3QgZXJjNzIxRGF0YSA9IGRlY29kZUZsdXNoRVJDNzIxVG9rZW5zRGF0YSh0cmFuc2FjdGlvbkpzb24uZGF0YSwgdHJhbnNhY3Rpb25Kc29uLnRvKTtcbiAgICAgICAgaWYgKGVyYzcyMURhdGEuZm9yd2FyZGVyVmVyc2lvbiA9PT0gNCkge1xuICAgICAgICAgIHRoaXMuZm9yd2FyZGVyVmVyc2lvbihlcmM3MjFEYXRhLmZvcndhcmRlclZlcnNpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9yd2FyZGVyQWRkcmVzcyhlcmM3MjFEYXRhLmZvcndhcmRlckFkZHJlc3MpO1xuICAgICAgICB0aGlzLnRva2VuQWRkcmVzcyhlcmM3MjFEYXRhLnRva2VuQWRkcmVzcyk7XG4gICAgICAgIHRoaXMudG9rZW5JZChlcmM3MjFEYXRhLnRva2VuSWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkZsdXNoRVJDMTE1NTpcbiAgICAgICAgdGhpcy5zZXRDb250cmFjdCh0cmFuc2FjdGlvbkpzb24udG8pO1xuICAgICAgICBjb25zdCBlcmMxMTU1RGF0YSA9IGRlY29kZUZsdXNoRVJDMTE1NVRva2Vuc0RhdGEodHJhbnNhY3Rpb25Kc29uLmRhdGEsIHRyYW5zYWN0aW9uSnNvbi50byk7XG4gICAgICAgIGlmIChlcmMxMTU1RGF0YS5mb3J3YXJkZXJWZXJzaW9uID09PSA0KSB7XG4gICAgICAgICAgdGhpcy5mb3J3YXJkZXJWZXJzaW9uKGVyYzExNTVEYXRhLmZvcndhcmRlclZlcnNpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9yd2FyZGVyQWRkcmVzcyhlcmMxMTU1RGF0YS5mb3J3YXJkZXJBZGRyZXNzKTtcbiAgICAgICAgdGhpcy50b2tlbkFkZHJlc3MoZXJjMTE1NURhdGEudG9rZW5BZGRyZXNzKTtcbiAgICAgICAgdGhpcy50b2tlbklkKGVyYzExNTVEYXRhLnRva2VuSWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlNlbmQ6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TZW5kRVJDMTE1NTpcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlNlbmRFUkM3MjE6XG4gICAgICAgIHRoaXMuc2V0Q29udHJhY3QodHJhbnNhY3Rpb25Kc29uLnRvKTtcbiAgICAgICAgdGhpcy5fdHJhbnNmZXIgPSB0aGlzLnRyYW5zZmVyKHRyYW5zYWN0aW9uSnNvbi5kYXRhLCBpc0ZpcnN0U2lnbmVyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5BZGRyZXNzSW5pdGlhbGl6YXRpb246XG4gICAgICAgIHRoaXMuc2V0Q29udHJhY3QodHJhbnNhY3Rpb25Kc29uLnRvKTtcbiAgICAgICAgY29uc3QgeyBiYXNlQWRkcmVzcywgYWRkcmVzc0NyZWF0aW9uU2FsdCwgZmVlQWRkcmVzcyB9ID0gZGVjb2RlRm9yd2FyZGVyQ3JlYXRpb25EYXRhKHRyYW5zYWN0aW9uSnNvbi5kYXRhKTtcbiAgICAgICAgaWYgKGJhc2VBZGRyZXNzICYmIGFkZHJlc3NDcmVhdGlvblNhbHQpIHtcbiAgICAgICAgICB0aGlzLmJhc2VBZGRyZXNzKGJhc2VBZGRyZXNzKTtcbiAgICAgICAgICB0aGlzLnNhbHQoYWRkcmVzc0NyZWF0aW9uU2FsdCk7XG4gICAgICAgICAgaWYgKGZlZUFkZHJlc3MpIHtcbiAgICAgICAgICAgIHRoaXMuZmVlQWRkcmVzcyhmZWVBZGRyZXNzKTtcbiAgICAgICAgICAgIHRoaXMuZm9yd2FyZGVyVmVyc2lvbig0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mb3J3YXJkZXJWZXJzaW9uKDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBmb3J3YXJkZXJJbXBsZW1lbnRhdGlvbkFkZHJlc3MgPSAodGhpcy5fY29pbkNvbmZpZy5uZXR3b3JrIGFzIEV0aGVyZXVtTmV0d29yaylcbiAgICAgICAgICAgIC5mb3J3YXJkZXJJbXBsZW1lbnRhdGlvbkFkZHJlc3MgYXMgc3RyaW5nO1xuICAgICAgICAgIGlmIChmb3J3YXJkZXJJbXBsZW1lbnRhdGlvbkFkZHJlc3MpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdENvZGUoZm9yd2FyZGVySW1wbGVtZW50YXRpb25BZGRyZXNzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TaW5nbGVTaWdTZW5kOlxuICAgICAgICB0aGlzLnNldENvbnRyYWN0KHRyYW5zYWN0aW9uSnNvbi50byk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsOlxuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRGVjcnlwdGlvbkRlbGVnYXRpb246XG4gICAgICAgIHRoaXMuc2V0Q29udHJhY3QodHJhbnNhY3Rpb25Kc29uLnRvKTtcbiAgICAgICAgdGhpcy5kYXRhKHRyYW5zYWN0aW9uSnNvbi5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdVbnN1cHBvcnRlZCB0cmFuc2FjdGlvbiB0eXBlJyk7XG4gICAgICAvLyBUT0RPOiBBZGQgb3RoZXIgY2FzZXMgb2YgZGVzZXJpYWxpemF0aW9uXG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHByb3RlY3RlZCBzaWduSW1wbGVtZW50YXRpb24oa2V5OiBCYXNlS2V5KTogQmFzZVRyYW5zYWN0aW9uIHtcbiAgICBjb25zdCBzaWduZXIgPSBuZXcgS2V5UGFpcih7IHBydjoga2V5LmtleSB9KTtcbiAgICBpZiAodGhpcy5fdHlwZSA9PT0gVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uICYmIHRoaXMuX3dhbGxldE93bmVyQWRkcmVzc2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IFNpZ25pbmdFcnJvcignQ2Fubm90IHNpZ24gYW4gd2FsbGV0IGluaXRpYWxpemF0aW9uIHRyYW5zYWN0aW9uIHdpdGhvdXQgb3duZXJzJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9zb3VyY2VLZXlQYWlyKSB7XG4gICAgICB0aHJvdyBuZXcgU2lnbmluZ0Vycm9yKCdDYW5ub3Qgc2lnbiBtdWx0aXBsZSB0aW1lcyBhIG5vbiBzZW5kLXR5cGUgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gICAgLy8gU2lnbmluZyB0aGUgdHJhbnNhY3Rpb24gaXMgYW4gYXN5bmMgb3BlcmF0aW9uLCBzbyBzYXZlIHRoZSBzb3VyY2UgYW5kIGxlYXZlIHRoZSBhY3R1YWxcbiAgICAvLyBzaWduaW5nIGZvciB0aGUgYnVpbGQgc3RlcFxuICAgIHRoaXMuX3NvdXJjZUtleVBhaXIgPSBzaWduZXI7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNhY3Rpb247XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdmFsaWRhdGVBZGRyZXNzKGFkZHJlc3M6IEJhc2VBZGRyZXNzKTogdm9pZCB7XG4gICAgaWYgKCFpc1ZhbGlkRXRoQWRkcmVzcyhhZGRyZXNzLmFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGFkZHJlc3MgJyArIGFkZHJlc3MuYWRkcmVzcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHZhbGlkYXRlS2V5KGtleTogQmFzZUtleSk6IHZvaWQge1xuICAgIGlmICghKGlzVmFsaWRYcHJ2KGtleS5rZXkpIHx8IGlzVmFsaWRQcnYoa2V5LmtleSkpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGtleScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgcmF3IHRyYW5zYWN0aW9uIGlzIGVpdGhlciBhIEpTT04gb3JcbiAgICogYSBoZXggZW5jb2RlZCB0cmFuc2FjdGlvblxuICAgKlxuICAgKiBAcGFyYW0ge2FueX0gcmF3VHJhbnNhY3Rpb24gVGhlIHJhdyB0cmFuc2FjdGlvbiB0byBiZSB2YWxpZGF0ZWRcbiAgICovXG4gIHZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHJhbnNhY3Rpb246IGFueSk6IHZvaWQge1xuICAgIGlmICghcmF3VHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcignUmF3IHRyYW5zYWN0aW9uIGlzIGVtcHR5Jyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcmF3VHJhbnNhY3Rpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoUkFXX1RYX0hFWF9SRUdFWC50ZXN0KHJhd1RyYW5zYWN0aW9uLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICAgIGNvbnN0IHR4Qnl0ZXMgPSBldGhVdGlsLnRvQnVmZmVyKGV0aFV0aWwuYWRkSGV4UHJlZml4KHJhd1RyYW5zYWN0aW9uLnRvTG93ZXJDYXNlKCkpKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzRWlwMTU1OVR4bih0eEJ5dGVzKSAmJiAhdGhpcy5pc1JMUERlY29kYWJsZSh0eEJ5dGVzKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ1RoZXJlIHdhcyBlcnJvciBpbiBkZWNvZGluZyB0aGUgaGV4IHN0cmluZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIEpTT04ucGFyc2UocmF3VHJhbnNhY3Rpb24pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlVHJhbnNhY3Rpb25FcnJvcignVGhlcmUgd2FzIGVycm9yIGluIHBhcnNpbmcgdGhlIEpTT04gc3RyaW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdUcmFuc2FjdGlvbiBpcyBub3QgYSBoZXggc3RyaW5nIG9yIHN0cmluZ2lmaWVkIGpzb24nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzRWlwMTU1OVR4bih0eG46IEJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICBGZWVNYXJrZXRFSVAxNTU5VHJhbnNhY3Rpb24uZnJvbVNlcmlhbGl6ZWRUeCh0eG4pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoXykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNSTFBEZWNvZGFibGUoYnl0ZXM6IEJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICBldGhVdGlsLnJscC5kZWNvZGUoYnl0ZXMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoXykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCB2YWxpZGF0ZUJhc2VUcmFuc2FjdGlvbkZpZWxkcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fZmVlID09PSB1bmRlZmluZWQgfHwgKCF0aGlzLl9mZWUuZmVlICYmICF0aGlzLl9mZWUuZ2FzUHJpY2UgJiYgIXRoaXMuX2ZlZS5laXAxNTU5KSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyBmZWUnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2NvbW1vbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBuZXR3b3JrIGNvbW1vbicpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fY291bnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIGFkZHJlc3MgY291bnRlcicpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB2YWxpZGF0ZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uOiBCYXNlVHJhbnNhY3Rpb24pOiB2b2lkIHtcbiAgICB0aGlzLnZhbGlkYXRlQmFzZVRyYW5zYWN0aW9uRmllbGRzKCk7XG4gICAgc3dpdGNoICh0aGlzLl90eXBlKSB7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5XYWxsZXRJbml0aWFsaXphdGlvbjpcbiAgICAgICAgdGhpcy52YWxpZGF0ZVdhbGxldEluaXRpYWxpemF0aW9uRmllbGRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuUmVjb3ZlcnlXYWxsZXREZXBsb3ltZW50OlxuICAgICAgICB0aGlzLnZhbGlkYXRlRGF0YUZpZWxkKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuU2VuZDpcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlNlbmRFUkM3MjE6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TZW5kRVJDMTE1NTpcbiAgICAgICAgdGhpcy52YWxpZGF0ZUNvbnRyYWN0QWRkcmVzcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkFkZHJlc3NJbml0aWFsaXphdGlvbjpcbiAgICAgICAgdGhpcy52YWxpZGF0ZUNvbnRyYWN0QWRkcmVzcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLkZsdXNoQ29pbnM6XG4gICAgICAgIHRoaXMudmFsaWRhdGVDb250cmFjdEFkZHJlc3MoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5GbHVzaFRva2VuczpcbiAgICAgICAgdGhpcy52YWxpZGF0ZUNvbnRyYWN0QWRkcmVzcygpO1xuICAgICAgICB0aGlzLnZhbGlkYXRlRm9yd2FyZGVyQWRkcmVzcygpO1xuICAgICAgICB0aGlzLnZhbGlkYXRlVG9rZW5BZGRyZXNzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRmx1c2hFUkM3MjE6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5GbHVzaEVSQzExNTU6XG4gICAgICAgIHRoaXMudmFsaWRhdGVDb250cmFjdEFkZHJlc3MoKTtcbiAgICAgICAgaWYgKHRoaXMuX2ZvcndhcmRlclZlcnNpb24gPCA0KSB7XG4gICAgICAgICAgdGhpcy52YWxpZGF0ZUZvcndhcmRlckFkZHJlc3MoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZhbGlkYXRlVG9rZW5BZGRyZXNzKCk7XG4gICAgICAgIGlmICghdGhpcy5fdG9rZW5JZCkge1xuICAgICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoXG4gICAgICAgICAgICB0aGlzLl90eXBlID09PSBUcmFuc2FjdGlvblR5cGUuRmx1c2hFUkM3MjFcbiAgICAgICAgICAgICAgPyAnVG9rZW4gSUQgaXMgcmVxdWlyZWQgZm9yIEVSQzcyMSBmbHVzaCdcbiAgICAgICAgICAgICAgOiAnVG9rZW4gSUQgaXMgcmVxdWlyZWQgZm9yIEVSQzExNTUgZmx1c2gnXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlNpbmdsZVNpZ1NlbmQ6XG4gICAgICAgIC8vIGZvciBzaW5nbGUgc2lnIHNlbmRzLCB0aGUgY29udHJhY3QgYWRkcmVzcyBpcyBhY3R1YWxseSB0aGUgcmVjaXBpZW50XG4gICAgICAgIHRoaXMudmFsaWRhdGVDb250cmFjdEFkZHJlc3MoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nTG9jazpcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdVbmxvY2s6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nVm90ZTpcbiAgICAgIGNhc2UgVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdVbnZvdGU6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nQWN0aXZhdGU6XG4gICAgICBjYXNlIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nV2l0aGRyYXc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuQ29udHJhY3RDYWxsOlxuICAgICAgY2FzZSBUcmFuc2FjdGlvblR5cGUuRGVjcnlwdGlvbkRlbGVnYXRpb246XG4gICAgICAgIHRoaXMudmFsaWRhdGVDb250cmFjdEFkZHJlc3MoKTtcbiAgICAgICAgdGhpcy52YWxpZGF0ZURhdGFGaWVsZCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ1Vuc3VwcG9ydGVkIHRyYW5zYWN0aW9uIHR5cGUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgd2FsbGV0IG93bmVyIGFkZHJlc3NlcyBmb3Igd2FsbGV0IGluaXRpYWxpemF0aW9uIHRyYW5zYWN0aW9ucyBhcmUgdmFsaWQgb3IgdGhyb3cuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlV2FsbGV0SW5pdGlhbGl6YXRpb25GaWVsZHMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3dhbGxldE93bmVyQWRkcmVzc2VzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IG1pc3Npbmcgd2FsbGV0IG93bmVycycpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl93YWxsZXRPd25lckFkZHJlc3Nlcy5sZW5ndGggIT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIHRyYW5zYWN0aW9uOiB3cm9uZyBudW1iZXIgb2Ygb3duZXJzIC0tIHJlcXVpcmVkOiAzLCBmb3VuZDogJHt0aGlzLl93YWxsZXRPd25lckFkZHJlc3Nlcy5sZW5ndGh9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSB0b2tlbiBhZGRyZXNzIGZvciB0aGUgdHggd2FzIGRlZmluZWQgb3IgdGhyb3cuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlVG9rZW5BZGRyZXNzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl90b2tlbkFkZHJlc3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyB0b2tlbiBhZGRyZXNzJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgZm9yd2FyZGVyIGFkZHJlc3MgZm9yIHRoZSB0eCB3YXMgZGVmaW5lZCBvciB0aHJvdy5cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVGb3J3YXJkZXJBZGRyZXNzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9mb3J3YXJkZXJBZGRyZXNzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IG1pc3NpbmcgZm9yd2FyZGVyIGFkZHJlc3MnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBjb250cmFjdCBhZGRyZXNzIGZvciB0aGUgd2FsbGV0IHdhcyBkZWZpbmVkIG9yIHRocm93LlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUNvbnRyYWN0QWRkcmVzcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fY29udHJhY3RBZGRyZXNzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IG1pc3NpbmcgY29udHJhY3QgYWRkcmVzcycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYSBjb250cmFjdCBjYWxsIGRhdGEgZmllbGQgd2FzIGRlZmluZWQgb3IgdGhyb3dzIG90aGVyd2lzZVxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZURhdGFGaWVsZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuX2RhdGEpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IG1pc3NpbmcgY29udHJhY3QgY2FsbCBkYXRhIGZpZWxkJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRDb250cmFjdChhZGRyZXNzOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBpZiAoYWRkcmVzcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdVbmRlZmluZWQgcmVjaXBpZW50IGFkZHJlc3MnKTtcbiAgICB9XG4gICAgdGhpcy5jb250cmFjdChhZGRyZXNzKTtcbiAgfVxuXG4gIHZhbGlkYXRlVmFsdWUodmFsdWU6IEJpZ051bWJlcik6IHZvaWQge1xuICAgIGlmICh2YWx1ZS5pc0xlc3NUaGFuKDApKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdWYWx1ZSBjYW5ub3QgYmUgYmVsb3cgbGVzcyB0aGFuIHplcm8nKTtcbiAgICB9XG4gICAgLy8gVE9ETzogdmFsaWRhdGUgdGhlIGFtb3VudCBpcyBub3QgYmlnZ2VyIHRoYW4gdGhlIG1heCBhbW91bnQgaW4gZWFjaCBFdGggZmFtaWx5IGNvaW5cbiAgfVxuXG4gIC8vIHJlZ2lvbiBDb21tb24gYnVpbGRlciBtZXRob2RzXG5cbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIHRyYW5zYWN0aW9uIGJlaW5nIGJ1aWx0LlxuICAgKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9uVHlwZX0gdHlwZVxuICAgKi9cbiAgdHlwZSh0eXBlOiBUcmFuc2FjdGlvblR5cGUpOiB2b2lkIHtcbiAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHRyYW5zYWN0aW9uIGZlZXMuIExvdyBmZWVzIG1heSBnZXQgYSB0cmFuc2FjdGlvbiByZWplY3RlZCBvciBuZXZlciBwaWNrZWQgdXAgYnkgYmFrZXJzLlxuICAgKlxuICAgKiBAcGFyYW0ge0ZlZX0gZmVlIEJha2VyIGZlZXMuIE1heSBhbHNvIGluY2x1ZGUgdGhlIG1heGltdW0gZ2FzIHRvIHBheVxuICAgKi9cbiAgZmVlKGZlZTogRmVlKTogdm9pZCB7XG4gICAgdGhpcy52YWxpZGF0ZVZhbHVlKG5ldyBCaWdOdW1iZXIoZmVlLmZlZSkpO1xuICAgIGlmIChmZWUuZ2FzTGltaXQpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVWYWx1ZShuZXcgQmlnTnVtYmVyKGZlZS5nYXNMaW1pdCkpO1xuICAgIH1cbiAgICBpZiAoZmVlLmVpcDE1NTkpIHtcbiAgICAgIGNvbnN0IG1heEZlZSA9IG5ldyBCaWdOdW1iZXIoZmVlLmVpcDE1NTkubWF4RmVlUGVyR2FzKTtcbiAgICAgIGNvbnN0IHByaW9yaXR5RmVlID0gbmV3IEJpZ051bWJlcihmZWUuZWlwMTU1OS5tYXhQcmlvcml0eUZlZVBlckdhcyk7XG4gICAgICB0aGlzLnZhbGlkYXRlVmFsdWUobWF4RmVlKTtcbiAgICAgIHRoaXMudmFsaWRhdGVWYWx1ZShwcmlvcml0eUZlZSk7XG4gICAgICBpZiAocHJpb3JpdHlGZWUuaXNHcmVhdGVyVGhhbihtYXhGZWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ21heFByaW9yaXR5RmVlUGVyR2FzIGNhbm5vdCBleGNlZWQgbWF4RmVlUGVyR2FzJyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChmZWUuZ2FzUHJpY2UpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVWYWx1ZShuZXcgQmlnTnVtYmVyKGZlZS5nYXNQcmljZSkpO1xuICAgIH1cbiAgICB0aGlzLl9mZWUgPSBmZWU7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSB0cmFuc2FjdGlvbiBjb3VudGVyIHRvIHByZXZlbnQgc3VibWl0dGluZyByZXBlYXRlZCB0cmFuc2FjdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjb3VudGVyIFRoZSBjb3VudGVyIHRvIHVzZVxuICAgKi9cbiAgY291bnRlcihjb3VudGVyOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoY291bnRlciA8IDApIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoYEludmFsaWQgY291bnRlcjogJHtjb3VudGVyfWApO1xuICAgIH1cblxuICAgIHRoaXMuX2NvdW50ZXIgPSBjb3VudGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSB0byBzZW5kIGFsb25nIHdpdGggdGhpcyB0cmFuc2FjdGlvbi4gMCBieSBkZWZhdWx0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VuZCBhbG9uZyB3aXRoIHRoaXMgdHJhbnNhY3Rpb25cbiAgICovXG4gIHZhbHVlKHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgLy8gc2V0IGFyZ3MgdGhhdCBhcmUgcmVxdWlyZWQgZm9yIGFsbCB0eXBlcyBvZiBldGggdHJhbnNhY3Rpb25zXG4gIHByb3RlY3RlZCBidWlsZEJhc2UoZGF0YTogc3RyaW5nKTogVHhEYXRhIHtcbiAgICBjb25zdCBiYXNlUGFyYW1zID0ge1xuICAgICAgZ2FzTGltaXQ6IHRoaXMuX2ZlZS5nYXNMaW1pdCxcbiAgICAgIG5vbmNlOiB0aGlzLl9jb3VudGVyLFxuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIGNoYWluSWQ6IHRoaXMuX2NvbW1vbi5jaGFpbklkQk4oKS50b1N0cmluZygpLFxuICAgICAgdmFsdWU6IHRoaXMuX3ZhbHVlLFxuICAgICAgdG86IHRoaXMuX2NvbnRyYWN0QWRkcmVzcyxcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuX2ZlZS5laXAxNTU5KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5iYXNlUGFyYW1zLFxuICAgICAgICBfdHlwZTogRVRIVHJhbnNhY3Rpb25UeXBlLkVJUDE1NTksXG4gICAgICAgIG1heEZlZVBlckdhczogdGhpcy5fZmVlLmVpcDE1NTkubWF4RmVlUGVyR2FzLFxuICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogdGhpcy5fZmVlLmVpcDE1NTkubWF4UHJpb3JpdHlGZWVQZXJHYXMsXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5iYXNlUGFyYW1zLFxuICAgICAgICBfdHlwZTogRVRIVHJhbnNhY3Rpb25UeXBlLkxFR0FDWSxcbiAgICAgICAgZ2FzUHJpY2U6IHRoaXMuX2ZlZT8uZ2FzUHJpY2UgPz8gdGhpcy5fZmVlLmZlZSxcbiAgICAgICAgdjogdGhpcy5nZXRGaW5hbFYoKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gZW5kcmVnaW9uXG5cbiAgLy8gcmVnaW9uIFdhbGxldEluaXRpYWxpemF0aW9uIGJ1aWxkZXIgbWV0aG9kc1xuICAvKipcbiAgICogU2V0IG9uZSBvZiB0aGUgb3duZXJzIG9mIHRoZSBtdWx0aXNpZyB3YWxsZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIEFuIEV0aGVyZXVtIGFkZHJlc3NcbiAgICovXG4gIG93bmVyKGFkZHJlc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLl90eXBlICE9PSBUcmFuc2FjdGlvblR5cGUuV2FsbGV0SW5pdGlhbGl6YXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ011bHRpc2lnIHdhbGxldCBvd25lciBjYW4gb25seSBiZSBzZXQgZm9yIGluaXRpYWxpemF0aW9uIHRyYW5zYWN0aW9ucycpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fd2FsbGV0T3duZXJBZGRyZXNzZXMubGVuZ3RoID49IERFRkFVTFRfTSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignQSBtYXhpbXVtIG9mICcgKyBERUZBVUxUX00gKyAnIG93bmVycyBjYW4gYmUgc2V0IGZvciBhIG11bHRpc2lnIHdhbGxldCcpO1xuICAgIH1cbiAgICBpZiAoIWlzVmFsaWRFdGhBZGRyZXNzKGFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGFkZHJlc3M6ICcgKyBhZGRyZXNzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3dhbGxldE93bmVyQWRkcmVzc2VzLmluY2x1ZGVzKGFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdSZXBlYXRlZCBvd25lciBhZGRyZXNzOiAnICsgYWRkcmVzcyk7XG4gICAgfVxuICAgIHRoaXMuX3dhbGxldE93bmVyQWRkcmVzc2VzLnB1c2goYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSB0cmFuc2FjdGlvbiBmb3IgYSBnZW5lcmljIG11bHRpc2lnIGNvbnRyYWN0LlxuICAgKlxuICAgKiBAcmV0dXJucyB7VHhEYXRhfSBUaGUgRXRoZXJldW0gdHJhbnNhY3Rpb24gZGF0YVxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkV2FsbGV0SW5pdGlhbGl6YXRpb25UcmFuc2FjdGlvbih3YWxsZXRWZXJzaW9uPzogbnVtYmVyKTogVHhEYXRhIHtcbiAgICBjb25zdCB3YWxsZXRJbml0RGF0YSA9XG4gICAgICB3YWxsZXRWZXJzaW9uID09PSBkZWZhdWx0V2FsbGV0VmVyc2lvblxuICAgICAgICA/IHRoaXMuZ2V0Q29udHJhY3REYXRhKHRoaXMuX3dhbGxldE93bmVyQWRkcmVzc2VzKVxuICAgICAgICA6IGdldFYxV2FsbGV0SW5pdGlhbGl6YXRpb25EYXRhKHRoaXMuX3dhbGxldE93bmVyQWRkcmVzc2VzLCB0aGlzLl9zYWx0KTtcbiAgICByZXR1cm4gdGhpcy5idWlsZEJhc2Uod2FsbGV0SW5pdERhdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNtYXJ0IGNvbnRyYWN0IGVuY29kZWQgZGF0YVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhZGRyZXNzZXMgLSB0aGUgY29udHJhY3Qgc2lnbmVyc1xuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIHRoZSBzbWFydCBjb250cmFjdCBlbmNvZGVkIGRhdGFcbiAgICovXG4gIHByb3RlY3RlZCBnZXRDb250cmFjdERhdGEoYWRkcmVzc2VzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFyYW1zID0gW2FkZHJlc3Nlc107XG4gICAgY29uc3QgcmVzdWx0RW5jb2RlZFBhcmFtZXRlcnMgPSBFdGhlcmV1bUFiaS5yYXdFbmNvZGUod2FsbGV0U2ltcGxlQ29uc3RydWN0b3IsIHBhcmFtcylcbiAgICAgIC50b1N0cmluZygnaGV4JylcbiAgICAgIC5yZXBsYWNlKCcweCcsICcnKTtcbiAgICByZXR1cm4gdGhpcy5fd2FsbGV0U2ltcGxlQnl0ZUNvZGUgKyByZXN1bHRFbmNvZGVkUGFyYW1ldGVycztcbiAgfVxuXG4gIC8vIGVuZHJlZ2lvblxuXG4gIC8vIHJlZ2lvbiBTZW5kIGJ1aWxkZXIgbWV0aG9kc1xuXG4gIGNvbnRyYWN0KGFkZHJlc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaXNWYWxpZEV0aEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgYWRkcmVzczogJyArIGFkZHJlc3MpO1xuICAgIH1cbiAgICB0aGlzLl9jb250cmFjdEFkZHJlc3MgPSBhZGRyZXNzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHRyYW5zZmVyIGZ1bmRzIGJ1aWxkZXIgaWYgZXhpc3QsIG9yIGNyZWF0ZXMgYSBuZXcgb25lIGZvciB0aGlzIHRyYW5zYWN0aW9uIGFuZCByZXR1cm5zIGl0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIHRyYW5zZmVyIGRhdGEgdG8gaW5pdGlhbGl6ZSB0aGUgdHJhbnNmZXIgYnVpbGRlciB3aXRoLCBlbXB0eSBpZiBub25lIGdpdmVuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNGaXJzdFNpZ25lciB3aGV0aGVyIHRoZSB0cmFuc2FjdGlvbiBpcyBiZWluZyBzaWduZWQgYnkgdGhlIGZpcnN0IHNpZ25lclxuICAgKiBAcmV0dXJucyB7VHJhbnNmZXJCdWlsZGVyIHwgRVJDNzIxVHJhbnNmZXJCdWlsZGVyIHwgRVJDMTE1NVRyYW5zZmVyQnVpbGRlcn0gdGhlIHRyYW5zZmVyIGJ1aWxkZXJcbiAgICovXG4gIGFic3RyYWN0IHRyYW5zZmVyKFxuICAgIGRhdGE/OiBzdHJpbmcsXG4gICAgaXNGaXJzdFNpZ25lcj86IGJvb2xlYW5cbiAgKTogVHJhbnNmZXJCdWlsZGVyIHwgRVJDNzIxVHJhbnNmZXJCdWlsZGVyIHwgRVJDMTE1NVRyYW5zZmVyQnVpbGRlcjtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2VyaWFsaXplZCBzZW5kTXVsdGlTaWcgY29udHJhY3QgbWV0aG9kIGRhdGFcbiAgICpcbiAgICogQHJldHVybnMge3N0cmluZ30gc2VyaWFsaXplZCBzZW5kTXVsdGlTaWcgZGF0YVxuICAgKi9cbiAgcHVibGljIGdldFNlbmREYXRhKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLl90cmFuc2Zlcikge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignTWlzc2luZyB0cmFuc2ZlciBpbmZvcm1hdGlvbicpO1xuICAgIH1cbiAgICBjb25zdCBjaGFpbklkID0gdGhpcy5fY29tbW9uLmNoYWluSWRCTigpLnRvU3RyaW5nKCk7XG4gICAgdGhpcy5fdHJhbnNmZXIud2FsbGV0VmVyc2lvbih0aGlzLl93YWxsZXRWZXJzaW9uKTtcbiAgICAvLyBUaGlzIGNoYW5nZSBpcyBtYWRlIHRvIHN1cHBvcnQgbmV3IGNvbnRyYWN0cyB3aXRoIGRpZmZlcmVudCBlbmNvZGluZyB0eXBlXG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zZmVyLnNpZ25BbmRCdWlsZChjaGFpbklkLCB0aGlzLmNvaW5Vc2VzTm9uUGFja2VkRW5jb2RpbmdGb3JUeERhdGEoKSk7XG4gIH1cblxuICAvKipcbiAgICogRGVjaWRlIGlmIHRoZSBjb2luIHVzZXMgbm9uLXBhY2tlZCBlbmNvZGluZyBmb3IgdHggZGF0YVxuICAgKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY29pbiB1c2VzIG5vbi1wYWNrZWQgZW5jb2RpbmcgZm9yIHR4IGRhdGFcbiAgICovXG4gIHB1YmxpYyBjb2luVXNlc05vblBhY2tlZEVuY29kaW5nRm9yVHhEYXRhKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLl93YWxsZXRWZXJzaW9uID09PSA0IHx8IHRoaXMuX2NvaW5Db25maWcuZmVhdHVyZXMuaW5jbHVkZXMoQ29pbkZlYXR1cmUuVVNFU19OT05fUEFDS0VEX0VOQ09ESU5HX0ZPUl9UWERBVEEpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRTZW5kVHJhbnNhY3Rpb24oKTogVHhEYXRhIHtcbiAgICBjb25zdCBzZW5kRGF0YSA9IHRoaXMuZ2V0U2VuZERhdGEoKTtcbiAgICBjb25zdCB0eDogVHhEYXRhID0gdGhpcy5idWlsZEJhc2Uoc2VuZERhdGEpO1xuICAgIHR4LnRvID0gdGhpcy5fY29udHJhY3RBZGRyZXNzO1xuICAgIHJldHVybiB0eDtcbiAgfVxuXG4gIC8vIGVuZHJlZ2lvblxuXG4gIC8vIHJlZ2lvbiBBZGRyZXNzSW5pdGlhbGl6YXRpb24gYnVpbGRlciBtZXRob2RzXG5cbiAgLyoqXG4gICAqIFNldCB0aGUgY29udHJhY3QgdHJhbnNhY3Rpb24gbm9uY2UgdG8gY2FsY3VsYXRlIHRoZSBmb3J3YXJkZXIgYWRkcmVzcy5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvbnRyYWN0Q291bnRlciBUaGUgY291bnRlciB0byB1c2VcbiAgICovXG4gIGNvbnRyYWN0Q291bnRlcihjb250cmFjdENvdW50ZXI6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChjb250cmFjdENvdW50ZXIgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKGBJbnZhbGlkIGNvbnRyYWN0IGNvdW50ZXI6ICR7Y29udHJhY3RDb3VudGVyfWApO1xuICAgIH1cblxuICAgIHRoaXMuX2NvbnRyYWN0Q291bnRlciA9IGNvbnRyYWN0Q291bnRlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIHRyYW5zYWN0aW9uIHRvIGNyZWF0ZSBhIGZvcndhcmRlci5cbiAgICpcbiAgICogQHJldHVybnMge1R4RGF0YX0gVGhlIEV0aGVyZXVtIHRyYW5zYWN0aW9uIGRhdGFcbiAgICovXG4gIHByaXZhdGUgYnVpbGRBZGRyZXNzSW5pdGlhbGl6YXRpb25UcmFuc2FjdGlvbigpOiBUeERhdGEge1xuICAgIGNvbnN0IGFkZHJlc3NJbml0RGF0YSA9IGdldEFkZHJlc3NJbml0RGF0YUFsbEZvcndhcmRlclZlcnNpb25zKFxuICAgICAgdGhpcy5fZm9yd2FyZGVyVmVyc2lvbixcbiAgICAgIHRoaXMuX2Jhc2VBZGRyZXNzLFxuICAgICAgdGhpcy5fc2FsdCxcbiAgICAgIHRoaXMuX2ZlZUFkZHJlc3NcbiAgICApO1xuICAgIGNvbnN0IHR4OiBUeERhdGEgPSB0aGlzLmJ1aWxkQmFzZShhZGRyZXNzSW5pdERhdGEpO1xuICAgIHR4LnRvID0gdGhpcy5fY29udHJhY3RBZGRyZXNzO1xuXG4gICAgaWYgKHRoaXMuX2NvbnRyYWN0Q291bnRlcikge1xuICAgICAgdHguZGVwbG95ZWRBZGRyZXNzID0gY2FsY3VsYXRlRm9yd2FyZGVyQWRkcmVzcyh0aGlzLl9jb250cmFjdEFkZHJlc3MsIHRoaXMuX2NvbnRyYWN0Q291bnRlcik7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3NhbHQgJiYgdGhpcy5faW5pdENvZGUpIHtcbiAgICAgIGNvbnN0IHNhbHRCdWZmZXIgPSBldGhVdGlsLnNldExlbmd0aExlZnQoZXRoVXRpbC50b0J1ZmZlcih0aGlzLl9zYWx0KSwgMzIpO1xuXG4gICAgICBjb25zdCB7IGNyZWF0ZUZvcndhcmRlclBhcmFtcywgY3JlYXRlRm9yd2FyZGVyVHlwZXMgfSA9IGdldENyZWF0ZUZvcndhcmRlclBhcmFtc0FuZFR5cGVzKFxuICAgICAgICB0aGlzLl9iYXNlQWRkcmVzcyxcbiAgICAgICAgc2FsdEJ1ZmZlcixcbiAgICAgICAgdGhpcy5fZmVlQWRkcmVzc1xuICAgICAgKTtcblxuICAgICAgLy8gSGFzaCB0aGUgd2FsbGV0IGJhc2UgYWRkcmVzcyBhbmQgZmVlIGFkZHJlc3MgaWYgcHJlc2VudCB3aXRoIHRoZSBnaXZlbiBzYWx0LCBzbyB0aGUgYWRkcmVzcyBkaXJlY3RseSByZWxpZXMgb24gdGhlIGJhc2UgYWRkcmVzcyBhbmQgZmVlIGFkZHJlc3NcbiAgICAgIGNvbnN0IGNhbGN1bGF0aW9uU2FsdCA9IGV0aFV0aWwuYnVmZmVyVG9IZXgoXG4gICAgICAgIEV0aGVyZXVtQWJpLnNvbGlkaXR5U0hBMyhjcmVhdGVGb3J3YXJkZXJUeXBlcywgY3JlYXRlRm9yd2FyZGVyUGFyYW1zKVxuICAgICAgKTtcbiAgICAgIHR4LmRlcGxveWVkQWRkcmVzcyA9IGNhbGN1bGF0ZUZvcndhcmRlclYxQWRkcmVzcyh0aGlzLl9jb250cmFjdEFkZHJlc3MsIGNhbGN1bGF0aW9uU2FsdCwgdGhpcy5faW5pdENvZGUpO1xuICAgIH1cbiAgICByZXR1cm4gdHg7XG4gIH1cbiAgLy8gZW5kcmVnaW9uXG5cbiAgLy8gcmVnaW9uIGZsdXNoIG1ldGhvZHNcbiAgLyoqXG4gICAqIFNldCB0aGUgZm9yd2FyZGVyIGFkZHJlc3MgdG8gZmx1c2hcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgVGhlIGFkZHJlc3MgdG8gZmx1c2hcbiAgICovXG4gIGZvcndhcmRlckFkZHJlc3MoYWRkcmVzczogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFpc1ZhbGlkRXRoQWRkcmVzcyhhZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBhZGRyZXNzOiAnICsgYWRkcmVzcyk7XG4gICAgfVxuICAgIHRoaXMuX2ZvcndhcmRlckFkZHJlc3MgPSBhZGRyZXNzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgYWRkcmVzcyBvZiB0aGUgRVJDMjAgdG9rZW4gY29udHJhY3QgdGhhdCB3ZSBhcmUgZmx1c2hpbmcgdG9rZW5zIGZvclxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYWRkcmVzcyB0aGUgY29udHJhY3QgYWRkcmVzcyBvZiB0aGUgdG9rZW4gdG8gZmx1c2hcbiAgICovXG4gIHRva2VuQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIWlzVmFsaWRFdGhBZGRyZXNzKGFkZHJlc3MpKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGFkZHJlc3M6ICcgKyBhZGRyZXNzKTtcbiAgICB9XG4gICAgdGhpcy5fdG9rZW5BZGRyZXNzID0gYWRkcmVzcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHRva2VuIElEIGZvciBFUkM3MjEvRVJDMTE1NSB0b2tlbiBmbHVzaFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdG9rZW5JZCB0aGUgdG9rZW4gSUQgdG8gZmx1c2hcbiAgICovXG4gIHRva2VuSWQodG9rZW5JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fdG9rZW5JZCA9IHRva2VuSWQ7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSB0cmFuc2FjdGlvbiB0byBmbHVzaCB0b2tlbnMgZnJvbSBhIGZvcndhcmRlci5cbiAgICpcbiAgICogQHJldHVybnMge1R4RGF0YX0gVGhlIEV0aGVyZXVtIHRyYW5zYWN0aW9uIGRhdGFcbiAgICovXG4gIHByaXZhdGUgYnVpbGRGbHVzaFRva2Vuc1RyYW5zYWN0aW9uKCk6IFR4RGF0YSB7XG4gICAgaWYgKHRoaXMuX2ZvcndhcmRlclZlcnNpb24gPj0gNCAmJiB0aGlzLl9jb250cmFjdEFkZHJlc3MgIT09IHRoaXMuX2ZvcndhcmRlckFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgY29udHJhY3QgYWRkcmVzczogJyArIHRoaXMuX2NvbnRyYWN0QWRkcmVzcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJ1aWxkQmFzZShmbHVzaFRva2Vuc0RhdGEodGhpcy5fZm9yd2FyZGVyQWRkcmVzcywgdGhpcy5fdG9rZW5BZGRyZXNzLCB0aGlzLl9mb3J3YXJkZXJWZXJzaW9uKSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSB0cmFuc2FjdGlvbiB0byBmbHVzaCB0b2tlbnMgZnJvbSBhIGZvcndhcmRlci5cbiAgICpcbiAgICogQHJldHVybnMge1R4RGF0YX0gVGhlIEV0aGVyZXVtIHRyYW5zYWN0aW9uIGRhdGFcbiAgICovXG4gIHByaXZhdGUgYnVpbGRGbHVzaENvaW5zVHJhbnNhY3Rpb24oKTogVHhEYXRhIHtcbiAgICByZXR1cm4gdGhpcy5idWlsZEJhc2UoZmx1c2hDb2luc0RhdGEoKSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSB0cmFuc2FjdGlvbiB0byBmbHVzaCBFUkM3MjEgTkZUcyBmcm9tIGEgZm9yd2FyZGVyLlxuICAgKlxuICAgKiBAcmV0dXJucyB7VHhEYXRhfSBUaGUgRXRoZXJldW0gdHJhbnNhY3Rpb24gZGF0YVxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZEZsdXNoRVJDNzIxVHJhbnNhY3Rpb24oKTogVHhEYXRhIHtcbiAgICBpZiAoIXRoaXMuX3Rva2VuQWRkcmVzcykge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVG9rZW4gYWRkcmVzcyBpcyByZXF1aXJlZCBmb3IgRVJDNzIxIGZsdXNoJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5fdG9rZW5JZCkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVG9rZW4gSUQgaXMgcmVxdWlyZWQgZm9yIEVSQzcyMSBmbHVzaCcpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fZm9yd2FyZGVyVmVyc2lvbiA+PSA0ICYmIHRoaXMuX2NvbnRyYWN0QWRkcmVzcyAhPT0gdGhpcy5fZm9yd2FyZGVyQWRkcmVzcykge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBjb250cmFjdCBhZGRyZXNzOiAnICsgdGhpcy5fY29udHJhY3RBZGRyZXNzKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYnVpbGRCYXNlKFxuICAgICAgZmx1c2hFUkM3MjFUb2tlbnNEYXRhKHRoaXMuX2ZvcndhcmRlckFkZHJlc3MsIHRoaXMuX3Rva2VuQWRkcmVzcywgdGhpcy5fdG9rZW5JZCwgdGhpcy5fZm9yd2FyZGVyVmVyc2lvbilcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgdHJhbnNhY3Rpb24gdG8gZmx1c2ggRVJDMTE1NSB0b2tlbnMgZnJvbSBhIGZvcndhcmRlci5cbiAgICpcbiAgICogQHJldHVybnMge1R4RGF0YX0gVGhlIEV0aGVyZXVtIHRyYW5zYWN0aW9uIGRhdGFcbiAgICovXG4gIHByaXZhdGUgYnVpbGRGbHVzaEVSQzExNTVUcmFuc2FjdGlvbigpOiBUeERhdGEge1xuICAgIGlmICghdGhpcy5fdG9rZW5BZGRyZXNzKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdUb2tlbiBhZGRyZXNzIGlzIHJlcXVpcmVkIGZvciBFUkMxMTU1IGZsdXNoJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5fdG9rZW5JZCkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVG9rZW4gSUQgaXMgcmVxdWlyZWQgZm9yIEVSQzExNTUgZmx1c2gnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2ZvcndhcmRlclZlcnNpb24gPj0gNCAmJiB0aGlzLl9jb250cmFjdEFkZHJlc3MgIT09IHRoaXMuX2ZvcndhcmRlckFkZHJlc3MpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgY29udHJhY3QgYWRkcmVzczogJyArIHRoaXMuX2NvbnRyYWN0QWRkcmVzcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmJ1aWxkQmFzZShcbiAgICAgIGZsdXNoRVJDMTE1NVRva2Vuc0RhdGEodGhpcy5fZm9yd2FyZGVyQWRkcmVzcywgdGhpcy5fdG9rZW5BZGRyZXNzLCB0aGlzLl90b2tlbklkLCB0aGlzLl9mb3J3YXJkZXJWZXJzaW9uKVxuICAgICk7XG4gIH1cbiAgLy8gZW5kcmVnaW9uXG5cbiAgLy8gcmVnaW9uIGdlbmVyaWMgY29udHJhY3QgY2FsbFxuICBkYXRhKGVuY29kZWRDYWxsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdXBwb3J0ZWRUcmFuc2FjdGlvblR5cGVzID0gW1xuICAgICAgVHJhbnNhY3Rpb25UeXBlLkNvbnRyYWN0Q2FsbCxcbiAgICAgIFRyYW5zYWN0aW9uVHlwZS5SZWNvdmVyeVdhbGxldERlcGxveW1lbnQsXG4gICAgICBUcmFuc2FjdGlvblR5cGUuRGVjcnlwdGlvbkRlbGVnYXRpb24sXG4gICAgXTtcbiAgICBpZiAoIXN1cHBvcnRlZFRyYW5zYWN0aW9uVHlwZXMuaW5jbHVkZXModGhpcy5fdHlwZSkpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ2RhdGEgY2FuIG9ubHkgYmUgc2V0IGZvciBjb250cmFjdCBjYWxsIHRyYW5zYWN0aW9uIHR5cGVzJyk7XG4gICAgfVxuICAgIHRoaXMuX2RhdGEgPSBlbmNvZGVkQ2FsbDtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRHZW5lcmljQ29udHJhY3RDYWxsVHJhbnNhY3Rpb24oKTogVHhEYXRhIHtcbiAgICByZXR1cm4gdGhpcy5idWlsZEJhc2UodGhpcy5fZGF0YSk7XG4gIH1cbiAgLy8gZW5kcmVnaW9uXG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHByb3RlY3RlZCBnZXQgdHJhbnNhY3Rpb24oKTogVHJhbnNhY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLl90cmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBwcm90ZWN0ZWQgc2V0IHRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbikge1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uID0gdHJhbnNhY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBmaW5hbCB2IHZhbHVlLiBGaW5hbCB2IGlzIGRlc2NyaWJlZCBpbiBFSVAtMTU1LlxuICAgKlxuICAgKiBAcHJvdGVjdGVkIGZvciBpbnRlcm5hbCB1c2Ugd2hlbiB0aGUgZW5hYmxlRmluYWxWRmllbGQgZmxhZyBpcyB0cnVlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldEZpbmFsVigpOiBzdHJpbmcge1xuICAgIHJldHVybiBldGhVdGlsLmFkZEhleFByZWZpeCh0aGlzLl9jb21tb24uY2hhaW5JZEJOKCkubXVsbigyKS5hZGRuKDM1KS50b1N0cmluZygxNikpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgZm9yd2FyZGVyIHZlcnNpb24gZm9yIGFkZHJlc3MgdG8gYmUgaW5pdGlhbGl6ZWRcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHZlcnNpb24gZm9yd2FyZGVyIHZlcnNpb25cbiAgICovXG4gIGZvcndhcmRlclZlcnNpb24odmVyc2lvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHZlcnNpb24gPCAwIHx8IHZlcnNpb24gPiA0IHx8IHZlcnNpb24gPT09IDMpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoYEludmFsaWQgZm9yd2FyZGVyIHZlcnNpb246ICR7dmVyc2lvbn1gKTtcbiAgICB9XG5cbiAgICB0aGlzLl9mb3J3YXJkZXJWZXJzaW9uID0gdmVyc2lvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHNhbHQgdG8gY3JlYXRlIHRoZSBhZGRyZXNzIHVzaW5nIGNyZWF0ZTJcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNhbHQgVGhlIHNhbHQgdG8gY3JlYXRlIHRoZSBhZGRyZXNzIHVzaW5nIGNyZWF0ZTIsIGhleCBzdHJpbmdcbiAgICovXG4gIHNhbHQoc2FsdDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fc2FsdCA9IHNhbHQ7XG4gIH1cblxuICAvKipcbiAgICogVGFrZSB0aGUgaW1wbGVtZW50YXRpb24gYWRkcmVzcyBmb3IgdGhlIHByb3h5IGNvbnRyYWN0LCBhbmQgZ2V0IHRoZSBiaW5hcnkgaW5pdGNvZGUgZm9yIHRoZSBhc3NvY2lhdGVkIHByb3h5XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpbXBsZW1lbnRhdGlvbkFkZHJlc3MgVGhlIGFkZHJlc3Mgb2YgdGhlIGltcGxlbWVudGF0aW9uIGNvbnRyYWN0XG4gICAqL1xuICBpbml0Q29kZShpbXBsZW1lbnRhdGlvbkFkZHJlc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaXNWYWxpZEV0aEFkZHJlc3MoaW1wbGVtZW50YXRpb25BZGRyZXNzKSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBhZGRyZXNzOiAnICsgaW1wbGVtZW50YXRpb25BZGRyZXNzKTtcbiAgICB9XG4gICAgdGhpcy5faW5pdENvZGUgPSBnZXRQcm94eUluaXRjb2RlKGltcGxlbWVudGF0aW9uQWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSB3YWxsZXQgdmVyc2lvbiBmb3Igd2FsbGV0IHRvIGJlIGluaXRpYWxpemVkXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2ZXJzaW9uIHdhbGxldCB2ZXJzaW9uXG4gICAqL1xuICB3YWxsZXRWZXJzaW9uKHZlcnNpb246IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh2ZXJzaW9uIDwgMCB8fCB2ZXJzaW9uID4gNCB8fCB2ZXJzaW9uID09PSAzKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKGBJbnZhbGlkIHdhbGxldCB2ZXJzaW9uOiAke3ZlcnNpb259YCk7XG4gICAgfVxuXG4gICAgdGhpcy5fd2FsbGV0VmVyc2lvbiA9IHZlcnNpb247XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBiYXNlIGFkZHJlc3Mgb2YgdGhlIHdhbGxldFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYWRkcmVzcyBUaGUgd2FsbGV0IGNvbnRyYWN0IGFkZHJlc3NcbiAgICovXG4gIGJhc2VBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaXNWYWxpZEV0aEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgYWRkcmVzczogJyArIGFkZHJlc3MpO1xuICAgIH1cbiAgICB0aGlzLl9iYXNlQWRkcmVzcyA9IGFkZHJlc3M7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBmZWUgYWRkcmVzcyBvZiB0aGUgd2FsbGV0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIFRoZSBmZWUgYWRkcmVzcyBvZiB0aGUgd2FsbGV0XG4gICAqL1xuICBmZWVBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaXNWYWxpZEV0aEFkZHJlc3MoYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgYWRkcmVzczogJyArIGFkZHJlc3MpO1xuICAgIH1cbiAgICB0aGlzLl9mZWVBZGRyZXNzID0gYWRkcmVzcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHdhbGxldCB2ZXJzaW9uIGZvciB3YWxsZXRcbiAgICovXG4gIHB1YmxpYyBnZXRXYWxsZXRWZXJzaW9uKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3dhbGxldFZlcnNpb247XG4gIH1cbn1cbiJdfQ==